# CDA User Lists | Status | Accepted | | :-- | :-- | | **ADR #** | 0013 | | **Author** | Charles Graham | | **Date** | 2026-07-24 | | **Supersedes** | N/A | ## Context CWMS Data API clients need reusable, named collections of existing CWMS users. The collections must expose current user identity data, including names and email addresses, without creating a second user identity store or changing CWMS authorization groups into general-purpose application data. User lists also require an authenticated management interface. Reading a list is useful to any authenticated CWMS user, while changing an office-owned list must remain an office administration operation. ## Decision CDA exposes office-scoped user lists backed by the CWMS database objects `AT_USER_LISTS`, `AT_USER_LIST_MEMBERS`, and `AV_USER_LIST_MEMBERS`. Membership references existing `AT_SEC_CWMS_USERS` rows. A list is uniquely identified by `(office-id, user-list-id)`. The same `user-list-id` may therefore be used independently by multiple offices, and membership rows carry the same office/list composite key. The REST resource is rooted at `/user/list`: - `GET /user/list?office=...` lists an office's lists. - `POST /user/list` creates a list. - `GET`, `PATCH`, and `DELETE /user/list/{user-list-id}?office=...` manage metadata. - `GET` and `POST /user/list/{user-list-id}/members?office=...` read or add members. - `DELETE /user/list/{user-list-id}/members/{user-id}?office=...` removes a member. Any authenticated principal with the `CWMS Users` role may read list metadata and membership for any office. Mutations require `CWMS User Admins` membership for the office named by the resource. This deliberately permits authenticated CDA clients to resolve current member names and email addresses across offices; user lists must not be used for information that should be hidden from other authenticated CWMS users. CDA sets `owned-by-user-id` to the authenticated user who creates the list. The client cannot provide or change that value. Ownership is immutable audit metadata; it does not bypass or replace office-admin authorization for later mutations. Member `added-by-user-id` audit values are derived the same way. List IDs are normalized to uppercase and limited to 128 letters, numbers, dots, underscores, or hyphens. Descriptions are limited to the database column's 1,024 characters. Duplicate lists and members return a conflict response. The `USER_LISTS` Togglz feature controls route exposure. CDA registers the documented handlers only when the feature is enabled. Requests are also guarded by the minimum CWMS database schema version that contains the user-list objects, so a deployment with an older schema receives an explicit unsupported response. The bundled CDA GUI provides the authenticated management surface. Existing public CDA pages remain public, while the user-list route requires sign-in and renders mutation controls only for offices the user may administer. ## Alternatives Considered ### Reuse CWMS security groups Rejected. Security groups carry authorization semantics, numeric group conventions, and package behavior that do not apply to general-purpose contact lists. ### Store independent user or email records Rejected. Duplicating identity data would drift from CWMS user profiles and require new synchronization behavior. ### Add PL/SQL CRUD packages Rejected for the initial implementation. CDA performs bind-variable SQL through its DAO layer, keeping the resource contract portable and the database objects relational. ## Consequences - List IDs are stable references while member identity and email values remain sourced from CWMS users. - List IDs are unique within an office, not globally. - The creating user remains visible as immutable audit metadata. - Office authorization is enforced by CDA rather than trusted to clients. - Deployments must enable the feature only after installing the required schema. - Future contact fields can be added to the membership view and DTO without changing the core list-to-user relationship. ## Implementation Status The database schema was introduced through CWMS database PR 160. The CDA backend branch implements the resource handlers, schema and feature gating, validation, office-aware authorization, and creator audit behavior described here. The stacked CDA UI branch provides the authenticated management interface.