feat: upload creates new chart from filename with duplicate handling
- POST /api/upload now creates a chart named from the CSV filename - Duplicate names get numeric suffix (e.g., btc-daily-2) - Candles inserted with chart_id instead of replacing all data - Response includes chart id and name
This commit is contained in:
parent
b53cb1b7d1
commit
98e91b047a
2 changed files with 41 additions and 10 deletions
|
|
@ -14,10 +14,10 @@
|
|||
|
||||
## 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
|
||||
- [x] 3.1 Modify `POST /api/upload` to create a new chart named from the uploaded filename (strip `.csv` extension)
|
||||
- [x] 3.2 Add duplicate name handling — append numeric suffix if chart name already exists
|
||||
- [x] 3.3 Insert candles with the new chart's `chart_id` instead of deleting all existing candles
|
||||
- [x] 3.4 Return chart `id` and `name` in the upload response JSON
|
||||
|
||||
## 4. Candles & Annotations API Scoping
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,28 @@
|
|||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import Papa from 'papaparse';
|
||||
import { db } from '@/lib/db';
|
||||
import { candles } from '@/lib/db/schema';
|
||||
import { sql } from 'drizzle-orm';
|
||||
import { candles, charts } from '@/lib/db/schema';
|
||||
import { eq, like } from 'drizzle-orm';
|
||||
|
||||
async function getUniqueChartName(baseName: string): Promise<string> {
|
||||
// Check if the base name is already taken
|
||||
const existing = await db.select().from(charts).where(eq(charts.name, baseName)).limit(1);
|
||||
if (existing.length === 0) return baseName;
|
||||
|
||||
// Find existing charts with this base name pattern (e.g., "btc-daily-2", "btc-daily-3")
|
||||
const pattern = `${baseName}-%`;
|
||||
const suffixed = await db.select({ name: charts.name }).from(charts).where(like(charts.name, pattern));
|
||||
|
||||
let maxSuffix = 1;
|
||||
for (const row of suffixed) {
|
||||
const match = row.name.match(/-(\d+)$/);
|
||||
if (match) {
|
||||
maxSuffix = Math.max(maxSuffix, parseInt(match[1], 10));
|
||||
}
|
||||
}
|
||||
|
||||
return `${baseName}-${maxSuffix + 1}`;
|
||||
}
|
||||
|
||||
export async function POST(request: NextRequest): Promise<NextResponse> {
|
||||
try {
|
||||
|
|
@ -18,6 +38,9 @@ export async function POST(request: NextRequest): Promise<NextResponse> {
|
|||
|
||||
const text = await file.text();
|
||||
|
||||
// Derive chart name from filename (strip .csv extension)
|
||||
const baseName = file.name.replace(/\.csv$/i, '');
|
||||
|
||||
return new Promise<NextResponse>((resolve) => {
|
||||
Papa.parse(text, {
|
||||
header: true,
|
||||
|
|
@ -56,6 +79,15 @@ export async function POST(request: NextRequest): Promise<NextResponse> {
|
|||
return;
|
||||
}
|
||||
|
||||
// Get unique chart name (handle duplicates)
|
||||
const chartName = await getUniqueChartName(baseName);
|
||||
|
||||
// Create the chart
|
||||
const [newChart] = await db.insert(charts).values({
|
||||
name: chartName,
|
||||
created_at: Math.floor(Date.now() / 1000),
|
||||
}).returning();
|
||||
|
||||
// Parse and prepare candle data
|
||||
const candleData = rows.map((row) => {
|
||||
let timestamp: number;
|
||||
|
|
@ -75,6 +107,7 @@ export async function POST(request: NextRequest): Promise<NextResponse> {
|
|||
}
|
||||
|
||||
return {
|
||||
chart_id: newChart.id,
|
||||
time: timestamp,
|
||||
open: Number(row.open),
|
||||
high: Number(row.high),
|
||||
|
|
@ -83,10 +116,7 @@ export async function POST(request: NextRequest): Promise<NextResponse> {
|
|||
};
|
||||
});
|
||||
|
||||
// Delete all old candles before inserting new ones
|
||||
await db.delete(candles);
|
||||
|
||||
// Insert new candles
|
||||
// Insert candles for this chart
|
||||
const count = candleData.length;
|
||||
if (count > 0) {
|
||||
await db.insert(candles).values(candleData);
|
||||
|
|
@ -96,6 +126,7 @@ export async function POST(request: NextRequest): Promise<NextResponse> {
|
|||
NextResponse.json({
|
||||
success: true,
|
||||
count,
|
||||
chart: { id: newChart.id, name: newChart.name },
|
||||
})
|
||||
);
|
||||
} catch (error: any) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue