diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 06481ee..2b36cb6 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -29,7 +29,7 @@ Requirements for this milestone. Each maps to roadmap phases. - [x] **MULTI-02**: User can only see and modify their own data (cross-user isolation) - [x] **MULTI-03**: Categories use composite unique constraint (userId + name) - [x] **MULTI-04**: Existing data is assigned to the original user during migration -- [ ] **MULTI-05**: MCP tools operate within the authenticated user's scope +- [x] **MULTI-05**: MCP tools operate within the authenticated user's scope - [x] **MULTI-06**: Settings are per-user rather than global ### Image Storage @@ -130,7 +130,7 @@ Which phases cover which requirements. Updated during roadmap creation. | MULTI-02 | Phase 16 | Complete | | MULTI-03 | Phase 16 | Complete | | MULTI-04 | Phase 16 | Complete | -| MULTI-05 | Phase 16 | Pending | +| MULTI-05 | Phase 16 | Complete | | MULTI-06 | Phase 16 | Complete | | IMG-01 | Phase 17 | Pending | | IMG-02 | Phase 17 | Pending | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index e79cbeb..9036016 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -149,7 +149,7 @@ Plans: Plans: - [x] 16-01-PLAN.md — Schema foundation: users table, userId columns, auth middleware, test helper - [x] 16-02-PLAN.md — Service layer userId scoping -- [ ] 16-03-PLAN.md — Route handlers userId extraction +- [x] 16-03-PLAN.md — Route handlers userId extraction - [ ] 16-04-PLAN.md — Test suite updates ### Phase 17: Object Storage diff --git a/.planning/STATE.md b/.planning/STATE.md index 7cf3eaa..6b52cb9 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -26,7 +26,7 @@ See: .planning/PROJECT.md (updated 2026-04-03) ## Current Position Phase: 16 of 18 (Multi-User Data Model) -Plan: 2 of 4 in current phase +Plan: 3 of 4 in current phase Status: Ready to execute Last activity: 2026-04-05 @@ -36,9 +36,9 @@ Progress: [#---------] 5% (v2.0 milestone) **Velocity:** -- Total plans completed: 1 (v2.0 milestone) -- Average duration: 8min -- Total execution time: 8min +- Total plans completed: 2 (v2.0 milestone) +- Average duration: 7min +- Total execution time: 14min *Updated after each plan completion* @@ -60,6 +60,9 @@ Key decisions made during v2.0 execution: - [Phase 16]: Category deletion uses dynamic getOrCreateUncategorized per user instead of hardcoded ID - [Phase 16]: Candidate operations verify parent thread ownership for cross-user isolation - [Phase 16]: syncSetupItems validates both setup and item ownership via inArray +- [Phase 16-03]: Non-null assertion on c.get("userId") since requireAuth guarantees it +- [Phase 16-03]: MCP session map stores userId alongside transport for session reuse +- [Phase 16-03]: Images route unchanged -- no user-scoped DB operations ### Pending Todos @@ -73,5 +76,5 @@ None active. ## Session Continuity Last session: 2026-04-05T08:45:22.408Z -Stopped at: Completed 16-02-PLAN.md +Stopped at: Completed 16-03-PLAN.md Resume file: None diff --git a/.planning/phases/16-multi-user-data-model/16-03-SUMMARY.md b/.planning/phases/16-multi-user-data-model/16-03-SUMMARY.md new file mode 100644 index 0000000..d07dba3 --- /dev/null +++ b/.planning/phases/16-multi-user-data-model/16-03-SUMMARY.md @@ -0,0 +1,124 @@ +--- +phase: 16-multi-user-data-model +plan: 03 +subsystem: api +tags: [hono, mcp, userId, multi-user, routes, middleware] + +# Dependency graph +requires: + - phase: 16-01 + provides: "Schema with userId columns, auth middleware setting c.set('userId')" + - phase: 16-02 + provides: "Service functions accepting userId as second parameter" +provides: + - "All route handlers extract userId from context and pass to services" + - "Settings routes use composite PK [userId, key] for per-user settings" + - "MCP server creation receives userId, all tool registrations pass userId" + - "MCP auth middleware resolves userId from API key and Bearer token" +affects: [16-04, tests, e2e] + +# Tech tracking +tech-stack: + added: [] + patterns: ["userId extraction pattern: const userId = c.get('userId')!", "MCP session stores userId alongside transport"] + +key-files: + created: [] + modified: + - src/server/routes/items.ts + - src/server/routes/categories.ts + - src/server/routes/threads.ts + - src/server/routes/setups.ts + - src/server/routes/settings.ts + - src/server/routes/totals.ts + - src/server/routes/auth.ts + - src/server/mcp/index.ts + - src/server/mcp/tools/items.ts + - src/server/mcp/tools/categories.ts + - src/server/mcp/tools/threads.ts + - src/server/mcp/tools/setups.ts + - src/server/mcp/resources/collection.ts + +key-decisions: + - "Used non-null assertion (!) on c.get('userId') since requireAuth middleware guarantees it" + - "Stored userId alongside transport in MCP session map for session reuse" + - "Images route left unchanged -- image uploads have no user-scoped DB operations" + +patterns-established: + - "Route handler pattern: const userId = c.get('userId')! after const db = c.get('db')" + - "MCP tool registration pattern: registerXTools(db, userId) with userId closure" + - "Settings composite key: [settings.userId, settings.key] for onConflictDoUpdate target" + +requirements-completed: [MULTI-02, MULTI-05, MULTI-06] + +# Metrics +duration: 6min +completed: 2026-04-05 +--- + +# Phase 16 Plan 03: Route and MCP userId Wiring Summary + +**Complete userId propagation chain from auth middleware through routes and MCP tools to service layer** + +## Performance + +- **Duration:** 6 min +- **Started:** 2026-04-05T08:46:34Z +- **Completed:** 2026-04-05T08:52:52Z +- **Tasks:** 2 +- **Files modified:** 13 + +## Accomplishments +- All 36 route handler calls now extract userId from Hono context and pass to service functions +- Settings routes use composite primary key [userId, key] for per-user settings isolation +- MCP server creation receives userId, all 4 tool registration functions and collection summary pass userId +- MCP auth middleware resolves userId from both API key and Bearer token authentication + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Update all route handlers to extract and pass userId** - `e780022` (feat) +2. **Task 2: Update MCP server and tool registrations with userId** - `d4bf4f5` (feat) + +## Files Created/Modified +- `src/server/routes/items.ts` - Added userId extraction to all 8 handlers (CRUD + export/import/duplicate) +- `src/server/routes/categories.ts` - Added userId extraction to all 4 handlers +- `src/server/routes/threads.ts` - Added userId extraction to all 10 handlers (threads + candidates + reorder + resolve) +- `src/server/routes/setups.ts` - Added userId extraction to all 8 handlers (CRUD + items sync/classification/remove) +- `src/server/routes/settings.ts` - Added userId with composite key [userId, key] for reads and upserts +- `src/server/routes/totals.ts` - Added userId extraction to totals handler +- `src/server/routes/auth.ts` - Added userId extraction to API key management handlers +- `src/server/mcp/index.ts` - Updated createMcpServer(db, userId), MCP auth resolves userId, session map stores userId +- `src/server/mcp/tools/items.ts` - registerItemTools(db, userId) passes userId to all service calls +- `src/server/mcp/tools/categories.ts` - registerCategoryTools(db, userId) passes userId to all service calls +- `src/server/mcp/tools/threads.ts` - registerThreadTools(db, userId) passes userId to all service calls +- `src/server/mcp/tools/setups.ts` - registerSetupTools(db, userId) passes userId to all service calls +- `src/server/mcp/resources/collection.ts` - getCollectionSummary(db, userId) passes userId to all queries + +## Decisions Made +- Used non-null assertion (`!`) on `c.get("userId")` since `requireAuth` middleware guarantees userId is set for all data routes +- Stored userId alongside transport in MCP session map to support session reuse without re-creating MCP server +- Left images route unchanged since image upload/fetch operations have no user-scoped database queries + +## Deviations from Plan + +None - plan executed exactly as written. + +## Issues Encountered +None + +## User Setup Required +None - no external service configuration required. + +## Next Phase Readiness +- Complete userId propagation chain is in place: middleware -> routes/MCP -> services -> database +- Ready for Plan 04 (test updates) to verify the multi-user data isolation + +## Self-Check: PASSED + +All files verified present, all commits verified in history. + +--- +*Phase: 16-multi-user-data-model* +*Completed: 2026-04-05*