building-stories-with-tdd
Orchestrates Test-Driven Development (TDD) workflows for user stories and features. Creates story tests first in tests/stories/, then iteratively implements until all pass. Invoke directly when a developer requests "TDD", "test-driven", "test first", "story test", "write tests before code", or feature implementation with TDD. Coordinates with generating-nest-servers (backend) and developing-lt-frontend (frontend). NOT for direct NestJS coding without TDD (use generating-nest-servers). NOT for standalone test generation (use /test-generate).
What this skill does
# Story-Based Test-Driven Development Expert
You are an expert in Test-Driven Development (TDD) for NestJS applications using @lenne.tech/nest-server. You help developers implement new features by first creating comprehensive story tests, then iteratively developing the code until all tests pass.
## Gotchas
- **Detect the test framework BEFORE writing the first test** — Projects use either Vitest or Jest. Vitest uses globals (`describe`, `it`, `expect`) without imports; Jest requires `import { describe, it, expect } from '@jest/globals'`. Mixing styles produces misleading error messages ("global not defined") that look like runtime failures. Check `vitest.config.ts` vs `jest.config.ts` first.
- **Test data emails MUST use `@test.com`** — The cleanup regex in `TestHelper` uses `@test.com` as its deletion filter. Using `@example.com` or `@user.de` for test data leaves records in the test DB after the run ends, polluting subsequent test runs. This applies to both backend story tests and frontend Playwright fixtures.
- **Never use `declare` on test-created Models** — Same gotcha as `generating-nest-servers`: `declare` removes the field at compile-time, so Typegoose decorators are lost. Test data that persists "successfully" but is missing fields in DB queries almost always traces back to a `declare`.
- **Story test files must be in `tests/stories/`** — The runner auto-discovers from this path. Placing them in `tests/` or `src/__tests__/` means they silently don't run. Backend: `projects/api/tests/stories/<feature>.e2e-spec.ts`. Frontend E2E: `projects/app/tests/<feature>.spec.ts`.
- **Iteration MUST be through the full test loop — not individual fixes** — When a test fails, the instinct is to fix just that assertion. In TDD with generated code, re-run the FULL test suite after any implementation change. A passing test can break a previously-passing one through Model/Service changes that don't generate compile errors.
- **Limit local Playwright runs to new + affected specs to keep TDD loops fast** — The full Playwright suite is slow and runs in **CI**. Inside the TDD loop, default to running only the **new + affected** specs via `lt dev test -- <spec>` (lt-projects) or `scripts/e2e-fast.sh -- <spec>` (non-lt). Backend Unit + API are fast and stay in the loop unrestricted. Only run the full local Playwright suite when the user explicitly asks.
## Ecosystem Context
TDD works in the **Lerna fullstack monorepo** created via `lt fullstack init`:
- **Backend tests** (`projects/api/tests/stories/`): API tests for `nest-server-starter` / `@lenne.tech/nest-server`
- **Frontend E2E tests** (`projects/app/tests/`): Playwright tests for `nuxt-base-starter` / `@lenne.tech/nuxt-extensions`
## When to Use This Skill
**ALWAYS use this skill for:**
- Implementing new API features using Test-Driven Development
- Creating story tests for user stories or requirements
- Developing new functionality in a test-first approach
- Ensuring comprehensive test coverage for new features
- Iterative development with test validation
- **Fullstack TDD workflows** (Backend + Frontend E2E tests)
## Fullstack TDD Workflow
**For fullstack projects, follow this order:**
```
Phase 1: BACKEND
├── 1. Write Backend Tests (API tests for REST/GraphQL)
└── 2. Implement Backend against tests (iterate until green)
Phase 2: FRONTEND
├── 3. Write Frontend E2E Tests (Playwright)
└── 4. Implement Frontend against tests (iterate until green)
Phase 3: VERIFICATION
└── 5. Debug with Chrome DevTools MCP (default for direct testing/debugging)
```
**Complete workflow details: [fullstack-tdd-workflow.md](${CLAUDE_SKILL_DIR}/fullstack-tdd-workflow.md)**
### Parallel Test Writing (Agent Teams)
When ALL of these conditions are met, use **parallel test writing** via `coordinating-agent-teams` Pattern 2 (Parallel With Handoff):
1. Agent Teams feature flag is enabled (`CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1`)
2. Fullstack monorepo detected (`projects/api/` AND `projects/app/`)
3. Story scope involves both backend AND frontend changes
**Parallel workflow:**
```
Phase 0: CONTRACT DEFINITION (Lead)
└── Define API contracts from story requirements (endpoints, request/response shapes)
Phase 1: PARALLEL TEST WRITING (2 teammates, simultaneous)
├── Teammate "backend-tests": Write API tests using contracts → share via message
└── Teammate "frontend-tests": Write E2E tests using contracts → consume API shapes
Phase 2: CONTRACT VALIDATION (Lead)
└── Verify backend and frontend tests reference consistent contracts
Phase 3: SEQUENTIAL IMPLEMENTATION (standard TDD)
├── Backend implementation (iterate until API tests green)
└── Frontend implementation (iterate until E2E tests green)
```
**Key:** Only test *writing* is parallelized. Implementation remains sequential (backend before frontend) because frontend depends on generated types from the running backend API.
### Test Isolation & Cleanup (CRITICAL)
**Tests MUST be repeatable without side effects:**
1. **Unique test data** - Use `${Date.now()}-${random}` patterns
2. **Complete cleanup in `afterAll`** - Delete all created entities
3. **Separate test database** - `app-test` vs `app-dev`
4. **No cross-test dependencies** - Each test file is independent
```typescript
afterAll(async () => {
// Delete test-created entities
await db.collection('entities').deleteMany({ createdBy: testUserId });
// Delete test users
await db.collection('users').deleteMany({ email: /@test\.com$/ });
});
```
**Why this matters:** Enables unlimited test runs without manual database cleanup.
### Detect Test Framework FIRST (CRITICAL)
**BEFORE writing or running ANY test**, mirror the project's existing framework and import style:
1. Check `package.json` for `vitest` or `jest` in dependencies/devDependencies
2. For Vitest: inspect `vitest.config.ts` / `vitest-e2e.config.ts` for `globals: true` — this flips whether `describe`/`it`/`expect` must be imported
3. Read 1-2 existing test files and mirror their import pattern exactly
4. Run tests via `package.json` scripts (e.g., `pnpm run test:e2e`), never via `npx vitest` / `npx jest`
**lt stack default:** `@lenne.tech/nest-server` and `nest-server-starter` use Vitest with `globals: true` in E2E configs — E2E specs do **not** import from `'vitest'`. Unit tests may import explicitly — match the neighbouring file.
**Migration projects:** Some projects keep Jest (`jest:*` scripts) next to Vitest (`test` alias). Within one project, `tests/**/*.e2e-spec.ts` may use globals while `src/**/*.spec.ts` uses explicit Vitest imports. Always mirror the nearest existing test file.
**Do NOT mix Vitest and Jest syntax in a single test file.**
## Skill Boundaries
| User Intent | Correct Skill |
|------------|---------------|
| "Implement with TDD" | **THIS SKILL** |
| "Write tests first" | **THIS SKILL** |
| "Create story tests" | **THIS SKILL** |
| "Create a NestJS module" (no TDD) | generating-nest-servers |
| "Fix this service bug" | generating-nest-servers |
| "Generate tests for existing code" | /test-generate command |
| "Build a Vue page" | developing-lt-frontend |
## Related Skills & Commands
**User-facing command:** `/lt-dev:resolve-ticket [issue-id | story-file]` — Resolves a ticket using this skill
**Works closely with:**
- `generating-nest-servers` skill - For code implementation (modules, objects, properties)
- `using-lt-cli` skill - For Git operations and project initialization
- `developing-lt-frontend` skill - For frontend E2E tests and implementation
- `coordinating-agent-teams` skill - For parallel test writing in fullstack projects
- `/lt-dev:create-ticket` command - Create any ticket type (Story, Task, Bug)
- `/lt-dev:create-story` command - Create a story, then implement with TDD
- `/lt-dev:review` command - Comprehensive quality check after implementation (Step 5a)
- `/lt-dev:backend:sec-review` command - nest-server specific security review
## TypeScript Language Server (Recommended)
**Use the LSP tool when avRelated in Web Dev
generating-lwc-components
IncludedLightning Web Components with PICKLES methodology and 165-point scoring. Use this skill when the user creates or edits LWC components, builds wire service patterns, or writes Jest tests for LWC. TRIGGER when: user creates/edits LWC components, touches lwc/**/*.js, .html, .css, .js-meta.xml files, or asks about wire service, SLDS, or Jest LWC tests. DO NOT TRIGGER when: Apex classes (use generating-apex), Aura components, or Visualforce.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Set up queries with useQuery, mutations with useMutation, configure QueryClient caching strategies, implement optimistic updates, and handle infinite scroll with useInfiniteQuery. Use when: setting up data fetching in React projects, migrating from v4 to v5, or fixing object syntax required errors, query callbacks removed issues, cacheTime renamed to gcTime, isPending vs isLoading confusion, keepPreviousData removed problems.
document-processor-api
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
nutrient-document-processing
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Covers useMutationState, simplified optimistic updates, throwOnError, network mode (offline/PWA), and infiniteQueryOptions. Use when setting up data fetching, fixing v4→v5 migration errors (object syntax, gcTime, isPending, keepPreviousData), or debugging SSR/hydration issues with streaming server components.
accelint-nextjs-best-practices
IncludedNext.js performance optimization and best practices. Use when writing Next.js code (App Router or Pages Router); implementing Server Components, Server Actions, or API routes; optimizing RSC serialization, data fetching, or server-side rendering; reviewing Next.js code for performance issues; fixing authentication in Server Actions; or implementing Suspense boundaries, parallel data fetching, or request deduplication.