61 lines
1.8 KiB
TypeScript
61 lines
1.8 KiB
TypeScript
|
|
/**
|
||
|
|
* /api/relations — read typed relations for an entity.
|
||
|
|
*
|
||
|
|
* GET /api/relations?class=person&id=j-edgar-hoover
|
||
|
|
* → Returns relations where this entity is source OR target,
|
||
|
|
* grouped by relation_type and direction.
|
||
|
|
*/
|
||
|
|
import { NextRequest } from "next/server";
|
||
|
|
import { pgQuery } from "@/lib/retrieval/db";
|
||
|
|
|
||
|
|
export const runtime = "nodejs";
|
||
|
|
export const dynamic = "force-dynamic";
|
||
|
|
|
||
|
|
function json(data: unknown, status = 200) {
|
||
|
|
return new Response(JSON.stringify(data), {
|
||
|
|
status,
|
||
|
|
headers: { "content-type": "application/json" },
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
interface Relation {
|
||
|
|
source_class: string;
|
||
|
|
source_id: string;
|
||
|
|
relation_type: string;
|
||
|
|
target_class: string;
|
||
|
|
target_id: string;
|
||
|
|
evidence_ref: string | null;
|
||
|
|
confidence: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function GET(req: NextRequest) {
|
||
|
|
const u = new URL(req.url);
|
||
|
|
const cls = u.searchParams.get("class") ?? "";
|
||
|
|
const id = u.searchParams.get("id") ?? "";
|
||
|
|
if (!cls || !id) return json({ error: "class and id required" }, 400);
|
||
|
|
|
||
|
|
try {
|
||
|
|
const outgoing = await pgQuery<Relation>(
|
||
|
|
`SELECT source_class, source_id, relation_type, target_class, target_id,
|
||
|
|
evidence_ref, confidence
|
||
|
|
FROM public.relations
|
||
|
|
WHERE source_class = $1 AND source_id = $2
|
||
|
|
ORDER BY confidence DESC, relation_type, target_class, target_id
|
||
|
|
LIMIT 200`,
|
||
|
|
[cls, id],
|
||
|
|
);
|
||
|
|
const incoming = await pgQuery<Relation>(
|
||
|
|
`SELECT source_class, source_id, relation_type, target_class, target_id,
|
||
|
|
evidence_ref, confidence
|
||
|
|
FROM public.relations
|
||
|
|
WHERE target_class = $1 AND target_id = $2
|
||
|
|
ORDER BY confidence DESC, relation_type, source_class, source_id
|
||
|
|
LIMIT 200`,
|
||
|
|
[cls, id],
|
||
|
|
);
|
||
|
|
return json({ outgoing, incoming });
|
||
|
|
} catch (e) {
|
||
|
|
return json({ error: "db_unavailable", message: (e as Error).message }, 503);
|
||
|
|
}
|
||
|
|
}
|