← All stories

BRANCH · ef-011-event-info-settings

Event info and settings

EF-011 Persona: Organizer Roots in: event-setup

The organizer edits the canonical event metadata surface: name, time, timezone, URL slug, language, location, waitlist behavior, archive state, and the settings EventFarm historically grouped with revenue, social, card, and duplicate-invitation controls. Voyage already has partial event create/update substrate at workers/events/src/routes/events.ts:60 and workers/events/src/routes/events.ts:79; this story pins the admin contract around what exists and exposes the missing parity as failing probes.

Preconditions

Organizer is authenticated in the event-setup trunk, has edit rights for the event, and the fixture event belongs to the active tenant.

Happy path / Lifecycle

  1. Open Event info from the setup hub.

    The page renders a tabbed settings surface with metadata first: event name, slug, language, timezone, date range, location, waitlist toggle, and archive status.

  2. Edit the metadata and save.

    The form uses the existing event update route, locks while saving, then shows a toast and updates the setup hub title without a reload.

  3. Archive and restore the event.

    Archive is reversible and visually distinct from delete. Archived events remain visible to organizers with a status pill and no public registration affordance.

Failure modes

Permission denied at the right boundary

Trigger: a viewer opens the direct event-info URL or submits the edit form.

Resolution: the route returns 403, the protected metadata payload is not rendered, and the page shows a permission boundary with no event settings leak.

Cross-tenant isolation

Trigger: an organizer from tenant A guesses tenant B's event id.

Resolution: the route returns 404 rather than 403, and no event name, slug, language, or archive state appears in the response.

Soft-delete leaves audit trail

Trigger: organizer deletes the event after confirming the destructive action.

Resolution: the event is tombstoned, not hard-erased inline; the audit table records actor, timestamp, event id, and prior metadata state.

Archive vs delete distinction

Trigger: organizer opens the archive menu.

Resolution: archive copy says reversible and delete copy says destructive; archive can be undone later, while delete requires the destructive confirmation component.

Edit lock during publish

Trigger: event publishing starts while event info has unsaved edits.

Resolution: publish wins deterministically; the form displays a conflict modal saying settings changed while publish began and requires reload or reapply.

Audit row on every state change

Trigger: name, URL slug, language, waitlist, archive, or delete state changes.

Resolution: each state transition writes an audit row; the harness asserts row existence after every successful patch.

Two organizers concurrent

Trigger: two organizers save different event info changes from stale forms.

Resolution: the second save sees an edited-since-you-started warning; no silent overwrite is accepted.

Undo window for destructive actions

Trigger: organizer archives or deletes the event.

Resolution: a toast provides a 10 second undo window; undo restores the prior state and writes its own audit row.

Social and revenue fields missing parity

Trigger: organizer expects social handles, accepted-card settings, duplicate invitation flags, or revenue snapshot controls.

Resolution: the story requires a visible parity gap panel until those settings exist, grounded in the matrix gap notes for EF-011.

Slug collision

Trigger: organizer changes the public URL slug to one already used in the tenant.

Resolution: inline validation blocks save, preserves input, and offers available alternatives without leaking slugs from other tenants.

Stable test attributes

Visibility teeth. Each attribute must be effectively visible when its applicable state is active.

data-testWherePurpose
event-info-pageEvent info routeRoot settings surface
event-info-formInside event-info-pageMetadata edit form
event-info-name-inputInside event-info-formEvent name
event-info-slug-inputInside event-info-formPublic URL slug
event-info-language-pickerInside event-info-formLanguage control
event-info-date-rangeInside event-info-formDate/time window
event-info-save-ctaInside event-info-formSave action
event-info-archive-ctaDanger zoneReversible archive
event-info-delete-ctaDanger zoneDestructive delete
event-info-undo-toastToast regionUndo destructive action
event-info-permission-deniedPermission state403 boundary
event-info-parity-gap-panelSettings pageMissing EF-011 settings

Agent test plan

- event-info-renders
- event-info-save-updates-metadata
- event-info-archive-and-restore
- 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
- missing-settings-gap-visible
- slug-collision-inline