/** * activity-registry 的 sys schema 表(编码规范 §7 / ADR-002 / OS 11.3)。 * **资产与包分离,各自单写者** —— 两张表、两条版本序列。 */ import { sql } from 'drizzle-orm'; import { boolean, index, integer, jsonb, primaryKey, text, timestamp, uniqueIndex } from 'drizzle-orm/pg-core'; import { sys } from '@shared/db.ts'; export const activityPackageTable = sys.table( 'activity_package', { activityId: text('activity_id').notNull(), version: text('version').notNull(), name: text('name').notNull(), category: text('category').notNull(), manifest: jsonb('manifest').notNull(), /** .JS 产物 —— 装载时由 registry 交给范式运行器(ADR-004) */ artifact: text('artifact').notNull(), state: text('state').notNull().default('active'), enabled: boolean('enabled').notNull().default(true), installedAt: timestamp('installed_at', { withTimezone: true }).notNull().defaultNow(), }, (t) => [ primaryKey({ columns: [t.activityId, t.version] }), index('activity_package_category_idx').on(t.category), ], ); export const activityAssetTable = sys.table( 'activity_asset', { activityId: text('activity_id').notNull(), kind: text('kind').notNull(), version: integer('version').notNull(), body: text('body').notNull(), effective: boolean('effective').notNull().default(false), source: text('source').notNull(), createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), }, (t) => [ primaryKey({ columns: [t.activityId, t.kind, t.version] }), // 每个「活动 × 资产类」至多一个生效版 —— 装载时不会取到两份 uniqueIndex('activity_asset_effective_key') .on(t.activityId, t.kind) .where(sql`${t.effective}`), ], ); /** 候选增量:候选 → 回放中 → 已放行 / 已否决(OS 11.3) */ export const assetIncrementTable = sys.table( 'asset_increment', { id: text('id').primaryKey(), activityId: text('activity_id').notNull(), kind: text('kind').notNull(), diff: text('diff').notNull(), /** 证据链 —— 指回任务记忆的具体片段 */ evidenceEntryIds: jsonb('evidence_entry_ids').notNull().default([]), state: text('state').notNull().default('candidate'), replayReport: jsonb('replay_report'), releasedBy: text('released_by'), createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), }, (t) => [index('asset_increment_activity_idx').on(t.activityId, t.state)], );