Every 'read-only placeholder' and 'missing functionality' gap from the
QA audit is now resolved:
COURSES — categories/instructors/locations can now be deleted:
- Added update/delete methods to course-reference-data.service.ts
- Added deleteCategory/deleteInstructor/deleteLocation server actions
- Created DeleteRefDataButton client component with confirmation dialog
- Wired delete buttons into all three table pages
BOOKINGS — calendar month navigation now works:
- Calendar was hardcoded to current month with disabled prev/next
- Added year/month search params for server-side month rendering
- Replaced disabled buttons with Link-based navigation
- Verified: clicking next/prev correctly renders different months
DOCUMENTS — templates page now reads from database:
- Was hardcoded empty array; now queries document_templates table
- Table exists since migration 20260414000006_shared_templates.sql
FISCHEREI — statistics page shows real data:
- Replaced dashed-border placeholder with 6 real stat cards
- Queries waters, species, stocking, catch_books, leases, permits
- Shows counts + stocking costs + pending catch books
- Falls back to helpful message when no data exists
VERBAND — statistics page shows real KPIs:
- Added server-side data fetching (clubs, members, fees)
- Passes activeClubs, totalMembers, openFees as props
- Added 4 KPI cards: Aktive Vereine, Gesamtmitglieder,
∅ Mitglieder/Verein, Offene Beiträge
- Kept existing trend charts below KPI cards
Every module had buttons that rendered visually but did nothing when
clicked. Server actions existed for all of them. Created client
components with dialogs/forms and wired them in.
BOOKINGS MODULE:
- BookingStatusActions: Check-in/Check-out/Cancel buttons now call
updateBookingStatus server action with loading states + toast
- CreateRoomDialog: 'Neues Zimmer' opens dialog with room number,
name, capacity, price/night fields → calls createRoom
- CreateGuestDialog: 'Neuer Gast' opens dialog with first/last name,
email, phone fields → calls createGuest
COURSES MODULE:
- EnrollParticipantDialog: 'Teilnehmer anmelden' on participants
page opens dialog with first/last name, email, phone → calls
enrollParticipant
EVENTS MODULE:
- EventRegistrationDialog: 'Anmeldung' button on event detail opens
dialog with participant data + DOB → calls registerForEvent
- CreateHolidayPassDialog: 'Neuer Ferienpass' opens dialog with name,
year, description, price, date range → calls createHolidayPass
NEWSLETTER MODULE:
- CreateTemplateDialog: 'Neue Vorlage' opens dialog with name,
subject, HTML body → calls createTemplate
SITE-BUILDER MODULE:
- Posts 'Neuer Beitrag' button now links to /posts/new page
All dialogs use German labels, helpful placeholders, loading spinners,
toast notifications, and form validation appropriate for association
board members (Vereinsvorstände, 40-65, moderate tech skills).
- fix(member-management): Zod v4 .partial() on refined schema crash
Separated CreateMemberBaseSchema from superRefine so .partial()
works for UpdateMemberSchema. Fixes members-cms page crash.
- fix(course-management): snake_case→camelCase stats normalization
getQuickStats RPC returns snake_case keys but templates expect
camelCase. Added normalization layer so stats cards display values.
- fix(blog): add missing cover images for 5 German blog posts
Posts referenced /images/posts/*.webp that didn't exist.
- fix(docker): remove non-existent catch_entries table from bootstrap
dev-bootstrap.sh granted permissions on catch_entries which has no
migration. Removed the stale reference.
- docs: add qa-checklist.md with full test report
The previous lint fix incorrectly renamed ctx to _ctx in server actions
that actually USE ctx.user.id for authorization. This caused runtime
'ctx is not defined' errors when creating pages, modules, etc.
Reverted all 13 action files back to using ctx properly.
Course and event creation Server Actions were failing with 'Something went
wrong' because empty form strings ('') were being inserted into date/uuid
columns which reject empty strings. Now converts '' to null for all
optional fields (dates, descriptions, IDs, contact info).