Expand description
Admin-owned models: user preferences and audit log.
Registered via [crate::AdminPlugin::models] so they flow through the
framework’s migration engine like any other plugin’s models. No raw
CREATE TABLE, no on_ready bootstrap — the same path used for
the admin LogEntry table.
§AdminUserPref
One row per admin user. Created the first time a user lands on
GET /admin/api/prefs. Holds theme, density, sidebar-collapsed
state, and the serialized dashboard layout.
§AdminAuditLog
One row per write operation (create / update / delete / bulk action).
The actor is the AuthUser resolved from the session at call time;
diff_summary is a short human description synthesized from context
(no field-level diffing in v1).
§Why the model is noedit
Every field on both models is marked #[umbral(noedit)] so the admin
exposes them as read-only — users see preferences and audit history
in the UI but cannot mutate them through the form path. Writes flow
exclusively through this module’s typed helpers.
Modules§
Structs§
- Admin
Audit Log - One entry in the admin audit trail.
- Admin
User Pref - Per-user admin preferences row.
- Audit
Entry - Template-friendly audit entry —
created_atrendered as RFC 3339 for minijinja, which has noDateTimecodec. - Table
Pref - gaps2 #11 — per-table changelist UI state. Persisted as a nested
entry under
preferences.tables.<table>in the JSON blob.
Functions§
- audit_
for_ object - Fetch the last
limitaudit entries for one object, newest first. Returned as template-friendlyAuditEntryvalues (timestamps formatted as strings) for direct rendering by minijinja. - fetch_
or_ default - Fetch the prefs row for
user_id, or return a struct filled with defaults (the row is not inserted; the caller decides whether to persist).id == 0distinguishes the unsaved-default case. - get_
last_ path - gaps2 #11 round 2 — read the “last viewed admin URL” for
user_id. Used by the admin index handler to redirect/admin/→ the user’s last working changelist. - get_
table_ pref - gaps2 #11 — read the persisted UI state for
(user_id, table). - get_
widget_ filters - Every saved filter value for one widget, from
preferences.dashboard.widget_filters.<widget_key>. - get_
widget_ period - gaps2 #11 round 2 — read a saved widget-period override for
widget_keyonpreferences.dashboard.widget_periods.<key>. - log
- Append one audit entry. Fire-and-forget: errors are logged but never surfaced to the caller, so a CRUD handler that succeeds at its real work isn’t undone by an audit-write hiccup.
- set_
last_ path - gaps2 #11 round 2 — write
last_pathtopreferences.last_path. Read-modify-write through the JSON blob, same pattern asset_table_pref. - set_
table_ pref - gaps2 #11 — merge a new
TablePrefintopreferences.tables.<table>. - set_
widget_ filter - Persist one filter value at
preferences.dashboard.widget_filters.<widget_key>.<filter_key>. - set_
widget_ period - gaps2 #11 round 2 — persist a widget-period override at
preferences.dashboard.widget_periods.<widget_key>. Same read-modify-write merge asset_table_pref/set_last_path. - toggle_
table_ col - gaps2 #11 round 2 — flip a column’s visibility on
preferences.tables.<table>.hidden_cols. Idempotent toggle: already-hidden → visible, already-visible → hidden. Returns the new visibility (true= now visible,false= now hidden) so the caller can emit a precise HX-Trigger payload. - upsert
- Insert or update the prefs row.