Let users pick and order their workbench module tiles.

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>
This commit is contained in:
oliver 2026-10-13 08:31:51 +08:00
parent 313706595d
commit 2307f19779
16 changed files with 906 additions and 23 deletions

View file

@ -76,6 +76,11 @@ def user_public(user: AppUser) -> dict[str, Any]:
}
def user_prefs(user: AppUser) -> dict[str, Any]:
raw = getattr(user, "prefs", None)
return dict(raw) if isinstance(raw, dict) else {}
def sanitize_detail(detail: Any) -> Any:
"""Recursively drop secret-looking keys from audit detail payloads."""
if isinstance(detail, dict):
@ -431,6 +436,7 @@ def login_issue_token(
"expires_in": ttl,
"refresh_expires_in": refresh_ttl,
"user": user_public(user),
"prefs": user_prefs(user),
}