# Bioluminux CTMS API endpoint inventory

Base URL examples:

- Public API: `https://api.example.com/api`
- Admin API: `https://api.example.com/api/admin`

JSON API responses use `{ "success": true|false, "message": "...", "data": ... }`. Validation errors use Laravel's HTTP 422 JSON format. Admin endpoints require an authenticated Sanctum session and the route-specific RBAC permission.

## Public API

### Locations
- `GET /api/locations` — active clinic locations; supports pagination/search where applicable.
- `GET /api/locations/{id|slug}` — public clinic detail and publicly visible assigned studies.

### Studies / participant recruitment
- `GET /api/studies?status=&location=&therapeutic_area=&search=&recruiting=1&per_page=` — published, non-draft/non-suspended studies.
- `GET /api/studies/{id|slug|protocol_code}` — study detail, assigned clinics, eligibility criteria and active questionnaires.
- `POST /api/studies/{id|slug|protocol_code}/apply` — guest participant application. No participant account is required.

### News
- `GET /api/news?category=&location=&per_page=`
- `GET /api/news/{id|slug}`

### Careers
- `GET /api/careers?location=&per_page=`
- `GET /api/careers/{id|slug}`
- `POST /api/careers/{id|slug}/apply` — job application with private CV upload.

### CMS / general public services
- `GET /api/content/{key|slug}` — published/scheduled CMS page and sections.
- `POST /api/contact` — contact/inquiry submission.
- `GET /api/site-settings` — only settings explicitly marked public.

Public request throttles are defined separately for general browsing, study/job applications and contact forms.

## Admin authentication

The frontend uses Laravel Sanctum's stateful SPA flow. Admin login itself is in the web middleware group so CSRF validation applies.

- `GET /sanctum/csrf-cookie`
- `POST /api/admin/login`
- `POST /api/admin/logout`
- `GET /api/admin/me`
- `POST /api/admin/forgot-password`
- `POST /api/admin/reset-password`
- `POST /api/admin/2fa/enable`
- `POST /api/admin/2fa/confirm`
- `DELETE /api/admin/2fa`

Optional TOTP 2FA is disabled by default and enabled/confirmed per administrator.

## Admin dashboard

- `GET /api/admin/dashboard/metrics`
- `GET /api/admin/dashboard/trends?days=30`
- `GET /api/admin/dashboard/top-studies`
- `GET /api/admin/dashboard/leads-by-clinic`
- `GET /api/admin/dashboard/recruitment-by-region`
- `GET /api/admin/dashboard/participant-pipeline`
- `GET /api/admin/dashboard/recent-activity`

All metrics are calculated from persisted study/application/location records and respect the authenticated user's clinic scope.

## Admin studies

- `GET /api/admin/studies`
- `POST /api/admin/studies`
- `GET /api/admin/studies/{id}`
- `PUT /api/admin/studies/{id}`
- `DELETE /api/admin/studies/{id}`
- `POST /api/admin/studies/{id}/publish` — toggles publish/unpublish.
- `POST /api/admin/studies/{id}/clone`
- `GET /api/admin/studies/{id}/builder`
- `PUT /api/admin/studies/{id}/builder`

The builder manages rich content, eligibility criteria, recruitment flow, protocol leads and per-clinic recruitment/booking configuration.

### Study questionnaires
- `GET /api/admin/studies/{id}/questionnaire`
- `POST /api/admin/studies/{id}/questionnaire`
- `PUT /api/admin/studies/{id}/questionnaire/{questionnaireId}`
- `DELETE /api/admin/studies/{id}/questionnaire/{questionnaireId}`

Questionnaires may be global or clinic-specific. Clinic-scoped staff can read shared questionnaires but can mutate only questionnaires assigned to their permitted clinics.

## Admin participants

- `GET /api/admin/participants?study=&location=&status=&from=&to=&search=&per_page=`
- `GET /api/admin/participants/{applicationId}` — participant profile plus permitted study history.
- `PUT /api/admin/participants/{applicationId}`
- `POST /api/admin/participants/{applicationId}/update-status`
- `GET /api/admin/participants/export`
- `POST /api/admin/participants/{applicationId}/consent-documents`
- `GET /api/admin/consent-documents/{id}/download`

Participant statuses: `pending`, `pre-screened`, `screened`, `enrolled`, `completed`, `withdrawn`, `not-eligible`.

## Admin locations

- `GET /api/admin/locations`
- `POST /api/admin/locations`
- `GET /api/admin/locations/{id}`
- `PUT /api/admin/locations/{id}`
- `DELETE /api/admin/locations/{id}`
- `POST /api/admin/locations/{id}/assign-team`

Team assignments are stored on the user-role pivot with an optional `location_id`, allowing the same role model to support both global and clinic-scoped staff.

## Admin CMS / media

- `GET /api/admin/content`
- `POST /api/admin/content/pages`
- `PUT /api/admin/content/pages/{id}`
- `POST /api/admin/content/sections`
- `PUT /api/admin/content/sections/{id}`
- `DELETE /api/admin/content/sections/{id}`
- `GET /api/admin/content/media`
- `POST /api/admin/content/media`
- `PUT /api/admin/content/media/{id}`
- `DELETE /api/admin/content/media/{id}`

CMS rich text is sanitized server-side. Public CMS media accepts raster images/PDFs; SVG is intentionally excluded.

## Admin careers / applications

- `GET /api/admin/careers`
- `POST /api/admin/careers`
- `GET /api/admin/careers/{id}`
- `PUT /api/admin/careers/{id}`
- `DELETE /api/admin/careers/{id}`
- `GET /api/admin/careers/{id}/applications`
- `PUT /api/admin/career-applications/{id}`
- `GET /api/admin/career-applications/{id}/resume`

CVs are stored on the private filesystem disk and served only through authorized download endpoints.

## Admin news

- `GET /api/admin/news`
- `POST /api/admin/news`
- `GET /api/admin/news/{id}`
- `PUT /api/admin/news/{id}`
- `DELETE /api/admin/news/{id}`

Clinic-scoped users can only manage location-associated news within their assigned clinics.

## Admin users, roles and permissions

- `GET /api/admin/users`
- `POST /api/admin/users`
- `GET /api/admin/users/{id}`
- `PUT /api/admin/users/{id}`
- `DELETE /api/admin/users/{id}`
- `GET /api/admin/roles`
- `POST /api/admin/roles`
- `PUT /api/admin/roles/{id}`
- `GET /api/admin/permissions`

Seeded system roles: Super Admin, Admin, Site Coordinator, Study Manager, Principal Investigator and Research Operations Manager.

## Admin contact messages

- `GET /api/admin/contact-messages`
- `PUT /api/admin/contact-messages/{id}`

Clinic-scoped staff only receive messages associated with an assigned clinic.

## Admin settings

- `GET /api/admin/settings`
- `PUT /api/admin/settings`

Settings groups include general, SMTP/email, notification templates, privacy/retention, recruitment automation, analytics and future integrations. SMTP passwords are encrypted at rest through Laravel's application encryption and masked in API responses.
