Aug 5 - Add new design (switchable)
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
"""0003 — placeholder for the missing early revision `0003_add_user_active`
|
||||
|
||||
WHY THIS FILE EXISTS
|
||||
────────────────────
|
||||
`phase1_projects_roles.py` declares `down_revision = '0003_add_user_active'`,
|
||||
but no migration script with that revision id exists in migrations/versions/.
|
||||
The early 0001–0003 scripts were lost from the repository at some point; the
|
||||
schema changes they made are long since applied in every environment (the
|
||||
`users.active` column exists), so nothing is missing from the database — only
|
||||
the node in Alembic's revision graph.
|
||||
|
||||
Alembic tolerates that as a warning while it walks the graph, but as soon as it
|
||||
has to build the full revision map (which any `flask db upgrade <target>` does),
|
||||
it fails hard:
|
||||
|
||||
KeyError: '0003_add_user_active'
|
||||
|
||||
This file restores the node so the chain resolves. It is intentionally a NO-OP:
|
||||
it makes no schema change in either direction, and it declares itself the base
|
||||
of the chain (`down_revision = None`) because the revisions below it no longer
|
||||
exist as files.
|
||||
|
||||
It never runs in practice — every environment's alembic_version is already far
|
||||
past it — but if it ever did, upgrade() and downgrade() do nothing, so it is
|
||||
safe either way.
|
||||
|
||||
DO NOT DELETE. Removing it re-breaks `flask db upgrade`.
|
||||
"""
|
||||
|
||||
revision = '0003_add_user_active'
|
||||
down_revision = None
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# No-op: the schema change this revision originally made (users.active)
|
||||
# is already present in every environment.
|
||||
pass
|
||||
|
||||
|
||||
def downgrade():
|
||||
# No-op: nothing to reverse.
|
||||
pass
|
||||
@@ -0,0 +1,51 @@
|
||||
"""phase48 — per-user web portal design preference
|
||||
|
||||
Adds to `users`:
|
||||
|
||||
ui_theme VARCHAR(16) NOT NULL DEFAULT 'classic'
|
||||
|
||||
Drives the design A/B test: 'classic' renders the original top-navbar shell
|
||||
(layouts/classic.html), 'modern' renders the new sidebar shell
|
||||
(layouts/modern.html). Every existing account starts on 'classic', so the
|
||||
portal looks and behaves exactly as before until a user opts in.
|
||||
|
||||
The value doubles as the user's vote — /ui/theme-votes tallies it.
|
||||
|
||||
Uses an INFORMATION_SCHEMA existence check — safe to re-run.
|
||||
"""
|
||||
|
||||
revision = 'phase48_user_ui_theme'
|
||||
down_revision = 'phase47_sched_acknowledged'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
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 _column_exists(bind, 'users', 'ui_theme'):
|
||||
op.execute(sa.text(
|
||||
"ALTER TABLE users "
|
||||
"ADD COLUMN ui_theme VARCHAR(16) NOT NULL DEFAULT 'classic'"
|
||||
))
|
||||
# Idempotent backfill for any row that predates the DEFAULT.
|
||||
op.execute(sa.text(
|
||||
"UPDATE users SET ui_theme = 'classic' "
|
||||
"WHERE ui_theme IS NULL OR ui_theme NOT IN ('classic', 'modern')"
|
||||
))
|
||||
|
||||
|
||||
def downgrade():
|
||||
bind = op.get_bind()
|
||||
if _column_exists(bind, 'users', 'ui_theme'):
|
||||
op.execute(sa.text("ALTER TABLE users DROP COLUMN ui_theme"))
|
||||
Reference in New Issue
Block a user