# Feature Specification: Bookmark an Event **Feature**: `011-bookmark-event` **Created**: 2026-03-06 **Status**: Draft **Source**: Migrated from spec/userstories.md > **Note on directory naming**: The migration task list labeled this directory `us-06-calendar-export`, but US-6 in userstories.md is "Bookmark an event". Calendar export is US-8. The directory was created with the correct name reflecting the actual story content. ## User Scenarios & Testing ### User Story 1 - Bookmark an event without RSVP (Priority: P1) A guest who has opened an event page wants to save it for later without committing to attendance. They activate a "Remember" / "Follow" action on the event page. The event token, title, and date are stored in localStorage — no server request is made. The bookmark persists across browser sessions on the same device. The guest can unfollow by activating the action again. **Why this priority**: Core bookmarking capability — without this, the entire feature has no value. **Independent Test**: Can be fully tested by visiting an event page, activating the bookmark action, closing the browser, and reopening to verify persistence. Delivers value by enabling the local event overview (US-7) to display bookmarked events. **Acceptance Scenarios**: 1. **Given** a guest has opened an event page, **When** they activate the "Remember" / "Follow" action, **Then** the event token, title, and date are stored in localStorage and no server request is made. 2. **Given** a guest has bookmarked an event, **When** they close and reopen the browser, **Then** the bookmark is still present in localStorage. 3. **Given** a guest has bookmarked an event, **When** they activate the bookmark action again, **Then** the bookmark is removed from localStorage ("unfollow") without any server contact. 4. **Given** a guest has bookmarked an event, **When** the event page is loaded again, **Then** the bookmark action reflects the current bookmarked state. --- ### User Story 2 - Bookmark is independent of RSVP state (Priority: P2) A guest who has already RSVPed to an event on their device can still explicitly bookmark or un-bookmark the event. The bookmark state is tracked separately from RSVP state. **Why this priority**: Important for correctness but not the primary use case. The primary scenario is the undecided guest who wants to remember without committing. **Independent Test**: Can be tested by RSVPing to an event and then toggling the bookmark action — both states persist independently in localStorage. **Acceptance Scenarios**: 1. **Given** a guest has RSVPed "attending" on this device, **When** they activate the bookmark action, **Then** the bookmark is stored independently and the RSVP state is unaffected. 2. **Given** a guest has bookmarked an event and RSVPed, **When** they remove the bookmark, **Then** the RSVP state is unaffected. --- ### User Story 3 - Bookmark available on expired events (Priority: P2) A guest who is viewing an event that has passed its expiry date can still bookmark it, so it remains visible in their local event overview (US-7). **Why this priority**: Edge case that ensures continuity of the local overview even for past events. **Independent Test**: Can be tested by visiting an expired event page and verifying the bookmark action is present and functional. **Acceptance Scenarios**: 1. **Given** an event has passed its expiry date, **When** a guest views the event page, **Then** the bookmark action is still shown and functional. 2. **Given** a guest bookmarks an expired event, **When** they view their local event overview (US-7), **Then** the event appears in the list marked as ended. --- ### Edge Cases - What happens when the event title or date changes after bookmarking? Locally cached title and date may become stale if the organizer edits the event — this is an accepted trade-off. Cached values are refreshed when the guest next visits the event page. - How does the app handle localStorage being unavailable (e.g. private browsing in some browsers)? [NEEDS EXPANSION] - What happens if the guest bookmarks the same event from multiple devices? Each device maintains its own independent bookmark — no server-side sync. ## Requirements ### Functional Requirements - **FR-001**: The event page MUST display a "Remember" / "Follow" action accessible to any visitor holding the event link. - **FR-002**: Activating the bookmark action MUST store the event token, event title, and event date in localStorage with no server request. - **FR-003**: The bookmark MUST persist across browser sessions on the same device. - **FR-004**: A second activation of the bookmark action MUST remove the bookmark ("unfollow") with no server contact. - **FR-005**: The bookmark state MUST be independent of the RSVP state — both can coexist for the same event on the same device. - **FR-006**: The bookmark action MUST remain available on event pages where the event has expired. - **FR-007**: No personal data, IP address, or identifier MUST be transmitted to the server when bookmarking or un-bookmarking. - **FR-008**: The bookmark action MUST reflect the current state (bookmarked / not bookmarked) when the event page loads. ### Key Entities - **Bookmark record** (localStorage): Stored per event token. Contains: event token, event title, event date. Indicates the guest has explicitly bookmarked this event without RSVPing. Independent of the RSVP record. ## Success Criteria ### Measurable Outcomes - **SC-001**: A guest can bookmark an event and find it in their local overview (US-7) without any server contact at any point in the bookmark flow. - **SC-002**: Bookmarking and un-bookmarking produce no network requests (verifiable via browser DevTools). - **SC-003**: A bookmark persists after browser restart on the same device. - **SC-004**: The bookmark state is correctly reflected on the event page across multiple sessions. - **SC-005**: Guests with existing RSVPs on this device can independently toggle the bookmark without affecting their RSVP state.