Migrate project artifacts to spec-kit format

- Move cross-cutting docs (personas, design system, implementation phases,
  Ideen.md) to .specify/memory/
- Move cross-cutting research and plans to .specify/memory/research/ and
  .specify/memory/plans/
- Extract 5 setup tasks from spec/setup-tasks.md into individual
  specs/001-005/spec.md files with spec-kit template format
- Extract 20 user stories from spec/userstories.md into individual
  specs/006-026/spec.md files with spec-kit template format
- Relocate feature-specific research and plan docs into specs/[feature]/
- Add spec-kit constitution, templates, scripts, and slash commands
- Slim down CLAUDE.md to Claude-Code-specific config, delegate principles
  to .specify/memory/constitution.md
- Update ralph.sh with stream-json output and per-iteration logging
- Delete old spec/ and docs/agents/ directories
- Gitignore Ralph iteration JSONL logs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 20:19:41 +01:00
parent 0b2b84dafc
commit 6aeb4b8bca
83 changed files with 6486 additions and 660 deletions

View File

@@ -0,0 +1,90 @@
# 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.