# Architecture and data flow

## Applications

The solution is intentionally split into two deployable applications:

1. **Next.js frontend** — preserves the supplied public site and internal dashboard interface, adds SEO/server metadata, public API reads, guest application flows and authenticated dashboard data adapters.
2. **Laravel API** — owns authentication, authorization, persistence, recruitment rules, participant/CV/consent data, CMS, email notifications, analytics aggregation and future integration events.

This separation allows the frontend to evolve independently while keeping sensitive business rules and participant access control on the server.

## Authentication

Administrators authenticate with a Laravel Sanctum stateful session. The browser obtains a CSRF cookie before login and sends credentialed requests. Optional TOTP 2FA is available per admin account but disabled by default.

Participants do **not** have accounts in this release. Study applications are guest submissions and are deduplicated by participant email plus study/location application uniqueness.

## RBAC and location scope

Permissions control *what* a user may do. The `role_user.location_id` pivot controls *where* they may do it.

- A Super Admin or role assignment with `location_id = null` is global.
- A location-scoped assignment restricts participant, dashboard, location, careers, location-news, contact-message and study visibility to assigned clinics.
- Multi-site study core definitions cannot be modified by a staff account that only owns a subset of that study's clinics. This prevents accidental removal or overwrite of other locations.
- Clinic-specific questionnaires can only be changed by users with access to that clinic; shared questionnaires remain readable.

## Study lifecycle

A study contains protocol identity, therapeutic area, title/content, target, dates, status and publish state. Locations are many-to-many through `location_study`, which also stores clinic recruitment flags, booking method/link and recruitment settings.

`BIO-###` codes use an atomic protocol-sequence table and database row locking. A manual unique protocol code may still be supplied.

Public visibility requires a publish timestamp and a non-draft/non-suspended status. Reaching the configured enrollment target can trigger notifications and, when enabled, automatic movement from `recruiting` to `enrolling` so new public applications are blocked.

## Participant recruitment

Guest application flow:

`Public study -> recruiting clinic -> dynamic questionnaire -> consent -> participant/application records -> acknowledgement email -> staff notification -> activity/integration event`

Questionnaire answers are validated against active shared and selected-clinic questions. Duplicate participant rows are protected by a unique email constraint, while a participant cannot create a duplicate application for the same study and clinic.

Participant documents and career CVs use private storage. Public study/news/CMS imagery uses the public media disk.

## CMS and SEO

CMS pages support status, publish date, scheduled publication, version number, rich text, sections and SEO fields. Rich HTML is sanitized before storage/rendering. The Next.js frontend provides metadata defaults, canonical URLs, robots rules, a dynamic sitemap and structured data for organisation/clinic content.

## Notifications

Email notifications are queued. Templates are configurable through site settings for applicant acknowledgements. Study application, career application, contact and study-target events notify the relevant parties using configured SMTP settings.

## Future CRM / EMR integrations

Important recruitment events are written to an `integration_events` outbox instead of directly calling a vendor. A future worker can deliver signed webhooks or map records into CRM/EMR APIs without changing the study/participant endpoints. The outbox provides a stable boundary for retry/idempotency work in the next integration phase.

## Data retention

The schema includes `participants.retention_until` and a configurable `privacy.default_retention_years` setting. No automatic legal deletion period is enabled because the final retention rule was not supplied and should be approved per study, jurisdiction and organisational governance before automated anonymisation/deletion is activated.
