Aug 5 - Update code to follow up ST - MT14b

This commit is contained in:
2026-08-05 09:43:00 -04:00
parent 45ad924df8
commit be5484e1fb
9 changed files with 965 additions and 38 deletions
@@ -0,0 +1,83 @@
"""phase50 — inspection schedule receipt acknowledgement
Ports single-tenant phase47 onto MT's `inspection_schedules` table. Adds:
acknowledged_at DATETIME NULL
Stamped when the assigned inspector confirms they have received/seen a scheduled
inspection request. NULL = awaiting confirmation.
Scope of the acknowledgement
----------------------------
It is per ASSIGNMENT, not per occurrence. `fulfill()` and `advance_due_date()`
deliberately leave this column alone as the schedule rolls forward — an
inspector who confirmed "yes, this weekly restroom round is mine" should not be
asked again every week. The edit route resets it to NULL when the schedule is
reassigned to a DIFFERENT inspector, because the new assignee has confirmed
nothing.
The acknowledger is always the assigned inspector — the only person the routes
permit to confirm — so no separate `acknowledged_by` column is stored.
Only meaningful for `plan` mode: an `auto` schedule materialises its inspection
without anyone starting it, so there is no request to receive. The UI shows the
control for plan-mode rows only.
No backfill: legacy rows keep NULL and render as "awaiting confirmation", which
is the correct initial state for an assignment nobody has confirmed yet.
Revision id note
----------------
`alembic_version.version_num` is VARCHAR(32); the id below is 24 characters.
The filename stays descriptive — Alembic keys on the `revision` string.
Uses an INFORMATION_SCHEMA check — safe to re-run on every tenant DB. Additive
only: nothing is renamed, retyped or dropped.
"""
revision = 'phase50_sched_acknowledged'
down_revision = 'phase49_followup_req_by'
branch_labels = None
depends_on = None
from alembic import op
import sqlalchemy as sa
_TABLE = 'inspection_schedules'
_COLUMN = 'acknowledged_at'
def _table_exists(conn, table):
return conn.execute(sa.text(
"SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES "
"WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = :t"
), {"t": table}).scalar() > 0
def _column_exists(conn, table, column):
return conn.execute(sa.text(
"SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS "
"WHERE TABLE_SCHEMA = DATABASE() "
"AND TABLE_NAME = :t AND COLUMN_NAME = :c"
), {"t": table, "c": column}).scalar() > 0
def upgrade():
bind = op.get_bind()
if not _table_exists(bind, _TABLE):
return
if not _column_exists(bind, _TABLE, _COLUMN):
op.execute(sa.text(
f"ALTER TABLE {_TABLE} ADD COLUMN {_COLUMN} DATETIME NULL"
))
def downgrade():
bind = op.get_bind()
if not _table_exists(bind, _TABLE):
return
if _column_exists(bind, _TABLE, _COLUMN):
op.execute(sa.text(
f"ALTER TABLE {_TABLE} DROP COLUMN {_COLUMN}"
))