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.