feat(db,contracts): full v0.1 data model migrations and shared zod contracts (W1-1)

- migrations 0002-0012 split by domain (foundation/instances/content/identity/
  sources/assets/policy/execution/agent/ops/organization): 41 tables, uuid pk,
  created_at/updated_at + touch trigger, text+CHECK status sets, pgcrypto/pg_trgm
- key constraints: source_release(site_id, site_release_id), observation(feed_id, guid),
  external_identity accepted partial unique, download_task(instance_id, torrent_hash),
  one active acquisition_plan per slot, one active path_binding per entity/season,
  asset_location root+path uniqueness, organization_record change_seq/change_xid cursor
- secret table (ciphertext/nonce/kdf) + secret_ref columns; outbox dispatch fields (ADR-002)
- src/types.ts generated from the migrated schema (scripts/gen-types.ts), drift-checked in tests;
  int8 -> number, date -> string parsers; migrator accepts migrationTableSchema
- contracts: Row/Create/Update schemas per domain, public organization-record API
  (changeSeq cursor), GlobalSettings, CapabilityDescriptor + 14 capability IO schemas,
  typed SSE events, Api endpoint table
- tests: migration up/down round trip on real PG in an isolated schema, constraint checks,
  contracts<->db column/enum sync, positive/negative parse for every exported schema

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
rootandClaude Fable 5.1 committed 2026-09-27 18:11:37 +08:00
1 parent 7ba712ea55
commit cc8b3a7df4
42 files changed
+7026 -25

No files matched your search

+9
View File
@@ -2,6 +2,15 @@ import { Kysely, PostgresDialect } from "kysely";
import pg from "pg";
import type { DB } from "./types";
// int8 → number(大小/序号都在 2^53 内;超出即报错而不是静默丢精度)
pg.types.setTypeParser(pg.types.builtins.INT8, (v: string) => {
const n = Number(v);
if (!Number.isSafeInteger(n)) throw new RangeError(`int8 超出安全整数范围: ${v}`);
return n;
});
// date → 原样 'YYYY-MM-DD' 字符串,避免按本地时区转成 Date 造成日期漂移
pg.types.setTypeParser(pg.types.builtins.DATE, (v: string) => v);
export interface CreateDbOptions {
/** 默认读 process.env.DATABASE_URL */
connectionString?: string;