Exclude PM room types from shared daily report processing
This commit is contained in:
1 parent
d3902dd857
commit
f46efd6d9a
32 files changed
+968
-69
No files matched your search
@@ -158,16 +158,20 @@ def _is_transient_database_error(error: Exception) -> bool:
|
||||
return isinstance(sqlstate, str) and sqlstate in TRANSIENT_SQLSTATES
|
||||
|
||||
|
||||
def _outcome_counts(payload: Mapping[str, Any]) -> Tuple[int, int, int, int, int, int]:
|
||||
def _outcome_counts(payload: Mapping[str, Any]) -> Tuple[int, int, int, int, int, int, int]:
|
||||
values = payload.get("outcome_counts")
|
||||
if not isinstance(values, Mapping):
|
||||
raise IngestionError(
|
||||
"RESULT_CONTRACT_INVALID",
|
||||
"structured outcome counts are invalid",
|
||||
)
|
||||
if payload.get("processor_version") == "4.4.0" and not {
|
||||
"excluded_cancelled", "excluded_pm"
|
||||
}.issubset(values):
|
||||
raise IngestionError("RESULT_CONTRACT_INVALID", "structured outcome counts are invalid")
|
||||
try:
|
||||
counts = tuple(
|
||||
int(values.get(name, 0) if name == "excluded_cancelled" else values[name])
|
||||
int(values.get(name, 0) if name in {"excluded_cancelled", "excluded_pm"} else values[name])
|
||||
for name in (
|
||||
"retained",
|
||||
"excluded_rate_code",
|
||||
@@ -175,6 +179,7 @@ def _outcome_counts(payload: Mapping[str, Any]) -> Tuple[int, int, int, int, int
|
||||
"validation_failed",
|
||||
"price_unmatched",
|
||||
"excluded_cancelled",
|
||||
"excluded_pm",
|
||||
)
|
||||
)
|
||||
except (KeyError, TypeError, ValueError):
|
||||
@@ -339,6 +344,7 @@ class PostgresIngestionRepository(IngestionRepository):
|
||||
raise IngestionError("DATABASE_MIGRATION_MISSING", "direct data entry requires migration 019")
|
||||
self._run_transaction(check, "direct data schema could not be checked")
|
||||
self.assert_cancelled_scope_schema()
|
||||
self.assert_pm_scope_schema()
|
||||
|
||||
def assert_cancelled_scope_schema(self) -> None:
|
||||
"""Require the count and outcome constraints before either input is enabled."""
|
||||
@@ -365,6 +371,36 @@ class PostgresIngestionRepository(IngestionRepository):
|
||||
"ARR processing requires migration 020")
|
||||
self._run_transaction(check, "ARR cancellation schema could not be checked")
|
||||
|
||||
def assert_pm_scope_schema(self) -> None:
|
||||
"""Require PM auditing before enabling the processor 4.4 entrypoints."""
|
||||
def check(cursor):
|
||||
cursor.execute("""SELECT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = 'finance' AND table_name = 'daily_versions'
|
||||
AND column_name = 'excluded_pm_rows'
|
||||
AND data_type = 'integer' AND is_nullable = 'NO'
|
||||
), (
|
||||
SELECT pg_get_constraintdef(oid) FROM pg_constraint
|
||||
WHERE conrelid = 'finance.daily_versions'::regclass
|
||||
AND conname = 'daily_versions_counts_reconcile'
|
||||
), (
|
||||
SELECT pg_get_constraintdef(oid) FROM pg_constraint
|
||||
WHERE conrelid = 'finance.daily_records'::regclass
|
||||
AND conname = 'daily_records_outcome_check'
|
||||
), (
|
||||
SELECT pg_get_constraintdef(oid) FROM pg_constraint
|
||||
WHERE conrelid = 'finance.daily_records'::regclass
|
||||
AND conname = 'daily_records_pm_exclusion_shape'
|
||||
)""")
|
||||
row = cursor.fetchone()
|
||||
if (not row or row[0] is not True
|
||||
or "excluded_pm_rows" not in str(row[1] or "")
|
||||
or "excluded_pm" not in str(row[2] or "")
|
||||
or "ROOM_TYPE_PM_EXCLUDED" not in str(row[3] or "")):
|
||||
raise IngestionError("DATABASE_MIGRATION_MISSING",
|
||||
"ARR processing requires migration 021")
|
||||
self._run_transaction(check, "ARR PM schema could not be checked")
|
||||
|
||||
def register_job(self, registration: JobRegistration) -> None:
|
||||
if (
|
||||
registration.source.role not in {"source_xml", "source_data"}
|
||||
@@ -1837,13 +1873,14 @@ class PostgresIngestionRepository(IngestionRepository):
|
||||
validation_failed_rows,
|
||||
price_unmatched_rows,
|
||||
excluded_cancelled_rows,
|
||||
excluded_pm_rows,
|
||||
failure_code,
|
||||
failure_message,
|
||||
validated_at
|
||||
)
|
||||
VALUES (
|
||||
NULL, NULL, %s, %s, %s, %s, %s, 'rejected',
|
||||
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
|
||||
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
|
||||
%s, 'deterministic processing failed', now()
|
||||
)
|
||||
RETURNING id
|
||||
@@ -2076,11 +2113,12 @@ class PostgresIngestionRepository(IngestionRepository):
|
||||
validation_failed_rows,
|
||||
price_unmatched_rows,
|
||||
excluded_cancelled_rows,
|
||||
excluded_pm_rows,
|
||||
validated_at
|
||||
)
|
||||
VALUES (
|
||||
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 'validated',
|
||||
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, now()
|
||||
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, now()
|
||||
)
|
||||
RETURNING id
|
||||
""",
|
||||
|
||||
Reference in new issue
Block a user