| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import { and, desc, eq } from "drizzle-orm"; |
| import { |
| db, |
| capabilityDataFoundation, |
| type CapabilityDataFoundationRow, |
| type InsertCapabilityDataFoundationRow, |
| } from "@workspace/db"; |
| import { newId } from "../../ids.js"; |
|
|
| export interface DataFoundationRow { |
| id: string; |
| capabilityId: string; |
| kind: string; |
| payload: Record<string, unknown>; |
| sourceRunId: string | null; |
| createdAt: Date; |
| } |
|
|
| export interface WriteRowInput { |
| capabilityId: string; |
| kind: string; |
| payload: Record<string, unknown>; |
| sourceRunId?: string | null; |
| } |
|
|
| export interface ReadRowsQuery { |
| capabilityId: string; |
| kind?: string; |
| |
| limit?: number; |
| |
| |
| |
| |
| |
| excludeSelf?: boolean; |
| } |
|
|
| function rowToOutput(r: CapabilityDataFoundationRow): DataFoundationRow { |
| return { |
| id: r.id, |
| capabilityId: r.capabilityId, |
| kind: r.kind, |
| payload: (r.payload ?? {}) as Record<string, unknown>, |
| sourceRunId: r.sourceRunId, |
| createdAt: r.createdAt, |
| }; |
| } |
|
|
| export async function writeRow(input: WriteRowInput): Promise<{ id: string }> { |
| if (!input.capabilityId) { |
| throw new Error("data-foundation/writeRow: capabilityId required"); |
| } |
| if (!input.kind) { |
| throw new Error("data-foundation/writeRow: kind required"); |
| } |
| const id = newId("cdf"); |
| const row: InsertCapabilityDataFoundationRow = { |
| id, |
| capabilityId: input.capabilityId, |
| kind: input.kind, |
| payload: input.payload, |
| sourceRunId: input.sourceRunId ?? null, |
| }; |
| await db.insert(capabilityDataFoundation).values(row); |
| return { id }; |
| } |
|
|
| export async function readRows( |
| query: ReadRowsQuery, |
| ): Promise<DataFoundationRow[]> { |
| const limit = Math.min(Math.max(query.limit ?? 50, 1), 500); |
| const conds = []; |
| if (query.excludeSelf) { |
| |
| |
| |
| |
| throw new Error( |
| "data-foundation/readRows: excludeSelf is reserved for B7 inner-loop search " + |
| "and is not yet implemented; pass capabilityId only to read own rows.", |
| ); |
| } |
| if (query.kind) { |
| conds.push( |
| and( |
| eq(capabilityDataFoundation.capabilityId, query.capabilityId), |
| eq(capabilityDataFoundation.kind, query.kind), |
| ), |
| ); |
| } else { |
| conds.push(eq(capabilityDataFoundation.capabilityId, query.capabilityId)); |
| } |
| const rows = await db |
| .select() |
| .from(capabilityDataFoundation) |
| .where(conds[0]) |
| .orderBy(desc(capabilityDataFoundation.createdAt)) |
| .limit(limit); |
| return rows.map(rowToOutput); |
| } |
|
|