← All stories

BRANCH · ef-005-address-book-groups

Address Book groups

EF-005Persona: Organizer adminRoots in: admin-shell-accessMatrix: Partial

Group invite and import preview exist for event guests, but reusable Address Book group management still needs template parity, duplicate/error downloadable reports, and account-level CRUD. Tier-3 tightening: the bulk upload path now references ui-csv-import-flow as its compound import foundation.

Preconditions

Organizer admin can access Address Book groups; fixtures include a reusable group, CSV import with duplicates, and an import job with row-level errors.

Happy path

  1. Open Address Book groups.

    The page lists reusable groups with member counts, status, and latest activity.

  2. Create or edit a group.

    Organizer names the group, edits membership, and confirms that nested groups are not supported by contract.

  3. Bulk upload contacts into a group.

    CSV preview validates rows, starts an async import, and exposes duplicate/error reports once available.

Failure modes

Permission denied at the right boundary

Trigger: viewer modifies group membership.

Resolution: 403 and no member PII leak beyond role scope.

Cross-tenant isolation

Trigger: tenant A user guesses tenant B group id.

Resolution: 404 masks group existence.

Soft-delete leaves audit trail

Trigger: organizer deletes a reusable group.

Resolution: group is soft-deleted with actor, timestamp, member count, and prior state.

Archive vs delete distinction

Trigger: organizer archives a group versus deletes it.

Resolution: archived group is hidden from default invite pickers but restorable; delete requires confirmation.

Edit lock during concurrent operations

Trigger: import job updates membership while organizer edits the same group.

Resolution: save receives conflict modal or deterministic import-wins warning.

Audit log row on every state change

Trigger: group create, rename, archive, delete, membership edit, or import commit.

Resolution: group audit row records before/after and import job id where relevant.

Two organizers concurrent

Trigger: two admins edit membership in the same reusable group.

Resolution: version conflict or merge summary makes final membership deterministic.

Undo window for destructive actions

Trigger: group archive, delete, or bulk member removal.

Resolution: 10 second undo restores group metadata and membership.

Nested group unsupported

Trigger: organizer attempts to add a group as a member of another group.

Resolution: UI blocks the action with explicit contract copy; no recursive group state is created.

CSV duplicate report missing

Trigger: import preview finds duplicate rows or existing contacts.

Resolution: gap panel remains until downloadable duplicate report exists.

CSV error report missing

Trigger: import job rejects invalid rows.

Resolution: gap panel remains until downloadable error report exists.

Capability gap: reusable group management incomplete

Trigger: matrix marks EF-005 partial.

Resolution: visible gap panel remains until template parity, reports, and reusable group CRUD ship.

Stable test attributes

Visibility teeth. Each attribute must be effectively visible when active.

address-book-groups-pagePageGroups root
address-book-group-tablePageGroups table
address-book-group-bulk-barToolbarBulk actions
address-book-group-modalModalCreate/edit group
address-book-group-import-previewImportCSV preview
address-book-group-import-jobImportAsync job tracker
address-book-group-toastToastSave/import feedback
address-book-group-gap-panelPagePartial gap
address-book-group-duplicate-reportImportDuplicate report
address-book-group-error-reportImportError report
address-book-group-nested-warningModalNested unsupported
address-book-group-undo-toastToastUndo destructive action

Agent test plan

- groups-table-renders
- group-create-or-edit
- group-csv-import-preview
- permission-denied-boundary
- cross-tenant-404
- soft-delete-audit
- archive-delete-distinction
- import-edit-lock
- audit-row-every-change
- concurrent-organizers-conflict
- destructive-undo-window
- nested-group-unsupported
- duplicate-report-gap
- error-report-gap
- groups-gap-probe
- evaluate-address-book-groups