- Create 25-00-SUMMARY.md with full plan documentation - Update STATE.md: advance to plan 2/4, record metrics and decisions - Update ROADMAP.md: phase 25 in progress (1/4 summaries) - Update REQUIREMENTS.md: mark FILE-01, FILE-02, FILE-03 complete
122 lines
5.4 KiB
Markdown
122 lines
5.4 KiB
Markdown
---
|
|
phase: 25-file-system
|
|
plan: "00"
|
|
subsystem: db-schema
|
|
tags: [database, schema, migrations, shared-types, validators, test-stubs]
|
|
dependency_graph:
|
|
requires: []
|
|
provides:
|
|
- chatFiles Drizzle schema (packages/db/src/schema/chat_files.ts)
|
|
- chatFileReferences Drizzle schema (packages/db/src/schema/chat_file_references.ts)
|
|
- SQL migrations 0053 and 0054
|
|
- ChatFile, ChatFileReference types from @paperclipai/shared
|
|
- uploadChatFileSchema, createFileReferenceSchema validators
|
|
affects:
|
|
- packages/db/src/schema/index.ts
|
|
- packages/shared/src/types/chat.ts
|
|
- packages/shared/src/validators/chat.ts
|
|
- packages/shared/src/index.ts
|
|
tech_stack:
|
|
added: []
|
|
patterns:
|
|
- Drizzle pgTable with object-syntax index callback (table) => ({})
|
|
- UUID FK with onDelete: "set null" for nullable cross-table references
|
|
- UUID FK with onDelete: "cascade" for required cross-table references
|
|
- Zod validators with .default() for source enum
|
|
- it.todo() for Wave 0 test scaffolding
|
|
key_files:
|
|
created:
|
|
- packages/db/src/schema/chat_files.ts
|
|
- packages/db/src/schema/chat_file_references.ts
|
|
- packages/db/src/migrations/0053_create_chat_files.sql
|
|
- packages/db/src/migrations/0054_create_chat_file_references.sql
|
|
- server/src/__tests__/chat-file-service.test.ts
|
|
- server/src/__tests__/chat-file-routes.test.ts
|
|
modified:
|
|
- packages/db/src/schema/index.ts
|
|
- packages/db/src/migrations/meta/_journal.json
|
|
- packages/shared/src/types/chat.ts
|
|
- packages/shared/src/validators/chat.ts
|
|
- packages/shared/src/index.ts
|
|
decisions:
|
|
- "Used object-syntax (table) => ({}) for Drizzle index callbacks — matches existing codebase pattern in chat_messages.ts, assets.ts"
|
|
- "chatFiles.conversationId and messageId are nullable FKs with ON DELETE SET NULL — file may exist before/without a conversation or message"
|
|
- "chatFileReferences uses ON DELETE CASCADE for both fileId and conversationId — reference has no meaning without both anchors"
|
|
- "projectId nullable FK on chatFiles with ON DELETE SET NULL — satisfies FILE-04 dual scoping for future project-scoped file listing"
|
|
- "uploadChatFileSchema source defaults to user_upload — agent-generated files pass source explicitly"
|
|
metrics:
|
|
duration_minutes: 6
|
|
completed_date: "2026-04-01"
|
|
tasks_completed: 2
|
|
files_created: 6
|
|
files_modified: 5
|
|
requirements:
|
|
- FILE-01
|
|
- FILE-02
|
|
- FILE-03
|
|
---
|
|
|
|
# Phase 25 Plan 00: File System Foundation Summary
|
|
|
|
**One-liner:** Drizzle ORM schema for `chat_files` and `chat_file_references` tables with SQL migrations, shared TypeScript types (ChatFile, ChatFileReference), Zod validators (uploadChatFileSchema, createFileReferenceSchema), and test stubs — establishing the data layer contract for Phase 25 file upload plans.
|
|
|
|
## What Was Built
|
|
|
|
### Task 1: DB Schema + Migrations (commit 70fa6fe5)
|
|
|
|
Two new Drizzle ORM schema tables:
|
|
|
|
**`chat_files`** — tracks every uploaded or agent-generated file with:
|
|
- Dual scoping: `company_id` (always) + optional `project_id` (FILE-04)
|
|
- Storage integration: `object_key` + `sha256` for dedup detection
|
|
- Lifecycle FKs: `conversation_id` (nullable, SET NULL), `message_id` (nullable, SET NULL)
|
|
- Classification: `source` (user_upload | agent_generated), `category` (image | document | code | other | null)
|
|
- 4 indexes: conversation, message, company+created_at composite, project
|
|
|
|
**`chat_file_references`** — enables cross-conversation file reuse without re-upload:
|
|
- Required FKs: `file_id` (CASCADE), `conversation_id` (CASCADE)
|
|
- Optional `message_id` (SET NULL)
|
|
- 3 indexes: file, conversation, message
|
|
|
|
SQL migrations 0053 and 0054 added with journal entries for idx 53 and 54.
|
|
|
|
### Task 2: Shared Types + Validators + Test Stubs (commit 5cf5e420)
|
|
|
|
**New types** in `packages/shared/src/types/chat.ts`:
|
|
- `ChatFile` — full file record interface with literal union types for source/category
|
|
- `ChatFileReference` — cross-conversation reference interface
|
|
- `ChatFileUploadResponse` — upload endpoint response shape
|
|
- `ChatFileListResponse` — listing endpoint response shape
|
|
- `ChatMessage.files?: ChatFile[]` — optional files array on existing ChatMessage type
|
|
|
|
**New Zod validators** in `packages/shared/src/validators/chat.ts`:
|
|
- `uploadChatFileSchema` — conversationId, messageId, source (default: "user_upload"), projectId
|
|
- `createFileReferenceSchema` — fileId, messageId
|
|
|
|
**Test stubs** created with `it.todo()` entries:
|
|
- `server/src/__tests__/chat-file-service.test.ts` — 5 service test stubs
|
|
- `server/src/__tests__/chat-file-routes.test.ts` — 6 route test stubs
|
|
|
|
## Deviations from Plan
|
|
|
|
None — plan executed exactly as written.
|
|
|
|
## Known Stubs
|
|
|
|
- `chat-file-service.test.ts` and `chat-file-routes.test.ts` are intentional `it.todo()` stubs — Plans 01 and 02 will implement the service and routes that these tests will cover.
|
|
|
|
## Self-Check: PASSED
|
|
|
|
Files verified:
|
|
- packages/db/src/schema/chat_files.ts: FOUND
|
|
- packages/db/src/schema/chat_file_references.ts: FOUND
|
|
- packages/db/src/migrations/0053_create_chat_files.sql: FOUND
|
|
- packages/db/src/migrations/0054_create_chat_file_references.sql: FOUND
|
|
- server/src/__tests__/chat-file-service.test.ts: FOUND
|
|
- server/src/__tests__/chat-file-routes.test.ts: FOUND
|
|
|
|
Commits verified:
|
|
- 70fa6fe5: FOUND (feat(25-00): create chat_files and chat_file_references DB schema + migrations)
|
|
- 5cf5e420: FOUND (feat(25-00): add shared types, validators, and test stubs for file system)
|
|
|
|
TypeScript compilation: PASSED (no errors)
|