Preconditions
Organizer is on the event-setup hub for an editable event in the active tenant.
Happy path / Lifecycle
Open Access Types and create a new type.
The form starts with distribution and transaction type, then reveals price, capacity, availability, FCFS, transferability, and sort controls.
Save and sort the list.
The list updates in place with status pills and the new sort order, backed by the existing access-types route.
Archive an inactive type.
Archive hides it from public selection but keeps historical guest associations and audit history.
Failure modes
Permission denied at the right boundary
Trigger: viewer submits an access-type mutation.
Resolution: server returns 403, form data is not persisted, and no protected access-type inventory leaks.
Cross-tenant isolation
Trigger: tenant A user opens tenant B access-type id.
Resolution: response is 404, not 403, with no name, price, capacity, or distribution details.
Soft-delete leaves audit trail
Trigger: organizer deletes a draft access type.
Resolution: row is tombstoned and audit captures actor, timestamp, prior state, and affected event.
Archive vs delete distinction
Trigger: organizer opens row actions.
Resolution: archive remains reversible for hidden inventory; delete is destructive and disabled once guests are associated.
Edit lock during publish
Trigger: event publish begins while access type edits are open.
Resolution: publish wins; save shows a conflict modal and does not mutate published inventory silently.
Audit row on every state change
Trigger: distribution, price, capacity, transferability, FCFS, availability, archive, or sort changes.
Resolution: every successful mutation writes an access-type audit row.
Two organizers concurrent
Trigger: two organizers edit price/capacity at the same time.
Resolution: stale save receives conflict UI; both sessions refresh to the final persisted state.
Undo window for destructive actions
Trigger: archive or delete action succeeds.
Resolution: a 10 second undo toast restores the prior access-type state and logs the restoration.
Payment settlement parity gap
Trigger: organizer configures a paid access type.
Resolution: pricing can be saved, but settlement behavior remains called out as a parity gap until payments stories cover it.
Public display parity gap
Trigger: organizer marks an access type transferable or public.
Resolution: admin state persists; public transfer/display parity is exposed as an implementation gap, not silently asserted as complete.
Sort collision
Trigger: two rows are dragged into the same order slot.
Resolution: server normalizes deterministic sort order and both sessions see the same list.
Stable test attributes
Visibility teeth. Each attribute must be effectively visible when active.
| data-test | Where | Purpose |
|---|---|---|
access-types-page | Access types route | Root list |
access-type-new-cta | Toolbar | Create action |
access-type-form | Create/edit modal | Validated form |
access-type-distribution-picker | Form | Distribution selector |
access-type-price-input | Form | Price |
access-type-capacity-stepper | Form | Capacity |
access-type-transferable-checkbox | Form | Transferability |
access-type-fcfs-checkbox | Form | FCFS toggle |
access-type-save-cta | Form | Save action |
access-type-row | Table | Each access type |
access-type-status-pill | Row | Active/archived status |
access-type-undo-toast | Toast region | Undo destructive action |
access-type-conflict-modal | Modal portal | Concurrent conflict |
access-type-parity-gap-panel | Page | Missing EF parity |
Agent test plan
- access-types-renders
- create-access-type
- archive-access-type
- permission-denied-boundary
- cross-tenant-404
- soft-delete-audit
- archive-delete-distinction
- publish-edit-lock
- audit-row-every-change
- concurrent-organizers-conflict
- destructive-undo-window
- payment-settlement-gap
- public-display-gap
- sort-collision-normalizes