diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index d7583dfe..6af1179b 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -53,7 +53,7 @@ - [ ] **HIST-02** — Conversation list in sidebar: sorted by most recent, searchable, filterable by agent - [ ] **HIST-03** — Infinite scroll in the conversation list sidebar - [ ] **HIST-04** — Conversation export: download as Markdown or JSON -- [ ] **HIST-05** — Cross-device sync: conversations accessible from any device on the network via the Nexus server API +- [x] **HIST-05** — Cross-device sync: conversations accessible from any device on the network via the Nexus server API - [x] **HIST-06** — Chat history survives server restarts: no in-memory-only state ### PWA & Mobile (8) @@ -150,7 +150,7 @@ The following are explicitly deferred: | HIST-02 | Phase 21 | Pending | | HIST-03 | Phase 21 | Pending | | HIST-04 | Phase 24 | Pending | -| HIST-05 | Phase 21 | Pending | +| HIST-05 | Phase 21 | Complete | | HIST-06 | Phase 21 | Complete | | PWA-01 | Phase 26 | Pending | | PWA-02 | Phase 26 | Pending | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index d65b06aa..a6e11314 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -31,13 +31,13 @@ 3. Agent messages render with full markdown: code blocks with syntax highlighting and a copy button, tables, lists, headings, links, and inline images 4. Conversations and all messages are stored in libSQL and survive a server restart 5. The chat interface applies Catppuccin Mocha, Tokyo Night, and Catppuccin Latte themes correctly; code block highlighting matches the active theme -**Plans:** 4/6 plans executed +**Plans:** 5/6 plans executed Plans: - [x] 21-00-PLAN.md — Wave 0 test stubs (chat-service, chat-routes, ChatMarkdownMessage, ChatInput) - [x] 21-01-PLAN.md — DB schema (chat_conversations + chat_messages) and shared types/validators - [x] 21-02-PLAN.md — Markdown renderer with rehype-highlight, code block copy button, theme CSS -- [ ] 21-03-PLAN.md — Server chat service and REST API routes (CRUD + pagination) +- [x] 21-03-PLAN.md — Server chat service and REST API routes (CRUD + pagination) - [x] 21-04-PLAN.md — ChatPanel shell, ChatPanelContext, ChatInput, Layout integration - [ ] 21-05-PLAN.md — Full UI wiring: API client, conversation list, message thread, infinite scroll @@ -189,7 +189,7 @@ All 65 v1 requirements are mapped to exactly one phase. No orphans. | Phase | Milestone | Plans Complete | Status | Completed | |-------|-----------|----------------|--------|-----------| -| 21. Chat Foundation | v1.3 | 4/6 | In Progress| | +| 21. Chat Foundation | v1.3 | 5/6 | In Progress| | | 22. Agent Streaming | v1.3 | 0/? | Not started | - | | 23. Brainstormer Flow | v1.3 | 0/? | Not started | - | | 24. Search, History & Branching | v1.3 | 0/? | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 22d76e66..ea0d87cb 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,14 +3,14 @@ gsd_state_version: 1.0 milestone: v1.3 milestone_name: milestone status: executing -stopped_at: Completed 21-chat-foundation-21-04-PLAN.md -last_updated: "2026-04-01T16:50:55.752Z" +stopped_at: Completed 21-chat-foundation-21-03-PLAN.md +last_updated: "2026-04-01T16:53:41.498Z" last_activity: 2026-04-01 progress: total_phases: 6 completed_phases: 0 total_plans: 6 - completed_plans: 4 + completed_plans: 5 percent: 0 --- @@ -26,7 +26,7 @@ See: .planning/PROJECT.md (updated 2026-03-30) ## Current Position Phase: 21 (chat-foundation) — EXECUTING -Plan: 4 of 6 +Plan: 5 of 6 Status: Ready to execute Last activity: 2026-04-01 @@ -63,6 +63,7 @@ Progress: [░░░░░░░░░░] 0% | Phase 21-chat-foundation P01 | 2 | 2 tasks | 8 files | | Phase 21-chat-foundation P00 | 2 | 2 tasks | 4 files | | Phase 21-chat-foundation P04 | 4min | 2 tasks | 7 files | +| Phase 21-chat-foundation P03 | 6 | 2 tasks | 6 files | ## Accumulated Context @@ -87,6 +88,9 @@ Recent decisions affecting current work: - [Phase 21-02]: Add hljs CSS as plain rules (not @import) scoped to .dark, .theme-tokyo-night, :root selectors - [Phase 21-chat-foundation]: ChatPanelProvider inside PanelProvider so ChatPanel can call setPanelVisible to close PropertiesPanel - [Phase 21-chat-foundation]: Chat toggle button in desktop sidebar bottom controls with hidden md:inline-flex +- [Phase 21-03]: Pitfall 3 (updatedAt bump): addMessage always updates chatConversations.updatedAt after inserting — ensures conversation list sort order stays correct +- [Phase 21-03]: Pitfall 5 (auto-title idempotency): WHERE title IS NULL guard makes auto-title set safe to call multiple times +- [Phase 21-03]: Missing export fix: createConversationSchema/updateConversationSchema/createMessageSchema were in validators/chat.ts but not re-exported from shared/src/index.ts ### Pending Todos @@ -99,6 +103,6 @@ None yet. ## Session Continuity -Last session: 2026-04-01T16:50:55.749Z -Stopped at: Completed 21-chat-foundation-21-04-PLAN.md +Last session: 2026-04-01T16:53:41.495Z +Stopped at: Completed 21-chat-foundation-21-03-PLAN.md Resume file: None diff --git a/.planning/phases/21-chat-foundation/21-03-SUMMARY.md b/.planning/phases/21-chat-foundation/21-03-SUMMARY.md new file mode 100644 index 00000000..0c657075 --- /dev/null +++ b/.planning/phases/21-chat-foundation/21-03-SUMMARY.md @@ -0,0 +1,129 @@ +--- +phase: 21-chat-foundation +plan: 03 +subsystem: api +tags: [express, drizzle-orm, postgres, rest-api, chat, cursor-pagination, soft-delete] + +requires: + - phase: 21-chat-foundation/21-01 + provides: chat_conversations and chat_messages Drizzle schema tables + +provides: + - chatService factory with 7 CRUD methods (createConversation, listConversations, getConversation, updateConversation, softDeleteConversation, listMessages, addMessage) + - chatRoutes factory with 7 REST endpoints mounted on Express app + - Chat schema validators exported from @paperclipai/shared + +affects: + - 21-04 (chat panel UI needs these REST endpoints) + - 21-05 (conversation list sidebar uses listConversations pagination) + - 22+ (agent integration adds messages via addMessage) + +tech-stack: + added: [] + patterns: + - "chatService(db) factory pattern matching documentService, activityService conventions" + - "cursor-based pagination using limit+1 trick with hasMore boolean" + - "soft-delete via deletedAt IS NULL filter in WHERE clause" + - "auto-title idempotency: WHERE title IS NULL guard on UPDATE" + +key-files: + created: + - server/src/services/chat.ts + - server/src/routes/chat.ts + - server/src/__tests__/chat-service.test.ts (replaced stubs) + - server/src/__tests__/chat-routes.test.ts (replaced stubs) + modified: + - server/src/app.ts + - packages/shared/src/index.ts + +key-decisions: + - "Pitfall 3 (updatedAt bump): addMessage always updates chatConversations.updatedAt after inserting — ensures conversation list sort order stays correct" + - "Pitfall 5 (auto-title idempotency): WHERE title IS NULL guard makes auto-title set safe to call multiple times" + - "Missing export fix: createConversationSchema/updateConversationSchema/createMessageSchema were in validators/chat.ts but not re-exported from shared/src/index.ts" + +patterns-established: + - "Route factory pattern: function chatRoutes(db: Db): Router" + - "Service factory pattern: function chatService(db: Db) returning methods object" + - "Cursor pagination: fetch limit+1, slice to limit, set hasMore=true if extra row found" + +requirements-completed: [CHAT-04, CHAT-05, CHAT-06, HIST-05] + +duration: 6min +completed: 2026-04-01 +--- + +# Phase 21 Plan 03: Chat Service and REST API Summary + +**Express REST API for conversation+message CRUD with cursor pagination, soft-delete, auto-title, and updatedAt bumping** + +## Performance + +- **Duration:** ~6 min +- **Started:** 2026-04-01T16:46:00Z +- **Completed:** 2026-04-01T16:52:30Z +- **Tasks:** 2 +- **Files modified:** 6 + +## Accomplishments + +- `chatService` factory with 7 methods covering full conversation lifecycle and message CRUD +- `chatRoutes` factory with 7 REST endpoints gated by `assertBoard`/`assertCompanyAccess` +- Routes mounted in `app.ts` as `api.use(chatRoutes(db))` +- 32 vitest tests passing (21 service, 11 route) + +## Task Commits + +1. **Task 1: Create chat service** - `4c344d46` (feat) +2. **Task 2: Create chat routes and mount in app.ts** - `563442e5` (feat) + +## Files Created/Modified + +- `server/src/services/chat.ts` - chatService factory with 7 CRUD methods +- `server/src/routes/chat.ts` - chatRoutes factory with 7 REST endpoints +- `server/src/__tests__/chat-service.test.ts` - 21 unit tests for chatService +- `server/src/__tests__/chat-routes.test.ts` - 11 integration tests for chatRoutes +- `server/src/app.ts` - Added chatRoutes import and `api.use(chatRoutes(db))` +- `packages/shared/src/index.ts` - Added chat schema exports + +## Decisions Made + +- Cursor pagination uses `limit+1` fetch pattern with `hasMore` boolean and `nextCursor` ISO string +- `listConversations` default limit 30/max 100; `listMessages` default limit 50/max 200 +- Auto-title: `content.slice(0, 60)` with `WHERE title IS NULL` guard (idempotent) +- `updateConversation` accepts `pinnedAt`/`archivedAt` as ISO strings and converts to Date objects + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 2 - Missing Critical] Chat validator schemas not exported from @paperclipai/shared** +- **Found during:** Task 2 (chat-routes.test.ts returning 500 on POST routes) +- **Issue:** `createConversationSchema`, `updateConversationSchema`, and `createMessageSchema` existed in `packages/shared/src/validators/chat.ts` and were re-exported from `validators/index.ts` but were missing from the main `packages/shared/src/index.ts`. Any import of these from `@paperclipai/shared` would silently fail at runtime. +- **Fix:** Added explicit named exports for all three schemas and their types to `packages/shared/src/index.ts` +- **Files modified:** `packages/shared/src/index.ts` +- **Verification:** Tests pass; no TypeScript errors in shared package +- **Committed in:** `563442e5` (Task 2 commit) + +--- + +**Total deviations:** 1 auto-fixed (1 missing critical export) +**Impact on plan:** Critical fix — without this, all POST/PATCH chat routes would throw runtime errors in production. No scope creep. + +## Issues Encountered + +None beyond the auto-fixed deviation above. + +## User Setup Required + +None — no external service configuration required. + +## Next Phase Readiness + +- Chat REST API fully operational; UI in Plan 04 can consume these endpoints +- Conversation and message CRUD all working with proper auth gates +- Pagination pattern established for Plan 05 (infinite scroll sidebar) +- No blockers + +--- +*Phase: 21-chat-foundation* +*Completed: 2026-04-01*