nexus/.planning/phases/25-file-system/25-05-SUMMARY.md

4.7 KiB

phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established requirements-completed duration completed
25-file-system 05 api, ui
chat-files
file-promotion
drizzle
express
react
phase provides
25-01 chatFileService and chatFileRoutes with existing DB schema (projectId nullable FK on chatFiles)
PATCH /files/:fileId/promote endpoint that sets projectId on a chat file
promoteToProject service method on chatFileService
ChatFileCard promote button with FolderUp icon and onPromoted callback
promoteFile API client method in chatApi
ui-chat
chat-file-display
project-integration
added patterns
Route ordering: specific sub-routes (/files/:fileId/promote) registered before catch-all (/files/:fileId) in Express
Optional promote callback pattern: file.projectId === null && projectId && onPromoted guards UI button render
created modified
server/src/services/chat-files.ts
server/src/routes/chat-files.ts
ui/src/api/chat.ts
ui/src/components/ChatFileCard.tsx
.planning/REQUIREMENTS.md
PATCH /files/:fileId/promote registered before PATCH /files/:fileId in Express router to prevent route shadowing
promoteToProject returns null (not throws) when row missing — route handles 404 explicitly
Promote button gated on file.projectId === null AND projectId AND onPromoted — all three required for intent
Sub-route ordering: register /files/:fileId/promote before /files/:fileId
Optional promote UX: ChatFileCard accepts optional projectId + onPromoted; renders button only when both provided and file not yet promoted
FILE-12
8min 2026-04-01

Phase 25 Plan 05: File Scope Promotion Summary

PATCH /files/:fileId/promote endpoint and ChatFileCard promote button with FolderUp icon wired to chatApi.promoteFile

Performance

  • Duration: ~8 min
  • Started: 2026-04-01T23:56:00Z
  • Completed: 2026-04-01T23:59:00Z
  • Tasks: 2
  • Files modified: 4 + REQUIREMENTS.md

Accomplishments

  • Added promoteToProject(fileId, projectId) method to chatFileService — updates projectId column via Drizzle ORM
  • Added PATCH /files/:fileId/promote Express route before generic PATCH /files/:fileId to prevent shadowing
  • Added promoteFile(fileId, projectId) to chatApi in ui/src/api/chat.ts with ChatFile return type
  • Added promote button to ChatFileCard with FolderUp icon, optional projectId and onPromoted props, and loading state
  • Marked FILE-12 Complete in REQUIREMENTS.md (checkbox + traceability table)

Task Commits

Each task was committed atomically:

  1. Task 1: Add promoteToProject service method and API endpoint - c435655f (feat)
  2. Task 2: Add promote button to ChatFileCard and API client method - 4c5deb4c (feat)
  3. REQUIREMENTS.md update - 9a911040 (feat, in main repo)

Files Created/Modified

  • server/src/services/chat-files.ts - Added promoteToProject(fileId, projectId) method
  • server/src/routes/chat-files.ts - Added PATCH /files/:fileId/promote route before generic PATCH route
  • ui/src/api/chat.ts - Added ChatFile import and promoteFile(fileId, projectId) method to chatApi
  • ui/src/components/ChatFileCard.tsx - Added projectId?, onPromoted? props, promoting state, FolderUp button
  • .planning/REQUIREMENTS.md - FILE-12 marked [x] and Complete in traceability table

Decisions Made

  • Registered /files/:fileId/promote BEFORE /files/:fileId in Express router to prevent the generic catch-all from capturing promote requests
  • promoteToProject returns null (not throws) when no rows returned, so the route can send an explicit 404
  • Promote button only renders when all three conditions are true: file.projectId === null, projectId prop provided, onPromoted prop provided — clean opt-in pattern for callers

Deviations from Plan

None - plan executed exactly as written.

Issues Encountered

None.

Known Stubs

None — promoteFile calls the real API endpoint. ChatFileCard renders the button conditionally based on real file.projectId field.

User Setup Required

None - no external service configuration required.

Next Phase Readiness

  • FILE-12 is complete: chat-scoped files can be promoted to project scope via UI
  • Callers of ChatFileCard (e.g. ChatFilePreview, ChatMessage) can now pass projectId and onPromoted to enable the promote affordance contextually
  • No blockers for subsequent plans

Self-Check: PASSED

All files verified present. Commits c435655f and 4c5deb4c confirmed in git log.


Phase: 25-file-system Completed: 2026-04-01