Commit Graph

15 Commits

Author SHA1 Message Date
52f6380ac0 security: round 3 — token security (crypto random, hashed storage, portal middleware)
Token generation:
- Replace Str::ulid() with bin2hex(random_bytes(32)) for 256-bit entropy
- Store SHA-256 hash in database, never plaintext tokens
- Hash input before lookup on all token endpoints

Invitation tokens:
- InvitationService: generate crypto random, store hash, pass plain
  token transiently for email URL via UserInvitation::$plainToken
- InvitationController show/accept: hash input before DB lookup
- AcceptInvitationRequest: hash token before invitation lookup
- Migration: widen user_invitations.token and artists.portal_token
  from char(26) to char(64) for SHA-256 hex digests

Portal token auth:
- PortalTokenController: remove Schema::hasTable() runtime checks,
  hash token before lookup, return shaped response via PortalEventResource
  instead of raw model data
- Create PortalEventResource (name, dates, status only — no internals)
- Handle missing production_requests table gracefully via try/catch

Portal token middleware:
- Implement full token validation: extract from Bearer header or ?token=
  query param, hash, look up in artists/production_requests, verify
  event exists and is not draft/closed, set portal context on request
- Return generic 401 on any failure (no information leakage)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 06:52:54 +02:00
1028498705 security: round 1 — quick wins (rate limiting, headers, mass assignment, logging)
- Add throttle middleware to login (5/min), portal/token-auth (10/min),
  volunteer-register (5/min), and invitation routes (10/min)
- Set Sanctum token expiration to 7 days
- Remove billing_status from UpdateOrganisationRequest (super_admin only)
- Revoke all Sanctum tokens on password reset
- Strengthen password rules: min 8 chars, mixed case, numbers
- Create SecurityHeaders middleware (X-Content-Type-Options, X-Frame-Options,
  HSTS, Referrer-Policy, Permissions-Policy)
- Fix open redirect on all 3 login pages (validate ?to= starts with /)
- Set APP_DEBUG=false in .env.example
- Log failed login attempts with email, IP, user-agent
- Log authorization failures (403) with user, IP, path, method
- Harden mass assignment: remove user_id from Person, audit fields from
  ShiftAssignment, system fields from UserInvitation $fillable
- Replace real DB records with factory make() in mail preview routes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 01:34:51 +02:00
f6e3568011 feat: registration form fields, section preferences, tag sync & schema updates
Implement EAV system for dynamic event-specific registration fields
with organisation-level templates, person section preferences with
priority ranking, and TagSyncService for deferred tag_picker sync.

New tables: registration_field_templates, registration_form_fields,
person_field_values, person_section_preferences.
New columns: persons.remarks, events.registration_show_section_preferences,
events.registration_show_availability.

58 tests, 126 assertions — all 432 tests pass (zero regressions).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 22:10:16 +02:00
6dccf87234 feat: add date_of_birth field to persons across all layers
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 09:06:29 +02:00
d2f282eb4c feat: split name into first_name + last_name across users, persons, and companies
Cross-cutting migration affecting the entire stack:
- Database: 3 migrations splitting name columns with data migration
- Models: first_name/last_name on User, Person; contact_first_name/contact_last_name on Company; backward-compatible name accessors
- API: all resources return first_name, last_name, full_name; assignablePersons endpoint updated
- Requests: validation rules updated for all person/user/company forms
- Services: VolunteerRegistrationService, ShiftAssignmentService, InvitationService updated
- Frontend: TypeScript types, Zod schemas, all forms split into Voornaam/Achternaam fields
- Display: all person/user name references use full_name; initials use first_name[0]+last_name[0]
- Tests: all 371 tests passing
- Docs: SCHEMA.md and API.md updated

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 23:04:55 +02:00
0cdc192239 feat: shift assignment workflow with claim, approve, reject, cancel, and bulk approve
Implements the complete ShiftAssignment lifecycle:
- ShiftAssignmentStatus enum with allowed transitions
- ShiftAssignmentService with claim/assign/approve/reject/cancel/bulkApprove
- ShiftAssignmentController with event-scoped endpoints
- ShiftAssignmentPolicy (organizer + volunteer self-cancel)
- VolunteerAvailability model, controller, and sync endpoint
- Refactored ShiftController to delegate to service layer
- 31 workflow tests covering all paths and multi-tenancy

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 17:00:56 +02:00
cae2242502 feat: crowd lists audit, enum, factory, service and tests
Audit and complete the Crowd Lists module:
- Add CrowdListType enum (internal/external) with proper casts
- Create CrowdListService for business logic (add/remove person,
  max_persons enforcement, auto_approve, activity logging)
- Create CrowdListFactory with Dutch names and states
- Create AddPersonToCrowdListRequest form request
- Fix FormRequests to use Rule::enum instead of hardcoded strings
- Fix CrowdListResource to use enum->value and add is_full field
- Refactor controller to be thin (delegates to service)
- Add eager loading for crowdType and recipientCompany
- Write 18 comprehensive tests (CRUD, auth, edge cases)
- Update API.md with request/response documentation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 13:53:57 +02:00
4b182b449a feat: person identity matching with detection, confirmation and audit trail
Implements enterprise-grade identity resolution (detect → suggest → confirm)
for Person ↔ User linking. Matches are detected automatically on person
creation and user account creation, then surfaced to organisers for explicit
confirmation or dismissal. No silent auto-linking.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 12:50:25 +02:00
d37a45b028 feat: person tags system - org-level skills with self-reported and organiser-assigned sources
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 11:15:43 +02:00
10bd55b8ae feat: festival/series model with sub-events, cross-event sections, tab navigation, SectionsShiftsPanel extraction
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 11:15:19 +02:00
c776331cf8 feat: festival/event model frontend + topbar activeren
- Events lijst: card grid met festival/serie chips
- Festival detail: programmaonderdelen grid
- CreateSubEventDialog voor sub-events binnen festival
- EventTabsNav: breadcrumb terug naar festival
- Sessie A: festival-bewuste EventResource + children endpoint
- Topbar: zoekbalk, theme switcher, shortcuts, notificaties
- Schema v1.7 + BACKLOG.md toegevoegd
- 121 tests groen
2026-04-08 10:06:47 +02:00
9acb27af3a feat: fase 2 backend — crowd types, persons, sections, shifts, invite flow
- Crowd Types + Persons CRUD (73 tests)
- Festival Sections + Time Slots + Shifts CRUD met assign/claim flow (84 tests)
- Invite Flow + Member Management met InvitationService (109 tests)
- Schema v1.6 migraties volledig uitgevoerd
- DevSeeder bijgewerkt met crowd types voor testorganisatie
2026-04-08 01:34:46 +02:00
0d24506c89 feat: consolidate frontend API layer, add query-client, and harden backend Fase 1
Frontend:
- Consolidate duplicate API layers into single src/lib/axios.ts per app
- Remove src/lib/api-client.ts and src/utils/api.ts (admin)
- Add src/lib/query-client.ts with TanStack Query config per app
- Update all imports and auto-import config

Backend:
- Fix organisations.billing_status default to 'trial'
- Fix user_invitations.invited_by_user_id to nullOnDelete
- Add MeResource with separated app_roles and pivot-based org roles
- Add cross-org check to EventPolicy view() and update()
- Restrict EventPolicy create/update to org_admin/event_manager (not org_member)
- Attach creator as org_admin on organisation store
- Add query scopes to Event and UserInvitation models
- Improve factories with Dutch test data
- Expand test suite from 29 to 41 tests (90 assertions)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 17:35:34 +02:00
1cb7674d52 refactor: align codebase with EventCrew domain and trim legacy band stack
- Update API: events, users, policies, routes, resources, migrations
- Remove deprecated models/resources (customers, setlists, invitations, etc.)
- Refresh admin app and docs; remove apps/band

Made-with: Cursor
2026-03-29 23:19:06 +02:00
34e12e00b3 feat: initial commit - Band Management application 2026-01-06 03:11:46 +01:00