mirror of
https://github.com/hansjone/netx.git
synced 2026-10-15 01:00:53 +08:00
Per-user layout lives in the new app_user.prefs JSON column, read via /v1/auth/me and written via PUT /v1/auth/me/prefs/workbench. The workbench gets an in-place edit mode (gear -> drag to reorder, x to remove, tray to add back, reset/done). Reset stores empty prefs so registry changes still apply; ids of modules the user can't currently see are kept on save. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
52 lines
1.8 KiB
Python
52 lines
1.8 KiB
Python
"""Add app_user.prefs JSON for per-user UI preferences.
|
|
|
|
Revision ID: 20261013_user_prefs
|
|
Revises: 20260922_biz_state_queued
|
|
Create Date: 2026-10-13
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Sequence, Union
|
|
|
|
import sqlalchemy as sa
|
|
from alembic import op
|
|
|
|
revision: str = "20261013_user_prefs"
|
|
down_revision: Union[str, Sequence[str], None] = "20260922_biz_state_queued"
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
|
depends_on: Union[str, Sequence[str], None] = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
bind = op.get_bind()
|
|
dialect = str(getattr(bind.dialect, "name", "") or "").lower()
|
|
if dialect.startswith("postgres"):
|
|
op.execute(
|
|
"ALTER TABLE app_user ADD COLUMN IF NOT EXISTS prefs JSON DEFAULT '{}'::json NOT NULL"
|
|
)
|
|
# Ensure NOT NULL + default for brownfield rows that already had a nullable column.
|
|
op.execute("UPDATE app_user SET prefs = '{}'::json WHERE prefs IS NULL")
|
|
op.execute("ALTER TABLE app_user ALTER COLUMN prefs SET DEFAULT '{}'::json")
|
|
op.execute("ALTER TABLE app_user ALTER COLUMN prefs SET NOT NULL")
|
|
else:
|
|
insp = sa.inspect(bind)
|
|
if "app_user" in insp.get_table_names():
|
|
cols = {c["name"] for c in insp.get_columns("app_user")}
|
|
if "prefs" not in cols:
|
|
op.add_column(
|
|
"app_user",
|
|
sa.Column("prefs", sa.JSON(), nullable=False, server_default="{}"),
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
bind = op.get_bind()
|
|
dialect = str(getattr(bind.dialect, "name", "") or "").lower()
|
|
if dialect.startswith("postgres"):
|
|
op.execute("ALTER TABLE app_user DROP COLUMN IF EXISTS prefs")
|
|
else:
|
|
try:
|
|
op.drop_column("app_user", "prefs")
|
|
except Exception:
|
|
pass
|