← back to Trademarks Copyright
src/app/api/swot/route.ts
65 lines
import { NextRequest, NextResponse } from "next/server";
import { query } from "@/lib/db";
import { runSwot, type Quadrant } from "@/lib/swot";
import { qwenIsUp } from "@/lib/qwen";
const QUADS: Quadrant[] = ["strength", "weakness", "opportunity", "threat"];
export async function POST(req: NextRequest) {
const body = await req.json().catch(() => ({}));
if (!body || typeof body !== "object" || Array.isArray(body)) {
return NextResponse.json({ error: "json object body required" }, { status: 400 });
}
const itemId = Number(body.itemId);
const force = !!body.force;
if (!Number.isFinite(itemId)) return NextResponse.json({ error: "itemId required" }, { status: 400 });
const { rows } = await query<{
id: number; name: string; kind: "trademark" | "copyright";
original_owner: string | null; nice_class: string | null;
goods_services: string | null; expired_date: string;
status: "abandoned" | "cancelled" | "expired" | "public_domain";
notes: string | null;
}>(
`SELECT id, name, kind, original_owner, nice_class, goods_services, expired_date, status, notes
FROM items WHERE id = $1`,
[itemId]
);
if (!rows.length) return NextResponse.json({ error: "item not found" }, { status: 404 });
const item = rows[0];
if (!force) {
const { rows: cached } = await query<{ quadrant: Quadrant; content: string; generated_at: string }>(
`SELECT quadrant, content, generated_at FROM swot_cache WHERE item_id = $1`,
[itemId]
);
if (cached.length === 4) {
return NextResponse.json({ cached: true, quadrants: cached });
}
} else {
await query(`DELETE FROM swot_cache WHERE item_id = $1`, [itemId]);
}
if (!(await qwenIsUp())) {
return NextResponse.json(
{ error: "Ollama not reachable at :11434. Start with `ollama serve`." },
{ status: 500 }
);
}
const results = await Promise.all(
QUADS.map(async (quadrant) => {
const content = await runSwot(item, quadrant);
await query(
`INSERT INTO swot_cache (item_id, quadrant, content)
VALUES ($1, $2, $3)
ON CONFLICT (item_id, quadrant) DO UPDATE SET content = EXCLUDED.content, generated_at = NOW()`,
[itemId, quadrant, content]
);
return { quadrant, content, generated_at: new Date().toISOString() };
})
);
return NextResponse.json({ cached: false, quadrants: results });
}