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:
@@ -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 }]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,6 +295,8 @@ scopeFestivals() // WHERE event_type IN ('festival', 'series')
|
||||
| `crew_accreditation_level` | string nullable | **v1.5** Default accreditation level for crew (e.g. AAA, AA, A) |
|
||||
| `public_form_accreditation_level` | string nullable | **v1.5** Accreditation level for public form registrants |
|
||||
| `timed_accreditations` | bool | **v1.5** Accreditations are time-limited for this section |
|
||||
| `show_in_registration` | bool | **v1.8** Show this section in the volunteer registration form |
|
||||
| `registration_description` | text nullable | **v1.8** Description shown to volunteers in the registration form |
|
||||
| `deleted_at` | timestamp nullable | Soft delete |
|
||||
|
||||
**Relations:** `hasMany` shifts
|
||||
@@ -309,6 +311,7 @@ scopeFestivals() // WHERE event_type IN ('festival', 'series')
|
||||
- `added_to_timeline`: false
|
||||
- `responder_self_checkin`: true
|
||||
- `timed_accreditations`: false
|
||||
- `show_in_registration`: false
|
||||
|
||||
> **Note:** "Overkoepelende" sections (shared across all sub-events of a festival)
|
||||
> are identified by `type = 'cross_event'`. There is no separate `is_shared` boolean
|
||||
|
||||
Reference in New Issue
Block a user