import { NextRequest, NextResponse } from 'next/server'; import { setRulesDate } from '@/lib/db'; import { sortableIso } from '@/lib/kept-rules'; type Params = { params: Promise<{ id: string }> }; /** A rules date may run this far ahead of the server's clock — room for a * browser whose clock or time zone is ahead, not for dating accounts later. */ const MAX_FUTURE_MS = 24 * 60 * 60 * 1000; function parseAccountId(raw: string): number | null { const id = parseInt(raw, 10); return Number.isNaN(id) ? null : id; } /** Set an account's rules date by hand. The date decides which of its type's * rule sets it trades on — one dated before a firm's rule change keeps the * old rules — and a date set here is never moved by broker evidence again. * The trade path reads it per tick, so nothing needs re-resolving. */ export async function PUT(req: NextRequest, { params }: Params) { const { id: idStr } = await params; const accountId = parseAccountId(idStr); if (accountId === null) return NextResponse.json({ error: 'Invalid id' }, { status: 400 }); const body = await req.json().catch(() => null) as { rulesDate?: unknown } | null; const raw = body?.rulesDate; const ms = typeof raw === 'string' ? Date.parse(raw) : NaN; if (!Number.isFinite(ms)) { return NextResponse.json({ error: 'rulesDate must be an ISO date' }, { status: 400 }); } if (ms > Date.now() + MAX_FUTURE_MS) { return NextResponse.json({ error: 'A rules date cannot be more than a day ahead' }, { status: 400 }); } // Stored as a plain four-digit-year toISOString(), the one format every // rules-date writer uses — lowerAutoRulesDate compares them as strings, // so nothing before 2000 (or that doesn't print as one) gets in. const rulesDate = sortableIso(ms); if (!rulesDate) { return NextResponse.json({ error: 'A rules date cannot be before 2000' }, { status: 400 }); } if (!setRulesDate(accountId, rulesDate, true)) { return NextResponse.json({ error: 'Unknown account' }, { status: 404 }); } return NextResponse.json({ ok: true, rulesDate }); }