Public event detail page at /events/:token — guests view event info via shared link
Backend: GET /api/events/{token} endpoint, timezone field added to Event model (cross-cutting to US-1)
Frontend: EventDetailView.vue with five states: loading (skeleton shimmer), loaded, expired, not-found, server error (retry)
Date/time formatted via Intl.DateTimeFormat with browser locale and IANA timezone label
Changes
Backend
OpenAPI: GET /events/{token} + GetEventResponse schema, timezone on create request/response
Liquibase: timezone VARCHAR(64) NOT NULL DEFAULT 'UTC' column
New GetEventUseCase inbound port, implemented in EventService
Controller computes expired flag (expiryDate vs server clock) and attendeeCount (hardcoded 0 until RSVP)
Integration tests refactored: DTOs + ObjectMapper instead of inline JSON, GET tests seed DB directly via JpaRepository
Frontend
EventDetailView.vue with openapi-fetch, skeleton shimmer (CSS-only), retry on error
Router: /events/:token route
Create form sends auto-detected timezone
Unit tests (Vitest) for all five view states
E2E tests (Playwright + MSW) for loaded, expired, not-found, server error
Test plan
Backend: 38 tests pass (./mvnw verify — includes checkstyle)
Frontend unit: 30 tests pass
Frontend E2E: 13 tests pass
## Summary
- Public event detail page at `/events/:token` — guests view event info via shared link
- Backend: `GET /api/events/{token}` endpoint, `timezone` field added to Event model (cross-cutting to US-1)
- Frontend: `EventDetailView.vue` with five states: loading (skeleton shimmer), loaded, expired, not-found, server error (retry)
- Date/time formatted via `Intl.DateTimeFormat` with browser locale and IANA timezone label
## Changes
### Backend
- OpenAPI: `GET /events/{token}` + `GetEventResponse` schema, `timezone` on create request/response
- Liquibase: `timezone VARCHAR(64) NOT NULL DEFAULT 'UTC'` column
- New `GetEventUseCase` inbound port, implemented in `EventService`
- Controller computes `expired` flag (expiryDate vs server clock) and `attendeeCount` (hardcoded 0 until RSVP)
- Integration tests refactored: DTOs + ObjectMapper instead of inline JSON, GET tests seed DB directly via JpaRepository
### Frontend
- `EventDetailView.vue` with openapi-fetch, skeleton shimmer (CSS-only), retry on error
- Router: `/events/:token` route
- Create form sends auto-detected timezone
- Unit tests (Vitest) for all five view states
- E2E tests (Playwright + MSW) for loaded, expired, not-found, server error
## Test plan
- [x] Backend: 38 tests pass (`./mvnw verify` — includes checkstyle)
- [x] Frontend unit: 30 tests pass
- [x] Frontend E2E: 13 tests pass
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>
OpenAPI: new GetEventResponse schema, timezone on Create request/response.
Liquibase: add timezone VARCHAR(64) NOT NULL DEFAULT 'UTC' column.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Domain: add timezone field to Event and CreateEventCommand.
Ports: new GetEventUseCase inbound port.
Service: implement getByEventToken, validate IANA timezone on create.
Controller: map to GetEventResponse, compute expired flag via Clock.
Persistence: timezone column in JPA entity and mapping.
Tests: integration tests use DTOs + ObjectMapper instead of inline JSON,
GET tests seed DB directly via JpaRepository for isolation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New view fetches event via openapi-fetch, formats date/time with
Intl.DateTimeFormat. Skeleton shimmer during loading (CSS-only).
Create form now sends auto-detected timezone.
Unit tests for all five view states, E2E tests with MSW mocks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add missing timezone field to CreateEventResponse mock
- Fix createTestRouter signature to accept optional token parameter
- Add non-null assertion for dateField element access
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The hook used --noEmit which is less strict than CI's --build,
causing type errors to slip through.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
nitrix
scheduled this pull request to auto merge when all checks succeed 2026-03-06 22:55:02 +01:00
nitrix
merged commit 5f50ea991b into master2026-03-06 22:57:04 +01:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
/events/:token— guests view event info via shared linkGET /api/events/{token}endpoint,timezonefield added to Event model (cross-cutting to US-1)EventDetailView.vuewith five states: loading (skeleton shimmer), loaded, expired, not-found, server error (retry)Intl.DateTimeFormatwith browser locale and IANA timezone labelChanges
Backend
GET /events/{token}+GetEventResponseschema,timezoneon create request/responsetimezone VARCHAR(64) NOT NULL DEFAULT 'UTC'columnGetEventUseCaseinbound port, implemented inEventServiceexpiredflag (expiryDate vs server clock) andattendeeCount(hardcoded 0 until RSVP)Frontend
EventDetailView.vuewith openapi-fetch, skeleton shimmer (CSS-only), retry on error/events/:tokenrouteTest plan
./mvnw verify— includes checkstyle)