Files
fete/specs/007-view-event/plan.md
nitrix 80d79c3596 Add design artifacts for view event feature (007)
Spec, research, data model, API contract, implementation plan, and
task breakdown for the public event detail page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 22:34:51 +01:00

4.9 KiB

Implementation Plan: View Event Landing Page

Branch: 007-view-event | Date: 2026-03-06 | Spec: spec.md Input: Feature specification from /specs/007-view-event/spec.md

Summary

Add a public event detail page at /events/:token that displays event information (title, date/time with IANA timezone, description, location, attendee count) without requiring authentication. The page handles four states: loaded, expired ("event has ended"), not found (404), and server error (retry button). Loading uses skeleton-shimmer placeholders. Backend adds GET /events/{token} endpoint and a timezone field to the Event model (cross-cutting change to US-1).

Technical Context

Language/Version: Java 25 (backend), TypeScript 5.9 (frontend) Primary Dependencies: Spring Boot 3.5.x, Vue 3, Vue Router 5, openapi-fetch, openapi-typescript Storage: PostgreSQL (JPA via Spring Data, Liquibase migrations) Testing: JUnit (backend), Vitest (frontend unit), Playwright + MSW (frontend E2E) Target Platform: Self-hosted web application (Docker) Project Type: Web service + SPA Performance Goals: N/A (single-user scale, self-hosted) Constraints: No external resources (CDNs, fonts, tracking), WCAG AA, privacy-first Scale/Scope: Single new view + one new API endpoint + one cross-cutting model change

Constitution Check

GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.

Principle Status Notes
I. Privacy by Design PASS No PII exposed. Only attendee count shown (not names). No external resources. No tracking.
II. Test-Driven Methodology PASS TDD enforced: backend unit tests, frontend unit tests, E2E tests per spec.
III. API-First Development PASS OpenAPI spec updated first. Types generated. Response schemas include example: fields.
IV. Simplicity & Quality PASS Minimal changes: one GET endpoint, one new view, one model field. attendeeCount returns 0 (no RSVP stub). Cancelled state deferred.
V. Dependency Discipline PASS No new dependencies. Skeleton shimmer is CSS-only.
VI. Accessibility PASS Semantic HTML, ARIA attributes, keyboard navigable, WCAG AA contrast via design system.

Post-Phase-1 re-check: All gates still pass. The timezone field addition is a justified cross-cutting change documented in research.md R-1.

Project Structure

Documentation (this feature)

specs/007-view-event/
├── plan.md              # This file
├── spec.md              # Feature specification
├── research.md          # Phase 0: research decisions
├── data-model.md        # Phase 1: entity definitions
├── quickstart.md        # Phase 1: implementation overview
├── contracts/
│   └── get-event.yaml   # Phase 1: GET endpoint contract
└── tasks.md             # Phase 2: implementation tasks (via /speckit.tasks)

Source Code (repository root)

backend/
├── src/main/java/de/fete/
│   ├── domain/
│   │   ├── model/Event.java                          # Add timezone field
│   │   └── port/in/GetEventUseCase.java              # NEW: inbound port
│   ├── application/service/EventService.java          # Implement GetEventUseCase
│   ├── adapter/
│   │   ├── in/web/EventController.java               # Implement getEvent()
│   │   └── out/persistence/
│   │       ├── EventJpaEntity.java                    # Add timezone column
│   │       └── EventPersistenceAdapter.java           # Map timezone field
│   └── config/
├── src/main/resources/
│   ├── openapi/api.yaml                               # Add GET endpoint + timezone
│   └── db/changelog/                                  # Liquibase: add timezone column
└── src/test/java/de/fete/                             # Unit + integration tests

frontend/
├── src/
│   ├── api/schema.d.ts                                # Regenerated from OpenAPI
│   ├── views/EventDetailView.vue                      # NEW: event detail page
│   ├── views/EventCreateView.vue                      # Add timezone to create request
│   ├── router/index.ts                                # Point /events/:token to EventDetailView
│   └── assets/main.css                                # Skeleton shimmer styles
├── e2e/
│   └── event-view.spec.ts                             # NEW: E2E tests for view event
└── src/__tests__/                                     # Unit tests for EventDetailView

Structure Decision: Existing web application structure (backend + frontend). No new packages or modules — extends existing hexagonal architecture with one new inbound port and one new frontend view.

Complexity Tracking

No constitution violations. No entries needed.