← 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 });
}