Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """Offline contract validation for committed PostgreSQL migrations.""" | |
| from __future__ import annotations | |
| import re | |
| import sys | |
| from pathlib import Path | |
| ROOT = Path(__file__).resolve().parents[1] | |
| sys.path.insert(0, str(ROOT / "hermes_overlay")) | |
| from trading.domain.schema import REQUIRED_TABLES, migration_plan # noqa: E402 | |
| FORBIDDEN = ( | |
| "AUTOINCREMENT", | |
| "PRAGMA ", | |
| "BEGIN IMMEDIATE", | |
| "SQLITE_MASTER", | |
| "RANDOMBLOB(", | |
| "INSERT OR IGNORE", | |
| ) | |
| def validate(root: Path = ROOT) -> list[str]: | |
| errors: list[str] = [] | |
| try: | |
| plan = migration_plan("postgresql") | |
| except Exception as exc: | |
| return [str(exc)] | |
| combined = "\n".join(item.path.read_text(encoding="utf-8") for item in plan) | |
| upper = combined.upper() | |
| for token in FORBIDDEN: | |
| if token in upper: | |
| errors.append(f"PostgreSQL migration contains SQLite-only token: {token}") | |
| created = { | |
| match.group(1).lower() | |
| for match in re.finditer( | |
| r"\bCREATE\s+TABLE(?:\s+IF\s+NOT\s+EXISTS)?\s+[\"']?([a-zA-Z_][a-zA-Z0-9_]*)", | |
| combined, | |
| flags=re.IGNORECASE, | |
| ) | |
| } | |
| # schema_migrations is created by the runner before applying migration files. | |
| missing = sorted((REQUIRED_TABLES - {"schema_migrations"}) - created) | |
| if missing: | |
| errors.append(f"PostgreSQL baseline missing required tables: {missing}") | |
| if "BIGSERIAL" not in upper: | |
| errors.append("PostgreSQL baseline must use a native generated-key type") | |
| if "REFERENCES ORDERS(ORDER_ID)" not in upper: | |
| errors.append("PostgreSQL order child entities must enforce foreign keys") | |
| for migration in plan: | |
| text = migration.path.read_text(encoding="utf-8").strip() | |
| if not text.endswith(";"): | |
| errors.append(f"migration does not end with a statement terminator: {migration.version}") | |
| return errors | |
| def main() -> int: | |
| errors = validate() | |
| for error in errors: | |
| print(f"ERROR: {error}") | |
| print( | |
| f"postgresql_migrations={'PASS' if not errors else 'FAIL'} " | |
| f"migrations={len(migration_plan('postgresql')) if not errors else 'unknown'}" | |
| ) | |
| return 1 if errors else 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |