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

+29
View File
@@ -91,3 +91,32 @@ export const HealthStatus = z.object({
time: Timestamp,
});
export type HealthStatus = z.infer<typeof HealthStatus>;
/** 日期(无时区),如 air_date:YYYY-MM-DD */
export const DateOnly = z.iso.date();
export type DateOnly = z.infer<typeof DateOnly>;
/** JSONB 对象列(证据、规则参数、原文快照等)的 API 表示 */
export const JsonObject = z.record(z.string(), z.unknown());
export type JsonObject = z.infer<typeof JsonObject>;
/** 字节数、计数等非负整数(DB 为 bigint,客户端按 number 解析,上限 2^53) */
export const NonNegInt = z.number().int().nonnegative();
/** 操作者类型:与 DB 中 actor_type 列一致 */
export const ActorType = z.enum(["user", "agent", "system", "api_key"]);
export type ActorType = z.infer<typeof ActorType>;
/** 实体行的公共字段 */
export const EntityBase = z.object({
id: Id,
createdAt: Timestamp,
updatedAt: Timestamp,
});
/** 所有实体 Create 输入都要剔除的服务端字段 */
export const SERVER_MANAGED = { id: true, createdAt: true, updatedAt: true } as const;
/** 路径参数 `{id}` */
export const IdParam = z.object({ id: Id });
export type IdParam = z.infer<typeof IdParam>;