@loomfsm/bundle-code 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/LICENSE +201 -0
  2. package/agents/acceptance.md +141 -0
  3. package/agents/api-contract.md +89 -0
  4. package/agents/architect.md +52 -0
  5. package/agents/challenger-reviewer.md +104 -0
  6. package/agents/classifier.md +74 -0
  7. package/agents/code-analyzer.md +43 -0
  8. package/agents/context-doc-verifier.md +94 -0
  9. package/agents/dependency-auditor.md +42 -0
  10. package/agents/implementer.md +135 -0
  11. package/agents/logic-reviewer.md +132 -0
  12. package/agents/migration.md +55 -0
  13. package/agents/performance.md +95 -0
  14. package/agents/plan-conformance.md +127 -0
  15. package/agents/plan-grounding-check.md +106 -0
  16. package/agents/planner.md +143 -0
  17. package/agents/playwright.md +68 -0
  18. package/agents/research.md +52 -0
  19. package/agents/security.md +88 -0
  20. package/agents/style-reviewer.md +85 -0
  21. package/agents/test.md +206 -0
  22. package/agents/ui-consistency.md +75 -0
  23. package/dist/manifest.d.ts +2 -0
  24. package/dist/manifest.js +34 -0
  25. package/dist/manifest.js.map +1 -0
  26. package/dist/src/bundle.d.ts +2 -0
  27. package/dist/src/bundle.js +424 -0
  28. package/dist/src/bundle.js.map +1 -0
  29. package/dist/src/index.d.ts +5 -0
  30. package/dist/src/index.js +14 -0
  31. package/dist/src/index.js.map +1 -0
  32. package/dist/src/invariants.d.ts +10 -0
  33. package/dist/src/invariants.js +208 -0
  34. package/dist/src/invariants.js.map +1 -0
  35. package/dist/src/policy-resolver.d.ts +2 -0
  36. package/dist/src/policy-resolver.js +65 -0
  37. package/dist/src/policy-resolver.js.map +1 -0
  38. package/dist/src/sandbox-rules.d.ts +2 -0
  39. package/dist/src/sandbox-rules.js +40 -0
  40. package/dist/src/sandbox-rules.js.map +1 -0
  41. package/dist/test/bundle.test.d.ts +1 -0
  42. package/dist/test/bundle.test.js +289 -0
  43. package/dist/test/bundle.test.js.map +1 -0
  44. package/dist/test/sandbox-rules.test.d.ts +1 -0
  45. package/dist/test/sandbox-rules.test.js +73 -0
  46. package/dist/test/sandbox-rules.test.js.map +1 -0
  47. package/knowledge/references/api-design.md +188 -0
  48. package/knowledge/references/arch-patterns.md +106 -0
  49. package/knowledge/references/caching.md +190 -0
  50. package/knowledge/references/concurrency.md +195 -0
  51. package/knowledge/references/db-postgres.md +153 -0
  52. package/knowledge/references/e2e-flutter.md +56 -0
  53. package/knowledge/references/e2e-playwright.md +53 -0
  54. package/knowledge/references/error-handling.md +208 -0
  55. package/knowledge/references/next-app-router.md +231 -0
  56. package/knowledge/references/observability.md +169 -0
  57. package/knowledge/references/optimization-strategy.md +197 -0
  58. package/knowledge/references/perf-flutter.md +62 -0
  59. package/knowledge/references/perf-nestjs.md +59 -0
  60. package/knowledge/references/perf-python.md +50 -0
  61. package/knowledge/references/perf-react.md +52 -0
  62. package/knowledge/references/react19.md +176 -0
  63. package/knowledge/references/redis.md +175 -0
  64. package/knowledge/references/security-backend.md +219 -0
  65. package/knowledge/references/test-flutter.md +65 -0
  66. package/knowledge/references/test-nestjs.md +82 -0
  67. package/knowledge/references/test-python.md +76 -0
  68. package/knowledge/references/test-react.md +66 -0
  69. package/knowledge/references/test-strategy.md +175 -0
  70. package/knowledge/references/ui-flutter.md +56 -0
  71. package/knowledge/references/ui-web.md +51 -0
  72. package/package.json +34 -0
  73. package/schemas/agent-feedback.schema.json +80 -0
  74. package/schemas/category-vocab.json +170 -0
  75. package/schemas/classifier-output.schema.json +53 -0
  76. package/schemas/finding.schema.json +92 -0
  77. package/schemas/pipeline-state.schema.json +238 -0
  78. package/schemas/reviewer-output.schema.json +62 -0
  79. package/schemas/state-extension.schema.json +53 -0
  80. package/schemas/validator-output.schema.json +48 -0
  81. package/stack-candidates.yaml +248 -0
@@ -0,0 +1,219 @@
1
+ ---
2
+ tags: [security, auth, authentication, authorization, jwt, oauth, secrets, backend]
3
+ stack_signals:
4
+ - project_type: [backend, monorepo]
5
+ summary: |
6
+ Backend security stance — input is hostile until proven otherwise. Covers
7
+ authentication, authorization, sessions, JWTs, cookies, secrets handling,
8
+ input validation, file uploads, SQL/NoSQL with user input, CORS/CSRF.
9
+ when_to_load: |
10
+ Task touches authentication, authorization, sessions, JWTs, cookies,
11
+ secrets/env vars, input validation, file uploads, SQL or NoSQL queries
12
+ with user input, server-side rendering of user content, CORS/CSRF
13
+ middleware, logging of user data, or password handling. Diff in auth/,
14
+ middleware/, routes/, controllers/, or new DB queries built from user input
15
+ also qualifies.
16
+ agent_hints: [security, logic-reviewer, challenger-reviewer]
17
+ ---
18
+
19
+ # Backend Security — Senior Stance
20
+
21
+ ## When this applies
22
+ Load when task touches: authentication, authorization, sessions, JWTs, cookies, secrets/env vars, input validation, file uploads, SQL or NoSQL queries with user input, server-side rendering of user content, CORS/CSRF middleware, logging of user data, password handling. Reviewer (especially Security Agent) auto-loads when diff includes auth code, route handlers accepting user input, DB queries built from user input, or any change in `auth/`, `middleware/`, `routes/`, `controllers/`. Also referenced by orchestrator's `--no-tests` confirmation prompt — backend-security-sensitive scope.
23
+
24
+ ## Default Stance
25
+ Backend security failures are silent until they're not. Most app code is trusted to be correct; security code is trusted to be paranoid. Default to "this input is hostile until proven otherwise". Validate at the boundary, log without leaking, fail closed, sandbox what you can't trust. Time spent on auth design pays off; time spent debugging an exploited deployment after the fact does not.
26
+
27
+ ## Patterns (use these)
28
+
29
+ ### Authentication: tokens with short expiry + refresh
30
+ - Access token: short-lived (15 min - 1 hour), used per request.
31
+ - Refresh token: longer-lived (days/weeks), only sent to refresh endpoint, rotation on use.
32
+ - Server-side revocation list for refresh tokens (DB or Redis with TTL).
33
+ - JWT signed with strong key (RS256 or ES256 preferred over HS256 for distributed verification). Validate `alg`, `iss`, `aud`, `exp`, `nbf` on every request.
34
+
35
+ ### Authorization: explicit per-resource check
36
+ - Authn produces a principal; authz checks the principal vs the resource per request.
37
+ - "Can this principal perform this action on this resource?" — answered by an explicit check, not by URL pattern alone.
38
+ - Default DENY. Whitelist allowed actions. No "if not in this blocklist, allow".
39
+ - Audit log every privileged action with `actor_id`, `target_id`, `action`, `outcome`, `request_id`.
40
+
41
+ ### Input validation at the boundary
42
+ - Validate at controller entry, BEFORE the request hits any business logic.
43
+ - Reject unknown fields explicitly (don't silently ignore). Tools: Zod, Pydantic, class-validator, JSON Schema.
44
+ - Validate types AND ranges AND lengths. `string` is not enough; `string between 1 and 200 chars matching /^[a-zA-Z0-9_]+$/` is.
45
+ - File uploads: check size, MIME type, magic bytes. Re-encode images server-side; never trust client-supplied content-type.
46
+
47
+ ### SQL: parameterized queries always
48
+ - ORM: usually parameterized by default. Never `prisma.$queryRawUnsafe` with user input.
49
+ - Raw SQL: `pg.query('SELECT * WHERE id = $1', [userId])`, never `\`SELECT * WHERE id = ${userId}\``.
50
+ - Even for "trusted" internal callers — defense in depth.
51
+ - Avoid dynamic table/column names from user input. If you must, allowlist the values.
52
+
53
+ ### Secrets handling
54
+ - NEVER commit secrets to git. Even ".env.example" should have placeholder values.
55
+ - Load from env vars or a secrets manager (Vault, AWS Secrets Manager, GCP Secret Manager).
56
+ - Rotate regularly. After any incident, immediately.
57
+ - Don't log secrets. Don't include them in error messages. Don't return them in API responses.
58
+ - Frontend bundles: anything in `process.env.NEXT_PUBLIC_*` / `VITE_*` is PUBLIC. Never put secrets in client-visible env vars.
59
+
60
+ ### CSRF protection
61
+ - For cookie-based auth: CSRF token (double-submit or synchronizer) required on state-changing requests.
62
+ - For pure bearer-token auth (Authorization header): CSRF less of a risk because browsers don't auto-send the header.
63
+ - SameSite cookies: `Strict` for sessions where possible; `Lax` is the default fallback.
64
+
65
+ ### CORS done right
66
+ - Specific allowed origins. Never `*` with credentials.
67
+ - Allowed methods/headers explicit, not wildcard.
68
+ - Preflight responses cached with `Access-Control-Max-Age` to reduce overhead.
69
+
70
+ ### Rate limiting at the boundary
71
+ - Per-user (authenticated) AND per-IP (unauthenticated).
72
+ - Stricter on auth endpoints (login, password reset, signup) — typical: 5 attempts / 15 min.
73
+ - Token bucket via redis-cell or equivalent.
74
+ - 429 with `Retry-After` header.
75
+
76
+ ### Password handling
77
+ - Hash with bcrypt / argon2id, NEVER MD5 / SHA1 / SHA256-without-salt.
78
+ - Bcrypt cost ≥ 12 in 2026; argon2id memory ≥ 64MiB.
79
+ - Compare with constant-time comparison.
80
+ - Rate-limit login attempts.
81
+ - Optional: pwned-passwords check at signup/change.
82
+
83
+ ### SSRF prevention
84
+ - If you accept a URL from a user (webhooks, image fetch, OAuth callback):
85
+ - Resolve DNS server-side; reject private IP ranges (10.x, 172.16-31.x, 192.168.x, 127.x, 169.254.x, fc00::/7, fe80::/10, ::1).
86
+ - Disallow `file://`, `gopher://`, `ftp://` etc. — only `https://` (or `http://` with explicit scope).
87
+ - Set short timeout; cap response size.
88
+
89
+ ### Path traversal prevention
90
+ - Never use user input directly in file paths.
91
+ - Resolve and check: `resolved = path.resolve(base, userPath); if (!resolved.startsWith(base)) reject`.
92
+ - Reject `..` / null bytes / absolute paths.
93
+
94
+ ### Server-side rendering of user content
95
+ - Encode for the context: HTML body, HTML attribute, JS, CSS, URL — each has different escape rules.
96
+ - Frameworks (React, Vue, Svelte, etc.) auto-escape by default. Be wary of `dangerouslySetInnerHTML`, `v-html`, `{@html}` — these bypass.
97
+ - For markdown/HTML user input: sanitize with a vetted lib (DOMPurify, bleach) — allowlist, not blocklist.
98
+
99
+ ### Sensitive data overreturn
100
+ API endpoint returns full user record including `password_hash`, `email_verified_at`, internal flags.
101
+ **Rule:** explicit response DTOs. List the fields you're sending. Never `return user` directly when `user` is the DB row.
102
+
103
+ ## Anti-Patterns (DO NOT)
104
+
105
+ ### Auth check in component, not in action
106
+ React Server Action does work; auth check is in the calling component.
107
+ **Why it bites:** action callable directly via fetch from anywhere. Components aren't security boundaries.
108
+ **Rule:** every Server Action begins with explicit auth check. Same for API routes, GraphQL resolvers, RPC methods.
109
+
110
+ ### Trusting `req.user` without verifying token freshness
111
+ Token decoded once at session start; for hours, code uses cached `req.user` without re-checking expiry, revocation, or scope changes.
112
+ **Rule:** validate token on every request (cheap with stateless JWT). For revocation, check Redis/DB on every request (or accept short cache window matching revocation SLA).
113
+
114
+ ### `eval` / `Function()` / dynamic require with user input
115
+ **Why it bites:** RCE.
116
+ **Rule:** never `eval` user input. If you need dynamic execution, use a sandbox (vm2 etc., though even those have escapes) and severely restrict capability.
117
+
118
+ ### MD5 / SHA1 / unsalted SHA256 for passwords
119
+ **Rule:** bcrypt or argon2id. Never anything weaker.
120
+
121
+ ### Comparing tokens / hashes with `==`
122
+ Timing-attack vulnerable. Naive equality reveals string length and partial match by timing.
123
+ **Rule:** constant-time compare (`crypto.timingSafeEqual` in Node, `hmac.compare_digest` in Python).
124
+
125
+ ### CORS `Access-Control-Allow-Origin: *` with credentials
126
+ **Why it bites:** browsers reject this anyway, but seeing it = misconfigured intent. May be loosened next sprint to "fix" the rejection.
127
+ **Rule:** explicit origin allowlist. Never wildcard with credentials.
128
+
129
+ ### Logging entire request bodies
130
+ Login request body logged → password in logs → log files compromised → password breach.
131
+ **Rule:** redact known-sensitive field paths (`password`, `token`, `card_number`, etc.) at log boundary. Whitelist what's logged, not blacklist.
132
+
133
+ ### Returning DB error messages to users
134
+ `SQLSTATE: 23505 unique constraint "users_email_key"` returned in HTTP response.
135
+ **Why it bites:** leaks schema info. Helps attackers map the DB.
136
+ **Rule:** map DB errors to user-facing categories at the boundary. "Email already in use" not "violates unique_constraint".
137
+
138
+ ### `findOne({...userInput})` without sanitization
139
+ NoSQL injection: `userInput = { $ne: null }` returns first user.
140
+ **Rule:** typed input validation. Reject objects where strings expected. ORMs help; raw drivers don't.
141
+
142
+ ### Storing JWT in localStorage
143
+ **Why it bites:** XSS reads it. There's no httpOnly defense in localStorage.
144
+ **Rule:** httpOnly cookie for session tokens (SameSite=Strict / Lax). If you must use bearer in JS, isolate via subdomain + strict CSP.
145
+
146
+ ### Client-side validation as the only validation
147
+ Client validates email format → server trusts → attacker bypasses client → server processes invalid.
148
+ **Rule:** server validates everything. Client validation is UX only.
149
+
150
+ ### Webhook endpoint without signature verification
151
+ Anyone can POST to `/webhooks/stripe` and claim to be Stripe.
152
+ **Rule:** verify signature with shared secret on every webhook. Reject unsigned/invalid.
153
+
154
+ ### Open redirect
155
+ `/login?next=https://evil.com` → after login, redirect to evil.com → phishing.
156
+ **Rule:** allowlist redirect destinations or restrict to relative paths.
157
+
158
+ ### Mass assignment
159
+ `User.update(req.body)` where `req.body` includes `is_admin: true`.
160
+ **Rule:** explicit allowlist of editable fields. Or DTO that strips non-allowed fields before update.
161
+
162
+ ### Same JWT for short-lived and long-lived contexts
163
+ One token used both for API auth (15 min OK) and for "remember me" (weeks). Compromise of either ruins both.
164
+ **Rule:** access token (short) + refresh token (long) split. Different scopes.
165
+
166
+ ## Decision Framework
167
+
168
+ | Need | Choice |
169
+ |---|---|
170
+ | Web session for users | httpOnly cookie + SameSite=Lax + CSRF token on writes |
171
+ | API token for service-to-service | Short-lived JWT, signed with RS256 |
172
+ | Long-lived "remember me" | Refresh token, server-side revocation |
173
+ | User uploads files | Size limit + MIME check + magic-bytes check + re-encode if image; store on object storage with random key |
174
+ | Password storage | argon2id (preferred) or bcrypt cost 12+ |
175
+ | Per-resource permission | Explicit authz check per request; default deny |
176
+ | Rate limit on login/signup | 5 req / 15 min per IP + per username |
177
+ | Webhook receiver | Verify signature; reject unsigned |
178
+ | URL fetched from user | Allowlist domains OR SSRF protection (DNS resolve + private-IP rejection) |
179
+ | Sensitive log content | Redact at log boundary; whitelist what's emitted |
180
+ | Admin actions | Re-auth (step-up) before privileged actions; audit log all |
181
+ | CORS | Specific origins; no wildcard with credentials |
182
+
183
+ ## Cost Model
184
+
185
+ | Vulnerability | Cost when exploited |
186
+ |---|---|
187
+ | SQL injection | Full DB compromise; data exfiltration; possible RCE |
188
+ | XSS | Session theft; account takeover at scale |
189
+ | Auth bypass | Full system compromise |
190
+ | SSRF | Internal service compromise; cloud metadata endpoint exposure (AWS IMDS) |
191
+ | Open redirect | Phishing campaigns leveraging your domain |
192
+ | Weak password hash | Password breach → credential stuffing across other sites |
193
+ | CSRF on sensitive action | Drive-by state changes from malicious sites |
194
+ | Token in localStorage + XSS | Account takeover via single XSS |
195
+ | Excessive log content with PII | GDPR fine; user data exposure |
196
+
197
+ ## Red Flags in Diff
198
+
199
+ - New raw SQL string built with template literals containing user input → flag immediately (SQL injection).
200
+ - New endpoint without explicit auth check at top of handler → flag.
201
+ - New `eval`, `new Function`, `vm.runInNewContext` with user input → flag immediately (RCE).
202
+ - Password handling using `crypto.createHash('md5'|'sha1'|'sha256')` directly → flag.
203
+ - Token/hash compared with `===` / `==` → flag (use constant-time compare).
204
+ - `dangerouslySetInnerHTML` / `v-html` / `{@html}` with user content → flag (XSS unless sanitized).
205
+ - New `Access-Control-Allow-Origin: *` with `credentials: true` → flag immediately.
206
+ - `findOne(req.body)` / `find(req.query)` patterns → flag (NoSQL injection / mass assignment).
207
+ - New `User.update(req.body)` without explicit field allowlist → flag (mass assignment).
208
+ - `localStorage.setItem('token', ...)` for session token → flag (XSS exposure).
209
+ - `redirect(req.query.next)` without allowlist → flag (open redirect).
210
+ - New webhook endpoint without signature verification → flag.
211
+ - Logging `req.body` directly → flag (PII / secrets in logs).
212
+ - Error response containing stack trace / DB error verbatim → flag (info leak).
213
+ - New URL fetch from user input without SSRF protection → flag.
214
+ - `path.join(baseDir, userInput)` without resolved-path check → flag (path traversal).
215
+ - Secrets / API keys / DB URLs visible in `process.env.NEXT_PUBLIC_*` or `VITE_*` → flag (client bundle exposure).
216
+ - New JWT validation skipping `exp` / `aud` / `iss` checks → flag.
217
+ - Missing rate limit on auth endpoint (login, signup, password-reset) → flag.
218
+ - Bcrypt cost < 12 / argon2id memory < 64MiB → flag.
219
+ - Cache layer caching responses across users without `Vary` / proper key → flag (cross-user data leak).
@@ -0,0 +1,65 @@
1
+ ---
2
+ tags: [testing, flutter, dart, widget-test, mobile]
3
+ stack_signals:
4
+ - language: [dart]
5
+ - project_type: [mobile, frontend-app]
6
+ summary: |
7
+ Flutter / Dart testing — widget tests for logic-bearing widgets, naming
8
+ conventions, do-not-test rules for pure layout.
9
+ when_to_load: |
10
+ Task writes or changes tests for a Flutter codebase, OR review of test
11
+ code in a Flutter project. pubspec.yaml with flutter_test in
12
+ dev_dependencies.
13
+ agent_hints: [test, acceptance, logic-reviewer]
14
+ ---
15
+
16
+ # Testing: Flutter / Dart
17
+
18
+ ## Framework Detection
19
+ - `pubspec.yaml` with `flutter_test` in dev_dependencies → `flutter test`
20
+ - `test/` directory with `*_test.dart` files → match existing patterns
21
+ - `integration_test/` → integration tests (run separately)
22
+
23
+ ## What to Test
24
+ **Widgets — only if they contain logic:**
25
+ - Widget renders correctly with given parameters
26
+ - User interaction (tap, swipe) → expected state change
27
+ - Conditional rendering based on state
28
+ - Do NOT test: pure layout widgets, theme styling, static text
29
+
30
+ ## File Naming
31
+ `*_test.dart` in `test/` directory (mirroring `lib/` structure)
32
+
33
+ ## Finder Priority
34
+ Prefer in this order:
35
+ 1. `find.byKey` (most stable, immune to text/type changes)
36
+ 2. `find.byType` (good for unique widgets)
37
+ 3. `find.text` (for verifying visible content)
38
+
39
+ ## pump vs pumpAndSettle
40
+ - `tester.pump()` — advance one frame. Use when you need precise frame control.
41
+ - `tester.pumpAndSettle()` — pump until no more frames scheduled. Use after actions that trigger animations/transitions. Default timeout is 10 seconds — pass custom `Duration` for slow screens.
42
+ - After `tester.tap()` / `tester.enterText()` → always pump or pumpAndSettle.
43
+
44
+ ## Mocking
45
+ - `mocktail` or `mockito` for dependencies
46
+ - `ProviderScope.overrides` for Riverpod state
47
+ - `BlocProvider` with mock blocs for BLoC pattern
48
+ - `pumpWidget()` with required providers and `MaterialApp` wrapper
49
+
50
+ ## Golden (Screenshot) Testing
51
+ - Use `matchesGoldenFile('goldens/widget_name.png')` for visual regression
52
+ - Run `flutter test --update-goldens` to generate/update baselines
53
+ - Store goldens in version control
54
+ - Goldens are platform-sensitive — generate on CI or use `alchemist` for platform-agnostic goldens
55
+
56
+ ## Async Testing
57
+ - `expectLater` with `emitsInOrder` for Stream assertions
58
+ - `tester.runAsync(() async { ... })` for real async operations in widget tests
59
+ - Wrap Future assertions in `expectLater` not `expect`
60
+
61
+ ## Do NOT
62
+ - Test implementation details (internal state variables)
63
+ - Test third-party package widgets
64
+ - Use arbitrary `Future.delayed` — use pump/pumpAndSettle
65
+ - Forget to `addTearDown` for controllers/subscriptions created in tests
@@ -0,0 +1,82 @@
1
+ ---
2
+ tags: [testing, nestjs, jest, backend]
3
+ stack_signals:
4
+ - language: [typescript, javascript]
5
+ - project_type: [backend, monorepo]
6
+ summary: |
7
+ NestJS testing patterns — Jest defaults, controller validation, service
8
+ input/output mapping, auth guard behavior, error response shapes.
9
+ when_to_load: |
10
+ Task writes or changes tests for a NestJS backend, OR review of test code
11
+ in a NestJS project. jest.config present.
12
+ agent_hints: [test, acceptance, logic-reviewer]
13
+ ---
14
+
15
+ # Testing: NestJS
16
+
17
+ ## Framework Detection
18
+ - `jest.config.*` or `package.json "jest"` → Jest (built-in with NestJS)
19
+
20
+ ## What to Test
21
+ **Controllers / Endpoints:**
22
+ - Request validation (missing fields, wrong types via class-validator)
23
+ - Success response shape
24
+ - Error responses (401, 403, 404, 422)
25
+ - Auth guard behavior
26
+
27
+ **Services:**
28
+ - Input → output mapping
29
+ - Error handling paths
30
+ - Edge cases
31
+
32
+ **Guards / Pipes / Interceptors:**
33
+ - Guard returns true/false correctly based on request context
34
+ - Pipe transforms/validates input correctly
35
+ - Interceptor modifies response as expected
36
+
37
+ ## File Naming
38
+ - Unit tests: `*.spec.ts` (colocated with source)
39
+ - E2E tests: `*.e2e-spec.ts` in `test/` directory
40
+
41
+ ## Module Setup
42
+ ```typescript
43
+ const module = await Test.createTestingModule({
44
+ providers: [
45
+ ServiceUnderTest,
46
+ { provide: DependencyService, useValue: mockDependency },
47
+ ],
48
+ }).compile();
49
+
50
+ const service = module.get(ServiceUnderTest);
51
+ ```
52
+
53
+ ## HTTP Testing
54
+ Use `supertest` for endpoint tests:
55
+ ```typescript
56
+ const app = module.createNestApplication();
57
+ await app.init();
58
+ await request(app.getHttpServer())
59
+ .get('/endpoint')
60
+ .expect(200)
61
+ .expect({ data: expected });
62
+ ```
63
+
64
+ ## Mocking
65
+ - `overrideProvider(Service).useValue(mock)` in TestingModule
66
+ - `jest.mock()` for external modules
67
+ - Custom providers for DB/HTTP mocks
68
+ - `@nestjs/testing` utilities for full module compilation
69
+
70
+ ## DTO Validation Testing
71
+ Test that class-validator decorators reject invalid input:
72
+ ```typescript
73
+ const dto = plainToInstance(CreateUserDto, { name: '' });
74
+ const errors = await validate(dto);
75
+ expect(errors.length).toBeGreaterThan(0);
76
+ ```
77
+
78
+ ## Do NOT
79
+ - Test NestJS framework internals (DI resolution, module loading)
80
+ - Leave real DB/HTTP calls in unit tests
81
+ - Share state between tests (each test gets fresh module)
82
+ - Test generated code (Prisma client, TypeORM entities with no custom logic)
@@ -0,0 +1,76 @@
1
+ ---
2
+ tags: [testing, python, pytest, unittest, backend]
3
+ stack_signals:
4
+ - language: [python]
5
+ - project_type: [backend, monorepo]
6
+ summary: |
7
+ Python testing patterns — pytest vs unittest detection, API/service
8
+ testing, fixtures, mocking external calls.
9
+ when_to_load: |
10
+ Task writes or changes tests for a Python codebase, OR review of test code
11
+ in a Python project. pytest.ini / pyproject.toml [tool.pytest] / conftest.py
12
+ present.
13
+ agent_hints: [test, acceptance, logic-reviewer]
14
+ ---
15
+
16
+ # Testing: Python
17
+
18
+ ## Framework Detection
19
+ - `pytest.ini`, `pyproject.toml [tool.pytest]`, `conftest.py` → pytest
20
+ - `unittest` imports in existing code → unittest
21
+ - Neither → recommend pytest
22
+
23
+ ## What to Test
24
+ **API Endpoints:**
25
+ - Request validation (missing fields, wrong types)
26
+ - Success response shape
27
+ - Error responses (401, 403, 404, 422)
28
+ - Auth guard behavior
29
+
30
+ **Services / Business Logic:**
31
+ - Input → output mapping
32
+ - Edge cases (empty, null, boundary values)
33
+ - Error handling paths
34
+
35
+ ## File Naming
36
+ `test_*.py` in `tests/` directory
37
+
38
+ ## Fixtures
39
+ - Use `conftest.py` for shared fixtures
40
+ - Scope correctly: `function` (default), `module`, `session`
41
+ - Compose fixtures — small focused fixtures combined in tests
42
+ - Factory fixtures for creating test data with overrides
43
+
44
+ ## Parametrize
45
+ Use `@pytest.mark.parametrize` for testing multiple inputs:
46
+ ```python
47
+ @pytest.mark.parametrize("input,expected", [
48
+ ("valid", True),
49
+ ("", False),
50
+ (None, False),
51
+ ])
52
+ def test_validate(input, expected):
53
+ assert validate(input) == expected
54
+ ```
55
+
56
+ ## Async Testing
57
+ - `@pytest.mark.asyncio` for async test functions
58
+ - `AsyncMock` for mocking async dependencies
59
+ - `pytest-asyncio` plugin with `asyncio_mode = "auto"` in config
60
+
61
+ ## FastAPI-Specific
62
+ - `httpx.AsyncClient` with `ASGITransport(app=app)` for async endpoint tests
63
+ - Override dependencies via `app.dependency_overrides[get_db] = mock_db`
64
+ - Test lifespan events separately if they have side effects
65
+
66
+ ## Mocking
67
+ - `unittest.mock.AsyncMock` / `MagicMock` for dependencies
68
+ - `pytest` fixtures for DB/connection setup
69
+ - `monkeypatch` for env vars and simple attribute patches
70
+ - `pytest.raises(ExceptionType)` for exception assertions
71
+
72
+ ## Do NOT
73
+ - Use `mock.patch` on the thing being tested
74
+ - Hardcode dates — use `freezegun` or fixture
75
+ - Rely on test execution order
76
+ - Leave real network calls in unit tests
@@ -0,0 +1,66 @@
1
+ ---
2
+ tags: [testing, react, nextjs, vitest, jest, frontend]
3
+ stack_signals:
4
+ - language: [typescript, javascript]
5
+ - project_type: [frontend-app, monorepo]
6
+ summary: |
7
+ React / Next.js testing — Vitest / Jest detection, what to test
8
+ (components with logic, hooks, mutations), Testing Library patterns.
9
+ when_to_load: |
10
+ Task writes or changes tests for a React/Next.js codebase, OR review of
11
+ test code in a React/Next.js project. Vitest/Jest config present.
12
+ agent_hints: [test, acceptance, logic-reviewer]
13
+ ---
14
+
15
+ # Testing: React / Next.js
16
+
17
+ ## Framework Detection
18
+ - `vitest.config.*` or `vite.config.* with test` → Vitest
19
+ - `jest.config.*` or `package.json "jest"` → Jest
20
+ - Neither → check CLAUDE.md stack. React/Next.js → recommend Vitest. NestJS → Jest (built-in).
21
+
22
+ ## What to Test
23
+ **Components — only if they contain logic:**
24
+ - Conditional rendering
25
+ - User interaction → expected outcome
26
+ - Do NOT test: pure layout, styling, static content
27
+
28
+ **Custom hooks:**
29
+ - Use `renderHook` from Testing Library
30
+ - Test state changes, return values, cleanup
31
+
32
+ ## File Naming
33
+ `*.test.ts`, `*.test.tsx`, `*.spec.ts`
34
+
35
+ ## Query Priority (Testing Library)
36
+ Prefer in this order:
37
+ 1. `getByRole` (most accessible)
38
+ 2. `getByLabelText`
39
+ 3. `getByText`
40
+ 4. `getByTestId` (last resort)
41
+
42
+ ## User Interaction
43
+ Prefer `userEvent` over `fireEvent` — it simulates real browser behavior:
44
+ ```typescript
45
+ import userEvent from '@testing-library/user-event';
46
+ const user = userEvent.setup();
47
+ await user.click(button);
48
+ await user.type(input, 'text');
49
+ ```
50
+
51
+ ## Async Patterns
52
+ - Use `waitFor` / `findBy*` for async state updates
53
+ - Handle act() warnings by using Testing Library's async utilities
54
+ - Always `await` user events
55
+
56
+ ## Mocking
57
+ - MSW for API mocking (intercepts at network level)
58
+ - `vi.mock()` / `jest.mock()` for module mocks
59
+ - `renderWithProviders` wrapper for QueryClient + Router + Store
60
+ - Mock router: `MemoryRouter` with initial entries
61
+
62
+ ## Do NOT
63
+ - Test implementation details (internal state, method calls)
64
+ - Test third-party library behavior
65
+ - Use snapshot tests unless project already has them
66
+ - Hardcode dates or rely on test execution order