feat: clear chat history manually, auto-expire old history after 90 days
Manual: DELETE /api/v1/ai/chat-history (scoped by recipeId or scope=general, matching GET's scoping) plus a trash-icon button + confirm dialog in both chat panels' headers. Automatic: new internal cron endpoint (chat-cleanup), same shared-secret pattern as the existing leftover-reminders/weekly-digest crons, deletes any chat_messages older than 90 days. Wired into cron/crontab (daily, 03:00 UTC) and the Dockerfile's cron stage. Verified locally: cleared a real conversation through the actual UI and confirmed it didn't come back on reopen (not just cleared client-side); inserted a 100-day-old and a 5-day-old message directly, called the cron endpoint with the real shared-secret check, confirmed only the old one was deleted and the recent one survived; confirmed the endpoint 401s with no/wrong secret.
This commit is contained in:
@@ -51,3 +51,33 @@ export async function GET(req: NextRequest) {
|
||||
})),
|
||||
});
|
||||
}
|
||||
|
||||
const DeleteSchema = z.object({
|
||||
recipeId: z.string().uuid().optional(),
|
||||
scope: z.enum(["general"]).optional(),
|
||||
});
|
||||
|
||||
// No `q` here on purpose — clearing is "this whole conversation" (or
|
||||
// everything), not "every message matching a search term".
|
||||
export async function DELETE(req: NextRequest) {
|
||||
const { session, response } = await requireSession();
|
||||
if (response) return response;
|
||||
|
||||
const { searchParams } = new URL(req.url);
|
||||
const parsed = DeleteSchema.safeParse({
|
||||
recipeId: searchParams.get("recipeId") ?? undefined,
|
||||
scope: searchParams.get("scope") ?? undefined,
|
||||
});
|
||||
if (!parsed.success) {
|
||||
return NextResponse.json({ error: "Validation error" }, { status: 400 });
|
||||
}
|
||||
const { recipeId, scope } = parsed.data;
|
||||
|
||||
const conditions = [eq(chatMessages.userId, session!.user.id)];
|
||||
if (recipeId) conditions.push(eq(chatMessages.recipeId, recipeId));
|
||||
else if (scope === "general") conditions.push(isNull(chatMessages.recipeId));
|
||||
|
||||
await db.delete(chatMessages).where(and(...conditions));
|
||||
|
||||
return NextResponse.json({ ok: true });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user