feat: registration section preferences with show_in_registration filtering and deduplication

Add show_in_registration and registration_description columns to festival_sections.
Registration form now shows deduplicated sections by name (across sub-events),
filtered by show_in_registration=true, grouped by category with card-based UI.
Section preferences use section_name instead of section_id.
Add GET/PUT registration-settings endpoints for festival-level bulk management.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-10 20:03:54 +02:00
parent 3400e4cc7e
commit c21bc085e9
22 changed files with 1443 additions and 104 deletions

View File

@@ -102,6 +102,43 @@ Returns 422 with `errors`, `current_status`, `requested_status`, and `allowed_tr
> Shifts on cross_event sections must use the **parent festival's event_id** in API calls,
> since the section's `event_id` points to the parent.
### Registration Settings (Festival-level bulk management)
- `GET /events/{event}/sections/registration-settings` — returns unique section names across the festival with registration visibility, description, and counts
- `PUT /events/{event}/sections/registration-settings` — bulk update registration visibility for a section name across all instances in the festival
#### GET Response
```json
{
"data": [
{
"name": "Hoofdpodium Bar",
"category": "Bar",
"icon": "tabler-beer",
"show_in_registration": true,
"registration_description": "Tap bier en drankjes voor festivalgangers",
"section_count": 3,
"section_ids": ["ulid1", "ulid2", "ulid3"]
}
]
}
```
#### PUT Body
```json
{
"name": "Hoofdpodium Bar",
"show_in_registration": true,
"registration_description": "Tap bier en drankjes voor festivalgangers"
}
```
Returns the full updated registration-settings response. Creates activity log `section.registration_settings_updated`.
Auth: org_admin or event_manager on the event's organisation.
## Time Slots
- `GET /events/{event}/time-slots`
@@ -391,7 +428,7 @@ Response: `{ "confirmed": 2, "errors": [{ "match_id": "ulid3", "error": "User al
## Public Registration Data
- `GET /public/events/{slug}/registration-data` — public, no auth. Returns event info, available sections, and volunteer time slots for the registration form. Only returns events with status `registration_open`. Excludes `cross_event` sections. Only includes time slots with `person_type = VOLUNTEER`. Resolves sub-events to parent festival.
- `GET /public/events/{slug}/registration-data` — public, no auth. Returns event info, available sections, and volunteer time slots for the registration form. Only returns events with status `registration_open`. Only includes sections with `show_in_registration = true` and `type = standard`. For festivals: returns child event sections only (deduplicated by name), excluding parent operational sections. Only includes time slots with `person_type = VOLUNTEER`. Resolves sub-events to parent festival.
### Response
@@ -399,7 +436,7 @@ Response: `{ "confirmed": 2, "errors": [{ "match_id": "ulid3", "error": "User al
{
"data": {
"event": { "id": "01JXYZ...", "name": "Echt Feesten 2026", "start_date": "2026-07-10", "end_date": "2026-07-12", "organisation_id": "01JXYZ..." },
"sections": [{ "id": "01JXYZ...", "name": "Hoofdpodium Bar", "category": "Bar", "icon": "tabler-glass" }],
"sections": [{ "id": "01JXYZ...", "name": "Hoofdpodium Bar", "category": "Bar", "icon": "tabler-glass", "registration_description": "Tap bier en drankjes voor festivalgangers" }],
"time_slots": [{ "id": "01JXYZ...", "name": "Vrijdag Avond", "date": "2026-07-10", "start_time": "18:00:00", "end_time": "02:00:00", "duration_hours": 8 }]
}
}