#!/usr/bin/env python
"""Print schema.sql from infrastructure/tables.py (the one source), DataK3's DDL subset: CREATE TABLE IF NOT EXISTS
with the full primary key — plus the capability claim and log tables erp_platform prints for a provider.
tests/test_schema.py fails when src/brick_contracts/schema.sql drifts from it.
python scripts/gen_schema.py > src/brick_contracts/schema.sql
"""
import pathlib
import sys
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1] / "src"))
from sqlalchemy.dialects import postgresql # noqa: E402
from erp_platform import capabilities # noqa: E402
from brick_contracts.infrastructure.tables import md # noqa: E402
HEAD = """-- brick-contracts: contracts, the clause library, templates and simple e-signature evidence. GENERATED from
-- src/brick_contracts/infrastructure/tables.py by scripts/gen_schema.py — edit tables.py, then regenerate.
-- Additive only: a new column goes at the END of its CREATE and as an explicit ALTER below it (erp-migrate refuses
-- DROP / RENAME / type changes). Natural keys only (never SERIAL); every child table's key starts with its
-- aggregate root's key. ct_signature_event is APPEND-ONLY (written by plain INSERT, never updated).
-- DataK3 enforces no foreign key: this brick being the ONLY writer of ct_* is the integrity.
"""
def render() -> str:
d = postgresql.dialect()
out = [HEAD]
for t in md.sorted_tables:
cols = []
for c in t.columns:
null = " NOT NULL" if (not c.nullable or c.primary_key) else ""
typ = c.type.compile(dialect=d).replace(" WITHOUT TIME ZONE", "").replace(", ", ",")
cols.append(f" {c.name} {typ}{null}")
pk = ", ".join(c.name for c in t.primary_key.columns)
out.append(f"CREATE TABLE IF NOT EXISTS {t.name} (\n" + ",\n".join(cols) + f",\n PRIMARY KEY ({pk})\n);\n")
out.append("-- The capability claims and action log of a PROVIDER (contracts.draft / send / status / fetch_executed),\n"
"-- named by the platform after the brick (contracts_), not ct_.\n" + capabilities.ddl("contracts"))
return "\n".join(out)
if __name__ == "__main__":
sys.stdout.write(render())