"""invites.invited_at — when the admin actually told this person the door was open Revision ID: 0081_invite_invited_at Revises: 0080_google_email Create Date: 2026-09-05 Whitelisting an address stays SILENT by design: the operator is opening a door as a possibility, usually after agreeing it with the person, and a row can sit approved for weeks without anyone registering. Telling them is therefore a separate, deliberate act — a send button on the row. Which raises the one question the admin cannot otherwise answer: "did I already write to them?" Without a record the only failure mode is writing to a real person twice, which is exactly the nudging the silent-by-default design exists to avoid. The audit log holds the event, but not where the decision is made. NULL means "never invited from here", which is true of every existing row: no backfill is possible or wanted, since the historic approval mails answered a REQUEST rather than inviting anyone. """ import sqlalchemy as sa from alembic import op revision: str = "0081_invite_invited_at" down_revision: str | None = "0080_google_email" branch_labels: str | None = None depends_on: str | None = None def upgrade() -> None: op.add_column("invites", sa.Column("invited_at", sa.DateTime(timezone=True), nullable=True)) def downgrade() -> None: op.drop_column("invites", "invited_at")