docs(16-03): complete route and MCP userId wiring plan
- SUMMARY.md documenting 2 tasks, 13 files modified - STATE.md updated with plan progress and decisions - ROADMAP.md marks 16-03 complete - REQUIREMENTS.md marks MULTI-05 complete
This commit is contained in:
@@ -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-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-03**: Categories use composite unique constraint (userId + name)
|
||||||
- [x] **MULTI-04**: Existing data is assigned to the original user during migration
|
- [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
|
- [x] **MULTI-06**: Settings are per-user rather than global
|
||||||
|
|
||||||
### Image Storage
|
### Image Storage
|
||||||
@@ -130,7 +130,7 @@ Which phases cover which requirements. Updated during roadmap creation.
|
|||||||
| MULTI-02 | Phase 16 | Complete |
|
| MULTI-02 | Phase 16 | Complete |
|
||||||
| MULTI-03 | Phase 16 | Complete |
|
| MULTI-03 | Phase 16 | Complete |
|
||||||
| MULTI-04 | Phase 16 | Complete |
|
| MULTI-04 | Phase 16 | Complete |
|
||||||
| MULTI-05 | Phase 16 | Pending |
|
| MULTI-05 | Phase 16 | Complete |
|
||||||
| MULTI-06 | Phase 16 | Complete |
|
| MULTI-06 | Phase 16 | Complete |
|
||||||
| IMG-01 | Phase 17 | Pending |
|
| IMG-01 | Phase 17 | Pending |
|
||||||
| IMG-02 | Phase 17 | Pending |
|
| IMG-02 | Phase 17 | Pending |
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ Plans:
|
|||||||
Plans:
|
Plans:
|
||||||
- [x] 16-01-PLAN.md — Schema foundation: users table, userId columns, auth middleware, test helper
|
- [x] 16-01-PLAN.md — Schema foundation: users table, userId columns, auth middleware, test helper
|
||||||
- [x] 16-02-PLAN.md — Service layer userId scoping
|
- [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
|
- [ ] 16-04-PLAN.md — Test suite updates
|
||||||
|
|
||||||
### Phase 17: Object Storage
|
### Phase 17: Object Storage
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ See: .planning/PROJECT.md (updated 2026-04-03)
|
|||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Phase: 16 of 18 (Multi-User Data Model)
|
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
|
Status: Ready to execute
|
||||||
Last activity: 2026-04-05
|
Last activity: 2026-04-05
|
||||||
|
|
||||||
@@ -36,9 +36,9 @@ Progress: [#---------] 5% (v2.0 milestone)
|
|||||||
|
|
||||||
**Velocity:**
|
**Velocity:**
|
||||||
|
|
||||||
- Total plans completed: 1 (v2.0 milestone)
|
- Total plans completed: 2 (v2.0 milestone)
|
||||||
- Average duration: 8min
|
- Average duration: 7min
|
||||||
- Total execution time: 8min
|
- Total execution time: 14min
|
||||||
|
|
||||||
*Updated after each plan completion*
|
*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]: 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]: Candidate operations verify parent thread ownership for cross-user isolation
|
||||||
- [Phase 16]: syncSetupItems validates both setup and item ownership via inArray
|
- [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
|
### Pending Todos
|
||||||
|
|
||||||
@@ -73,5 +76,5 @@ None active.
|
|||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-04-05T08:45:22.408Z
|
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
|
Resume file: None
|
||||||
|
|||||||
124
.planning/phases/16-multi-user-data-model/16-03-SUMMARY.md
Normal file
124
.planning/phases/16-multi-user-data-model/16-03-SUMMARY.md
Normal file
@@ -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*
|
||||||
Reference in New Issue
Block a user