# Feature Specification: Create an Event

**Feature**: `006-create-event`
**Created**: 2026-03-06
**Status**: Approved
**Source**: Migrated from spec/userstories.md

## User Scenarios & Testing

### User Story 1 - Create Event with Required Fields (Priority: P1)

An event organizer fills in the event creation form with a title, date/time, and mandatory expiry date, submits it, and is redirected to the new event page. The server returns both an event token and an organizer token. The organizer token is stored in localStorage on the current device.

**Why this priority**: Core action of the entire application. All other stories depend on event creation existing. Without it, there is nothing to view, RSVP to, or manage.

**Independent Test**: Can be fully tested by submitting the creation form and verifying the redirect to the event page, localStorage state, and the server-side persistence.

**Acceptance Scenarios**:

1. **Given** the organizer opens the event creation form, **When** they fill in title, date/time, and expiry date and submit, **Then** the server stores the event and returns a UUID event token and a separate UUID organizer token in the response.
2. **Given** the event is created successfully, **When** the organizer is redirected, **Then** they land on the event page identified by the event token.
3. **Given** the event is created successfully, **When** the organizer token is received, **Then** it is stored in localStorage to grant organizer access on this device.
4. **Given** the event is created successfully, **When** the response is processed, **Then** the event token, title, and date are also stored in localStorage so the local event overview (US-7) can display the event without server contact.
5. **Given** the event creation form, **When** it is opened, **Then** no account, login, or personal data is required.

---

### User Story 2 - Optional Fields (Priority: P2)

An organizer can optionally provide a description and location when creating an event. These fields are not required but are stored alongside the event when provided.

**Why this priority**: Enriches the event page but does not block the core creation flow.

**Independent Test**: Can be tested by creating an event with and without description/location, verifying both cases result in a valid event.

**Acceptance Scenarios**:

1. **Given** the creation form, **When** the organizer leaves description and location blank and submits, **Then** the event is created successfully without those fields.
2. **Given** the creation form, **When** the organizer fills in description and location and submits, **Then** the event is created and those fields are stored.

---

### User Story 3 - Expiry Date Validation (Priority: P2)

The expiry date field is mandatory and must be set to a date in the future. The organizer cannot submit the form without providing it, and cannot set a past date.

**Why this priority**: Mandatory expiry is a core privacy guarantee (linked to US-12 data deletion). The field must always be valid at creation time.

**Independent Test**: Can be tested by attempting to submit the form without an expiry date, or with a past expiry date, and verifying the form is rejected with a clear validation message.

**Acceptance Scenarios**:

1. **Given** the creation form, **When** the organizer attempts to submit without an expiry date, **Then** the submission is rejected and the expiry date field is flagged as required.
2. **Given** the creation form, **When** the organizer enters a past date as the expiry date and submits, **Then** the submission is rejected with a clear validation message.
3. **Given** the creation form, **When** the organizer enters a future date as the expiry date and submits, **Then** the event is created successfully.

---

### Edge Cases

- What happens when the organizer submits the form with only whitespace in the title?
- How does the system handle the expiry date set to exactly today (midnight boundary)?
- What if localStorage is unavailable or full when storing the organizer token?
- What happens if the server returns an error during event creation (network failure, server error)?

## Requirements

### Functional Requirements

- **FR-001**: System MUST accept event creation with: title (required), description (optional), date and time (required), location (optional), expiry date (required).
- **FR-002**: System MUST reject event creation if title is missing.
- **FR-003**: System MUST reject event creation if date/time is missing.
- **FR-004**: System MUST reject event creation if expiry date is missing or is not in the future.
- **FR-005**: System MUST generate a unique, non-guessable UUID event token upon successful event creation.
- **FR-006**: System MUST generate a separate unique, non-guessable UUID organizer token upon successful event creation.
- **FR-007**: System MUST return both tokens in the creation response.
- **FR-008**: Frontend MUST store the organizer token in localStorage to grant organizer access on the current device.
- **FR-009**: Frontend MUST store the event token, title, and date in localStorage alongside the organizer token.
- **FR-010**: Frontend MUST redirect the organizer to the event page after successful creation.
- **FR-011**: System MUST NOT require any account, login, or personal data to create an event.
- **FR-012**: The event MUST NOT be discoverable except via its direct link (no public listing).

### Key Entities

- **Event**: Represents a scheduled gathering. Key attributes: event token (UUID, public), organizer token (UUID, secret), title, description, date/time, location, expiry date, creation timestamp.
- **Organizer Token**: A secret UUID stored in localStorage on the device where the event was created. Used to authenticate organizer actions on that device.
- **Event Token**: A public UUID embedded in the event URL. Used by guests to access the event page.

## Success Criteria

### Measurable Outcomes

- **SC-001**: An organizer can complete the event creation form and be redirected to the new event page in a single form submission.
- **SC-002**: After creation, the organizer token and event metadata are present in localStorage on the current device.
- **SC-003**: An event created without description or location renders correctly on the event page without errors.
- **SC-004**: Submitting the form with a missing or past expiry date displays a clear, user-readable validation error.
- **SC-005**: The event is not accessible via any URL other than the one containing the event token.
