# Implementation Plan: Watch Event **Branch**: `017-watch-event` | **Date**: 2026-03-12 | **Spec**: [spec.md](spec.md) **Input**: Feature specification from `/specs/017-watch-event/spec.md` ## Summary Add a bookmark icon to the event detail page (left of event title) that lets users save events to localStorage without RSVPing. Watched events appear in the event list with a "Watching" label. The feature is entirely client-side — no backend changes required. ## Technical Context **Language/Version**: TypeScript 5.9 (frontend only) **Primary Dependencies**: Vue 3, Vue Router 5 **Storage**: localStorage via `useEventStorage.ts` composable (existing) **Testing**: Vitest for unit tests, Playwright + MSW for E2E **Target Platform**: Mobile-first PWA (browser) **Project Type**: Web application (frontend-only change) **Performance Goals**: Instant toggle (no network requests) **Constraints**: No backend involvement, no new dependencies **Scale/Scope**: 4 modified files, 0 new files ## Constitution Check *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* | Principle | Status | Notes | |-----------|--------|-------| | I. Privacy by Design | PASS | No data sent to server. Watch is purely localStorage. No tracking. | | II. Test-Driven Methodology | PASS | Unit tests for composable changes, E2E tests for user stories. | | III. API-First Development | PASS | No API changes needed. Feature is client-side only. | | IV. Simplicity & Quality | PASS | Minimal changes to existing code. No new abstractions. | | V. Dependency Discipline | PASS | No new dependencies introduced. | | VI. Accessibility | PASS | Bookmark icon will use semantic button/ARIA, keyboard-operable. | No violations. Gate passes. ## Project Structure ### Documentation (this feature) ```text specs/017-watch-event/ ├── plan.md # This file ├── spec.md # Feature specification ├── research.md # Phase 0 output ├── data-model.md # Phase 1 output ├── quickstart.md # Phase 1 output └── tasks.md # Phase 2 output (/speckit.tasks) ``` ### Source Code (files to modify) ```text frontend/src/ ├── composables/ │ ├── useEventStorage.ts # Add saveWatch(), isStored() methods │ └── __tests__/ │ └── useEventStorage.spec.ts # Tests for new methods ├── components/ │ ├── EventCard.vue # Add 'watcher' role + badge styling │ ├── EventList.vue # Update getRole() to return 'watcher', adjust delete flow │ └── __tests__/ │ ├── EventCard.spec.ts # Tests for watcher badge │ └── EventList.spec.ts # Tests for watcher delete behavior ├── views/ │ ├── EventDetailView.vue # Add bookmark icon next to title │ └── __tests__/ │ └── EventDetailView.spec.ts # Tests for bookmark behavior └── e2e/ └── watch-event.spec.ts # E2E tests for all user stories ``` **Structure Decision**: Frontend-only changes. No new files needed — all modifications go into existing components and composables. One new E2E test file. ## Complexity Tracking No constitution violations. No complexity justifications needed.