"""invites.lang — the language this person asked us in Revision ID: 0082_invite_lang Revises: 0081_invite_invited_at Create Date: 2026-09-05 The mails an access request produces — approved, denied, invited — go to an address that often has no account yet, so there is no `preferences.language` to read. The signal does exist, though, and only at the moment of the request: the language of the page the form was submitted from, or the locale Google reported for a sign-in we refused. Recording it there is what lets the decision mail answer in the requester's own language instead of an admin's guess about a stranger. Captured rather than derived, for the third time in this epic: `preferences.language` (S6) and `google_email` (S3) both taught that a signal which exists only in one moment cannot be backfilled later. So no backfill here either — NULL means "we were never told", which is the honest state for every historic row, and for every address an admin whitelists by hand. Those fall back to English unless the admin picks otherwise on the invitation send. """ import sqlalchemy as sa from alembic import op revision: str = "0082_invite_lang" down_revision: str | None = "0081_invite_invited_at" branch_labels: str | None = None depends_on: str | None = None def upgrade() -> None: op.add_column("invites", sa.Column("lang", sa.String(length=8), nullable=True)) def downgrade() -> None: op.drop_column("invites", "lang")