Files
summercms/.planning/phases/12.1-user-plugin-admin-screens/12.1-DISCUSSION-LOG.md
2026-10-04 14:52:44 +02:00

8.7 KiB

Phase 12.1: User plugin admin screens - Discussion Log

Audit trail only. Do not use as input to planning, research, or execution agents. Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.

Date: 2026-10-04 Phase: 12.1-user-plugin-admin-screens Areas discussed: Impersonate and convert-guest, Group membership and the admin group, User actions and trashed users, Fields the Go model lacks, Release


Impersonate and convert-guest

Should 'impersonate user' be part of this phase?

Option Description Selected
Out of scope (Recommended) PHP impersonation is session-based and never reaches the JWT-driven Nuxt app; permission not registered
Out, but register the permission No action, but golem15.users.impersonate_user is registered so imported roles stay valid ✓
In scope: mint a user JWT Admin gets a short-lived frontend token for the user, with audit; needs security review and a Nuxt entry point

User's choice: Out, but register the permission

What happens to convert-guest and the guest concept?

Option Description Selected
Drop it entirely (Recommended) No action, no is_guest column or list column, no guest hint ✓
Add is_guest, skip the action Column and invisible list column for schema fidelity, no popup
Port convert-guest fully Column, popup with group choice, optional registration mail

User's choice: Drop it entirely Notes: The application never creates guests and the Go users table has no is_guest.


Group membership and the admin group

Which backend permission is required to change a user's group membership?

Option Description Selected
Extra permission for privileged groups (Recommended) access_users for ordinary groups; privileged groups need a new permission, server-side ✓
access_users only (PHP parity) Any user editor can put a user in any group, including admin
New permission for all membership changes Any users_groups change needs a dedicated permission

How does the plugin know which groups are privileged?

Option Description Selected
Config list, default [admin] (Recommended) golem15.user config key listing privileged codes ✓
Hard-coded code admin Only admin is privileged, no config
A flag column on user_groups New boolean on the group row

How should the User Groups screen guard privileged codes?

Option Description Selected
Privileged codes need the extra permission (Recommended) Create with, rename to/from, and delete of a privileged code need the extra permission ✓
Code is read-only after create Code never changes once saved
No guard (PHP parity) access_groups edits any group including its code

How do privileged groups behave for an admin without the permission?

Option Description Selected
Shown but locked, 403 on tamper (Recommended) Visible and disabled; a tampered save is refused and changes nothing ✓
Hidden from the options Left out of the field; existing memberships kept
Whole save refused, no UI hint Field looks normal; validation error if a privileged group changed

User actions and trashed users

How should the Go admin carry the six bulk actions and three record actions?

Option Description Selected
Extend cabana generically (Recommended) Framework gains declared bulk actions and record actions ✓
Plugin-side with existing pieces Widget buttons on the form; bulk actions dropped except delete
Record actions only, bulk later Record buttons now, bulk to the backlog

Delete semantics and trashed users

Option Description Selected
PHP parity (Recommended) Trashed users listed; deactivate = soft delete, restore, delete = permanent ✓
Parity, but force delete needs confirmation by email Same, plus typing the user's email before a permanent delete
Soft delete only No permanent delete in the admin

Where do the status and the actions live (PHP has a preview screen)?

Option Description Selected
On the update form (Recommended) Status notice and conditional action buttons on the update form; no preview
Add a preview screen to the framework cabana gains Winter's preview context with its own toolbar ✓
Actions always visible, no status notice All buttons shown regardless of state

User's choice: Add a preview screen to the framework Notes: Chosen over the recommended lighter option; PHP parity of the admin experience is the bar.

How should the list show user state?

Option Description Selected
Generic row state in the framework (Recommended) Controller returns a state per row from a fixed set; SPA styles with tokens ✓
A status column One computed Status column, no row styling
Both Row state and a status column

Fields the Go model lacks

Port the frontend Permissions tab (FrontendPermissionEditor)?

Option Description Selected
Leave out, defer (Recommended) No Permissions tab; its own later phase
Port the editor Registry table, users.permissions, editor on both forms ✓

User's choice: Port the editor

How far does the frontend-permissions port go?

Option Description Selected
Storage, editor and resolver (Recommended) Table, column, editor, and a Go getMergedPermissions equivalent ✓
Storage and editor only No resolver until a project needs it
Also a plugin-declared registry Plugins declare frontend permissions in Go, synced at boot

How should the editor be built?

Option Description Selected
Built-in framework field type (Recommended) permissioneditor in cabana and the SPA, reusable for backend roles later ✓
Extend the widget contract type: widget carries a structured value; plugin ships a custom element

Block mail (MailBlocker)

Option Description Selected
Leave out, defer (Recommended) No checkbox; a mail feature, not an admin screen
Port MailBlocker now Table, form flag, mailer check

User's choice: (free text) "Leave out, write in todos to implement together with mailing development (so together with mail settings, templates etc)" Notes: Todo written: .planning/todos/pending/mailblocker-with-mailing.md.

username and last_seen

Option Description Selected
Drop both from the YAML (Recommended) Only columns the Go model has
Add last_seen, drop username Additive last_seen updated by the auth path ✓
Add both columns Full schema fidelity

Create form: password, invite, avatar

Option Description Selected
All of it (Recommended) Password + confirmation, reset on update, send_invite mail, avatars on users and organisations ✓
Password and avatar, no invite No invitation mail
Password only No invite, no avatar fields

Release

Option Description Selected
Framework first, tagged v0.1.2 (Recommended) Framework work lands first and is tagged; plugin builds on the tag ✓ (as v0.1.3)
One phase, no tag Ship together through the local replace
Split the framework work into its own phase Insert 12.3 for the cabana features

User's choice: (free text) "Framework first, but i belive it's v0.1.3, v0.1.2 already exists" Notes: Verified with git tag: v0.1.2 exists, so the tag is v0.1.3.


Claude's Discretion

  • The extra permission's code, label and tab; the privileged-list config key name.
  • YAML keys and Go interface names for bulk actions, record actions, preview and row state.
  • The row state set and styling; preview screen contents beyond hints, fields and actions.
  • When last_seen is written; force-delete cleanup details.
  • Plan count and split (subject to the plan-count checkpoint).

Deferred Ideas

  • Impersonation by minting a short-lived user JWT.
  • MailBlocker with the mailing work (todo written).
  • Guests and convert-guest; username and login by username.
  • Plugin-declared frontend permission registry; permissioneditor for backend roles.
  • The user plugin's Settings screen.