SUMMARY.md for 04-02: listEmitter + listAccess TDD plan. RED/GREEN gate confirmed. D-04 isolation proven. ioredis not introduced.
6.1 KiB
6.1 KiB
phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, decisions, metrics
| phase | plan | subsystem | tags | dependency_graph | tech_stack | key_files | decisions | metrics | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 04-shared-lists-live-sync | 02 | api-lib, test-harness |
|
|
|
|
|
|
Phase 4 Plan 2: Scoped Fan-out Primitives Summary
One-liner: In-memory per-list EventEmitter singleton (listEmitter.ts) + owner/shares access-scope query (listAccess.ts) with D-04 isolation proven by RED/GREEN TDD gate.
TDD Gate Compliance
| Gate | Commit | Status |
|---|---|---|
| RED — failing tests | 2d250af |
PASS — module-not-found; 6 tests failed as expected |
| GREEN — implementation | 792efeb |
PASS — all 9 tests pass |
| REFACTOR | (skipped) | No refactoring needed — implementation was clean on first pass |
Tasks Completed
| Task | Name | Commit | Files |
|---|---|---|---|
| RED | Write failing listEmitter + listAccess tests | 2d250af |
listEmitter.test.ts (stubs → assertions), listAccess.test.ts (new) |
| GREEN | Implement listEmitter.ts + listAccess.ts | 792efeb |
listEmitter.ts, listAccess.ts, listAccess.test.ts (UUID fix), vitest.config.ts |
| FIX | fileParallelism:false to eliminate DB race condition | 9e17853 |
vitest.config.ts |
Deviations from Plan
Auto-fixed Issues
1. [Rule 1 - Bug] Test seed helper oidc_sub collisions across runs
- Found during: GREEN phase — running both test files together
- Issue:
seedUser('owner-5')insertedsub-owner-5on first run; on the second run (or when running tests without cleanup of the users table), theuniq_oidc_identitykey firedER_DUP_ENTRY. - Fix: Added
randomUUID()suffix:oidcSub: sub-${label}-${randomUUID()}— unique per invocation regardless of table state. - Files modified:
apps/api/tests/lib/listAccess.test.ts - Commit:
792efeb
2. [Rule 1 - Bug] Concurrent test files race against shared-MariaDB global afterEach
- Found during: GREEN phase — running both test files together (and during full suite run)
- Issue: vitest defaults to
fileParallelism: true. The globalafterEachintest/setup.tsruns in every worker and truncateslists/listShares. When two DB-backed test files ran concurrently, file A'safterEachdeleted rows that file B's test was still reading — producing FK violations (ER_NO_REFERENCED_ROW_2) and incorrect empty results. - Fix: Added
fileParallelism: falsetovitest.config.ts, serializing test file execution. - Files modified:
apps/api/vitest.config.ts - Commit:
9e17853
Verification Results
TDD Tests
- listEmitter suite: 5 passed (Tests 1-4 + D-18 scale check)
- listAccess suite: 4 passed (Tests 5-8)
- Test 2 (D-04 cross-list negative): GREEN — handler subscribed to list 1 received 0 events when list 2 published
- Test 7 (D-04 private-list negative): GREEN —
getAccessibleListIds(otherUser)did not return a list owned exclusively by another user
Full API Suite
- 15 test files passed | 3 skipped (Wave-0 stubs, expected) | 117 passed | 38 todo
- No regressions from prior plans
TypeScript
pnpm --filter @familysync/api exec tsc --noEmit— PASS
ioredis Check
grep -r "ioredis" apps/api/— not present (D-18 confirmed)
Known Stubs
None. Both modules are fully implemented and tested.
Threat Surface Scan
| Flag | File | Description |
|---|---|---|
| T-04-02 (mitigated) | apps/api/src/lib/listEmitter.ts | Fan-out channel keyed by listId; cross-list isolation proven by Test 2 |
| T-04-03 (mitigated) | apps/api/src/lib/listAccess.ts | Access-scope query restricted to owner_id OR list_shares; over-return proven impossible by Test 7 |
| T-04-04 (accepted) | apps/api/src/lib/listEmitter.ts | setMaxListeners(200) headroom applied; DoS risk accepted for household scale |
Self-Check: PASSED
apps/api/src/lib/listEmitter.ts— FOUNDapps/api/src/lib/listAccess.ts— FOUNDapps/api/tests/lib/listEmitter.test.ts— FOUND (stubs replaced)apps/api/tests/lib/listAccess.test.ts— FOUNDapps/api/vitest.config.ts— FOUND (fileParallelism:false)- Commit
2d250af(RED) — FOUND - Commit
792efeb(GREEN) — FOUND - Commit
9e17853(fix) — FOUND