feat: add charts table schema and migration with data backfill

- Add charts table with id, name (unique), created_at
- Add chart_id FK to candles table with composite unique on (chart_id, time)
- Add chart_id FK to annotations table
- Custom migration handles existing data: creates 'Imported Data' chart and backfills chart_id
- Recreates tables for NOT NULL constraint (SQLite limitation)
This commit is contained in:
Marko Djordjevic 2026-02-13 00:12:21 +01:00
parent 178834f3b2
commit 92d3339a48
14 changed files with 913 additions and 3 deletions

View file

@ -0,0 +1,56 @@
## 1. Database Schema & Migration
- [x] 1.1 Add `charts` table to Drizzle schema (`src/lib/db/schema.ts`) with columns: `id`, `name` (unique), `created_at`
- [x] 1.2 Add `chart_id` foreign key column to `candles` table in schema, replace `time` unique constraint with composite unique on `(chart_id, time)`
- [x] 1.3 Add `chart_id` foreign key column to `annotations` table in schema
- [x] 1.4 Generate Drizzle migration files (`npx drizzle-kit generate`)
- [x] 1.5 Write data migration logic: if existing candles exist, create a default "Imported Data" chart and assign all existing candles and annotations to it
- [x] 1.6 Test migration against existing database with data
## 2. Charts API Endpoints
- [ ] 2.1 Create `GET /api/charts` endpoint — returns all charts ordered by `created_at` desc
- [ ] 2.2 Create `DELETE /api/charts/[id]` endpoint — deletes chart + cascading candles and annotations in a transaction
## 3. Upload Endpoint Changes
- [ ] 3.1 Modify `POST /api/upload` to create a new chart named from the uploaded filename (strip `.csv` extension)
- [ ] 3.2 Add duplicate name handling — append numeric suffix if chart name already exists
- [ ] 3.3 Insert candles with the new chart's `chart_id` instead of deleting all existing candles
- [ ] 3.4 Return chart `id` and `name` in the upload response JSON
## 4. Candles & Annotations API Scoping
- [ ] 4.1 Modify `GET /api/candles` to accept `?chartId=` query param and filter by chart_id (fall back to most recent chart if omitted)
- [ ] 4.2 Modify `GET /api/annotations` to accept `?chartId=` query param and filter by chart_id (fall back to most recent chart if omitted)
- [ ] 4.3 Modify `POST /api/annotations` to require `chart_id` in request body and store it
- [ ] 4.4 Modify `GET /api/export` to accept `?chartId=` query param and scope exported annotations to that chart
## 5. Chart Selector UI Component
- [ ] 5.1 Create a `ChartSelector` component with dropdown listing all charts (name + created date), positioned in the sidebar between header and file upload
- [ ] 5.2 Add delete button per chart in the dropdown with confirmation dialog
- [ ] 5.3 Show "No charts — upload a CSV to get started" placeholder when no charts exist
## 6. Frontend State & Data Flow
- [ ] 6.1 Add `activeChartId` and `charts` state to `page.tsx`
- [ ] 6.2 Fetch charts list on mount via `GET /api/charts`, auto-select the most recent chart
- [ ] 6.3 Pass `activeChartId` to `CandleChart` component — update it to fetch candles/annotations with `?chartId=` param
- [ ] 6.4 Update `handleUploadSuccess` to receive the new chart from the upload response, add it to `charts` state, and set it as `activeChartId`
- [ ] 6.5 Update annotation create/delete flows to include `chart_id` in requests
- [ ] 6.6 When `activeChartId` changes, refetch candles and annotations for the new chart
- [ ] 6.7 Update export handler to include `?chartId=` in the export URL
## 7. UI Polish
- [ ] 7.1 Restyle "Manage Annotation Types" link — replace `text-blue-600 hover:text-blue-800 underline` with `text-muted-foreground hover:text-foreground` and remove underline
- [ ] 7.2 Verify chart selector and all components render correctly in both light and dark themes
## 8. Testing & Verification
- [ ] 8.1 Test full workflow: upload CSV -> chart created -> switch charts -> annotations scoped correctly
- [ ] 8.2 Test migration: existing database with candles/annotations migrates to default chart
- [ ] 8.3 Test chart deletion: candles and annotations cascade-deleted
- [ ] 8.4 Test edge cases: upload duplicate filename, delete last chart, upload with no charts existing
- [ ] 8.5 Run build (`npm run build`) and fix any type errors