// Triplet 統計 action — 知識圖譜規模統計 // 零 SQL / 零 D1:取全部 triplet record(走基本盤 API),在記憶體 reduce 出統計。 // GET /triplets/stats import type { KbdbClient } from '../lib/kbdb-client'; import { queryTriplets } from './triplet-crud'; export interface TripletStats { total: number; // 保留 by_owner_id(原 by_user_id 改名,對齊基本盤 owner_id 欄位)。 // 注:基本盤 record 不回傳 owner_id / 時間戳,故 by_owner_id/recent 在純插件層無法填, // 待 [→arcrun] base 於 record 回應帶上 owner_id + created_at 後補。 by_owner_id: Record; recent: { today: number; this_week: number }; top_subjects: { subject: string; count: number }[]; top_predicates: { predicate: string; count: number }[]; } export async function getTripletStats(client: KbdbClient): Promise { const { triplets } = await queryTriplets(client, { limit: 2000 }); const subjectCounts = new Map(); const predicateCounts = new Map(); const ownerCounts: Record = {}; for (const t of triplets) { subjectCounts.set(t.subject, (subjectCounts.get(t.subject) ?? 0) + 1); predicateCounts.set(t.predicate, (predicateCounts.get(t.predicate) ?? 0) + 1); } const top = (m: Map) => [...m.entries()].sort((a, b) => b[1] - a[1]).slice(0, 10); return { total: triplets.length, by_owner_id: ownerCounts, // base record 暫無 owner_id,待上游補 recent: { today: 0, this_week: 0 }, // base record 暫無 created_at,待上游補 top_subjects: top(subjectCounts).map(([subject, count]) => ({ subject, count })), top_predicates: top(predicateCounts).map(([predicate, count]) => ({ predicate, count })), }; }