MEGAINFRA-WEBAPP/src/app/api/chat/threads/route.ts
DEls 7c5df11b84 feat(ask): per-user persistent threads
Adds the "Who's using Ask?" picker (GET /api/ask/users), actor
resolution via x-ask-user (src/lib/agent/context.ts), and thread
persistence (src/lib/chat/threads.ts, /api/chat/threads routes).
/api/chat now accepts { threadId?, message, display?, images? } and
persists each turn as its own append-only ask_messages row; the old
{ history } body still works for one release. chat-view.tsx gained the
picker, a thread sidebar (new/select/rename/archive), and ?thread=<id>
in the URL.

Live browser check skipped: ask_threads/ask_messages/ask_log don't
exist yet in the target PocketBase (Task 1's schema is dry-run only,
pending the user's --apply). Covered by mocked unit tests instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 18:05:01 +02:00

43 lines
1.3 KiB
TypeScript

/**
* GET /api/chat/threads — the actor's threads, newest first.
* POST /api/chat/threads — creates an empty thread owned by the actor.
*/
import { pbAdmin } from "@/lib/pb";
import { resolveActor } from "@/lib/agent/context";
export const dynamic = "force-dynamic";
export async function GET(request: Request) {
const actor = await resolveActor(request);
if (actor instanceof Response) return actor;
const pb = await pbAdmin();
const rows = await pb.collection("ask_threads").getFullList({
filter: pb.filter("owner = {:owner}", { owner: actor.id }),
sort: "-last_message_at,-created",
});
return Response.json({ threads: rows });
}
export async function POST(request: Request) {
const actor = await resolveActor(request);
if (actor instanceof Response) return actor;
let body: Record<string, unknown> = {};
try {
body = await request.json();
} catch {
// An empty body is fine — "New thread" sends none.
}
const title = typeof body.title === "string" && body.title.trim() ? body.title.trim() : "New thread";
const pb = await pbAdmin();
const created = await pb.collection("ask_threads").create({
title,
owner: actor.id,
archived: false,
});
return Response.json({ id: created.id, title: created.title });
}