--- status: Active lastUpdated: 2026-09-16 applyTo: - "Fuchs/Controllers/IntranetController.AdminGroups.cs" - "Fuchs/js/intranet/modules/fis.usrgrp*.js" - "Fuchs/js/intranet/modules/fis.usrgrp.scss" - "Fuchs/js/intranet/fis_main_menu.js" - "Fuchs_Database/dbo/Functions/fis_admin_getUserGroupList.sql" - "Fuchs_Database/dbo/Stored Procedures/fis_admin_setUserGroup.sql" - "Fuchs_Database/dbo/Stored Procedures/fis_admin_delUserGroup.sql" relatedDecisions: - "0021-user-group-management.md" - "0014-admin-user-management.md" - "0015-split-admin-user-management-module.md" --- # Group Management module (`usrgrp`) ## Summary The **Gruppenverwaltung** module lets a privileged operator see every non-deleted usergroup, create a new one, rename it, and delete it. It's the catalog-management counterpart to the `usr` module's per-user "Gruppen" dialog, which toggles an individual user's membership in these groups but cannot create/rename/delete the groups themselves. Same sidemenu-visibility and server-side authorization gate as `usr`/`admin` (`fds_sys > 4`), own `fn=usrgrp`, own frontend bundle, own controller partial. See [0021](../Decisions/0021-user-group-management.md) for why this is a separate module rather than folded into `usr`. ## How it works ### Authorization (two independent axes — same as `usr`, read [0014](../Decisions/0014-admin-user-management.md) first) 1. **Menu visibility + `fds_sys` gate** — `fis_main_menu.js#addAdminMenuButtonsIfAuthorized` checks `fds_sys > 4` once and, if authorized, adds the "Administration" sidemenu dropdown with three entries: Benutzerverwaltung (`init:usr`), Gruppenverwaltung (`init:usrgrp`) and Systemüberwachung (`init:admin`). Every `/do/usrgrp/*` endpoint re-checks `fds_sys > 4` server-side (`Do_Process_AdminGroups`, reusing `AdminMinAuthExclusive`/`GetSystemAdminAuthAsync` from `IntranetController.Admin.cs`) and 401s otherwise. 2. **Separate SQL-layer gate** — every `fis_admin_*` proc/function called below independently checks the caller's `intranet_admin` setting via `fis_admin_getUserAuth(@authaccount) > 1`. An account with `fds_sys > 4` but no `intranet_admin` setting reaches every `usrgrp` endpoint but gets empty results / silent no-op writes — not an error. This also applies to `fis_admin_addGroupMember`/`remGroupMember` (used by the `usr` module's membership dialog, documented there) — all five group-related `fis_admin_*` write/read objects now carry this check as of [0021](../Decisions/0021-user-group-management.md), which closed a real gap where three of them had none. ### Request flow ``` click "Gruppenverwaltung" → $ocms.init('usrgrp') POST /do/usrgrp/auth → { manage, level } (manage>0 ⇒ authorized) load /web/fis.usrgrp.de.js + /web/fis.usrgrp.css $ocms.usrgrp.init2() → init3() → renderLst() POST /do/usrgrp/list → { groups: [...] } every non-deleted group base ribbon (eM) → "Anlegen" (always available) POST /do/usrgrp/create {name} → { ok, usergroup_id, name } row click → per-row ribbon (iMn): Umbenennen / Löschen POST /do/usrgrp/rename {usergroup_id, name} → { ok, usergroup_id, name } POST /do/usrgrp/delete {usergroup_id} → { ok } ``` ### Backend (`IntranetController.AdminGroups.cs`) - `list` → `fis_admin_getUserGroupList(@authaccount, NULL)`, all non-deleted groups with decrypted names. - `create`/`rename` → both call `fis_admin_setUserGroup(@authaccount, @usergroup_id, @name, @enc_key)`; `create` passes `@usergroup_id = NULL` (the proc generates a new id via `fis_fn_id`), `rename` passes the existing id. - `delete` → `fis_admin_delUserGroup(@authaccount, @usergroup_id)` (soft-delete: sets `UserDeleted`/`DateDeleted`). No check for remaining members — a deleted group's membership rows simply stop being returned by `fis_admin_getUserGroupMembership` (filtered on the group's own `DateDeleted`), see [0021](../Decisions/0021-user-group-management.md) Consequences. ### Frontend (`fis.usrgrp.js` + `fis.usrgrp_txt_de.js` + `fis.usrgrp.scss`) Same list+ribbon pattern as `fis.usr.js`: `renderLst` builds a single-column card-style row list; a row click toggles `.selected` and swaps the `#topbar` ribbon between the base ribbon (`eM`: "Anlegen") and the per-row actions (`iMn`: Umbenennen/Löschen). `createDlg`/`renameDlg` use `$ocms.dlgform`; `deleteGroup` follows the `confirm(...)`-before-destructive-action pattern (no dialog, nothing to collect beyond the confirmation). ## Key files - `Fuchs/Controllers/IntranetController.AdminGroups.cs` — `Do_Process_AdminGroups` dispatch. - `Fuchs/Controllers/IntranetController.Admin.cs` — shared `AdminMinAuthExclusive`/ `GetSystemAdminAuthAsync`/`AdminJson` this module reuses. - `Fuchs/js/intranet/modules/fis.usrgrp.js`, `fis.usrgrp_txt_de.js`, `fis.usrgrp.scss` — the module, texts, styles (bundled via `bdlconfig.json`, `intranet:usrgrp` context). - `Fuchs/js/intranet/fis_main_menu.js` (`addAdminMenuButtonsIfAuthorized`) — sidemenu wiring. - `Fuchs_Database/dbo/Functions/fis_admin_getUserGroupList.sql` — read-side group query. - `Fuchs_Database/dbo/Stored Procedures/fis_admin_setUserGroup.sql`, `fis_admin_delUserGroup.sql` — write-side group procs. ## Related decisions - [0021 — User group management (new module, closed the missing intranet_admin gate)](../Decisions/0021-user-group-management.md) - [0014 — Admin user management (dual auth axis, original decisions)](../Decisions/0014-admin-user-management.md) - [0015 — Split Admin into separate Status/User-Management modules](../Decisions/0015-split-admin-user-management-module.md)