# Milestone 04 — Guest RSVP and Invitation Language ## Reference Read `plans/wedding-bootstrap-plan.md` first. This milestone depends on Milestones 01 and 03. Admin auth from Milestone 02 should already protect admin pages. ## Goal Build the guest-facing `/invite/[token]` flow with localized copy based on `invitations.language`, per-member attendance, per-member meal/dietary fields, group logistics, and deadline behavior. ## Scope Implement only: - `/invite/[token]` page. - Invalid invitation handling. - Localization dictionary foundation for guest-facing copy. - Per-member RSVP form. - Group logistics form. - Save/update `invitation_members` attendance/meal/dietary fields. - Save/update `invitation_responses` logistics and `submitted_at`. - RSVP deadline read-only behavior. - Admin visibility of submitted RSVP data if not already present. ## Non-goals Do not implement: - MinIO photo upload. - Song requests. - Toast requests. - Guest messages. - Advanced final visual design. - New admin component libraries. ## Required constraints - `invitations.language` is the source of truth for guest-facing language. - Do not rely only on browser language detection. - `invitation_members.attending` is the source of truth for attendance. - Do not store duplicate attendance status on `invitation_responses`. - Edits are allowed until `RSVP_DEADLINE`. - After the deadline, guest RSVP data is read-only. - Guest-facing design may be custom; shadcn-only restriction applies to admin pages. ## Implementation tasks - Add `lib/i18n/config.ts` with supported languages. - Add translation dictionaries under `lib/i18n/dictionaries/`. - Add helper to resolve dictionary by invitation language. - Add response/member validation schemas. - Add query helpers for: - find invitation by token with members/response - update member RSVP fields - upsert invitation response - Implement `/invite/[token]`. - Add form handling using current Next.js best practice. - Add deadline helper. - Ensure admin detail/list can show derived RSVP status and submitted response data. ## Localized guest copy must include - Page headings. - RSVP labels. - Meal/dietary labels. - Travel/logistics labels. - Validation messages. - Submit/success/error messages. - Deadline/read-only messages. ## Verification Run: ```bash npm run lint npm run build ``` Manual checks: - Invalid token shows a friendly invalid invitation page. - Valid token shows personalized invitation. - Page renders using the invitation's configured language. - Different members can have different attendance values. - Different members can have different meal preferences/dietary restrictions. - Group logistics save correctly. - `submitted_at` is set after submission. - Admin can see submitted RSVP data. - After deadline, guest form is read-only. ## Acceptance criteria - Guest RSVP MVP works end-to-end. - Localization is driven by invitation language. - Attendance is stored only per member. - No upload or optional interaction features were implemented yet.