From b53cb1b7d138c2f3822133173b1b46b97a8ed047 Mon Sep 17 00:00:00 2001 From: Marko Djordjevic Date: Fri, 13 Feb 2026 00:12:53 +0100 Subject: [PATCH] feat: add charts API endpoints (GET list, DELETE with cascade) --- .../changes/multi-chart-management/tasks.md | 4 +-- src/app/api/charts/[id]/route.ts | 28 +++++++++++++++++++ src/app/api/charts/route.ts | 9 ++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 src/app/api/charts/[id]/route.ts create mode 100644 src/app/api/charts/route.ts diff --git a/openspec/changes/multi-chart-management/tasks.md b/openspec/changes/multi-chart-management/tasks.md index 0ff2033..767daf6 100644 --- a/openspec/changes/multi-chart-management/tasks.md +++ b/openspec/changes/multi-chart-management/tasks.md @@ -9,8 +9,8 @@ ## 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 +- [x] 2.1 Create `GET /api/charts` endpoint — returns all charts ordered by `created_at` desc +- [x] 2.2 Create `DELETE /api/charts/[id]` endpoint — deletes chart + cascading candles and annotations in a transaction ## 3. Upload Endpoint Changes diff --git a/src/app/api/charts/[id]/route.ts b/src/app/api/charts/[id]/route.ts new file mode 100644 index 0000000..923fbbf --- /dev/null +++ b/src/app/api/charts/[id]/route.ts @@ -0,0 +1,28 @@ +import { NextRequest, NextResponse } from 'next/server'; +import { db } from '@/lib/db'; +import { charts, candles, annotations } from '@/lib/db/schema'; +import { eq } from 'drizzle-orm'; + +export async function DELETE( + _request: NextRequest, + { params }: { params: Promise<{ id: string }> } +) { + const { id } = await params; + const chartId = parseInt(id, 10); + + if (isNaN(chartId)) { + return NextResponse.json({ error: 'Invalid chart ID' }, { status: 400 }); + } + + const existing = await db.select().from(charts).where(eq(charts.id, chartId)).limit(1); + if (existing.length === 0) { + return NextResponse.json({ error: 'Chart not found' }, { status: 404 }); + } + + // Delete in order: annotations, candles, then chart (application-level cascade) + await db.delete(annotations).where(eq(annotations.chart_id, chartId)); + await db.delete(candles).where(eq(candles.chart_id, chartId)); + await db.delete(charts).where(eq(charts.id, chartId)); + + return NextResponse.json({ success: true }); +} diff --git a/src/app/api/charts/route.ts b/src/app/api/charts/route.ts new file mode 100644 index 0000000..50b1990 --- /dev/null +++ b/src/app/api/charts/route.ts @@ -0,0 +1,9 @@ +import { NextResponse } from 'next/server'; +import { db } from '@/lib/db'; +import { charts } from '@/lib/db/schema'; +import { desc } from 'drizzle-orm'; + +export async function GET() { + const allCharts = await db.select().from(charts).orderBy(desc(charts.created_at)); + return NextResponse.json(allCharts); +}