test_db_migration_contract.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. from __future__ import annotations
  2. from pathlib import Path
  3. MIGRATION = Path("db/migrations/001_creation_knowledge_schema.sql")
  4. def _migration_sql() -> str:
  5. return MIGRATION.read_text(encoding="utf-8")
  6. def test_creation_knowledge_migration_declares_formal_business_tables():
  7. sql = _migration_sql()
  8. expected_tables = [
  9. "query_batches",
  10. "queries",
  11. "acquisition_runs",
  12. "acquisition_jobs",
  13. "candidate_items",
  14. "media_assets",
  15. "item_classifications",
  16. "decode_jobs",
  17. "decode_results",
  18. "knowledge_particles",
  19. "scope_results",
  20. "payload_drafts",
  21. "ingest_records",
  22. "contract_snapshots",
  23. ]
  24. assert "CREATE SCHEMA IF NOT EXISTS creation_knowledge" in sql
  25. assert "CREATE EXTENSION IF NOT EXISTS pgcrypto" in sql
  26. for table in expected_tables:
  27. assert f"CREATE TABLE IF NOT EXISTS creation_knowledge.{table}" in sql
  28. def test_migration_is_replayable_and_not_sqlite_shaped():
  29. sql = _migration_sql()
  30. assert "CREATE TABLE IF NOT EXISTS" in sql
  31. assert "CREATE INDEX IF NOT EXISTS" in sql
  32. assert "ON CONFLICT (version) DO UPDATE" in sql
  33. assert "CREATE OR REPLACE FUNCTION creation_knowledge.touch_updated_at" in sql
  34. assert "CREATE TRIGGER" in sql
  35. sqlite_only_tokens = ["AUTOINCREMENT", "PRAGMA", "sqlite_master", "WITHOUT ROWID"]
  36. assert not any(token in sql.upper() for token in sqlite_only_tokens)
  37. def test_migration_keeps_state_rows_traceable_and_resumable():
  38. sql = _migration_sql()
  39. for table in [
  40. "acquisition_runs",
  41. "acquisition_jobs",
  42. "candidate_items",
  43. "decode_jobs",
  44. "decode_results",
  45. "payload_drafts",
  46. "ingest_records",
  47. ]:
  48. assert f"creation_knowledge.{table}" in sql
  49. assert "status text NOT NULL" in sql
  50. assert "attempt_count integer NOT NULL DEFAULT 0" in sql
  51. assert "error_message text" in sql
  52. assert "metadata jsonb NOT NULL DEFAULT '{}'::jsonb" in sql
  53. assert "source_payload jsonb NOT NULL DEFAULT '{}'::jsonb" in sql
  54. assert "response_payload jsonb NOT NULL DEFAULT '{}'::jsonb" in sql
  55. assert "UNIQUE (run_id, query_id, platform)" in sql
  56. assert "idx_candidate_items_platform_item" in sql