openapi: 3.1.0
info:
  title: Bioluminux Clinical Trial Management API
  version: 1.0.0
  description: Public recruitment and internal CTMS administration API. Admin authorization
    combines RBAC permissions with clinic-level scope.
servers:
- url: https://api.example.com
  description: Replace with deployment API origin
paths:
  /api/locations:
    get:
      tags:
      - Public
      summary: List active clinic locations
      responses:
        '200':
          description: Success
  /api/locations/{id}:
    get:
      tags:
      - Public
      summary: Get clinic location by id or slug
      responses:
        '200':
          description: Success
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/studies:
    get:
      tags:
      - Public
      summary: List published clinical studies
      responses:
        '200':
          description: Success
  /api/studies/{id}:
    get:
      tags:
      - Public
      summary: Get clinical study by id, slug or protocol code
      responses:
        '200':
          description: Success
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/studies/{id}/apply:
    post:
      tags:
      - Public
      summary: Submit a guest participant application
      responses:
        '200':
          description: Success
        '422':
          description: Validation error
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StudyApplicationRequest'
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/news:
    get:
      tags:
      - Public
      summary: List published news
      responses:
        '200':
          description: Success
  /api/news/{id}:
    get:
      tags:
      - Public
      summary: Get published news article
      responses:
        '200':
          description: Success
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/careers:
    get:
      tags:
      - Public
      summary: List open careers
      responses:
        '200':
          description: Success
  /api/careers/{id}:
    get:
      tags:
      - Public
      summary: Get career posting
      responses:
        '200':
          description: Success
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/careers/{id}/apply:
    post:
      tags:
      - Public
      summary: Submit career application with CV
      responses:
        '200':
          description: Success
        '422':
          description: Validation error
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/contact:
    post:
      tags:
      - Public
      summary: Submit public contact message
      responses:
        '200':
          description: Success
        '422':
          description: Validation error
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ContactRequest'
  /api/site-settings:
    get:
      tags:
      - Public
      summary: Get public site settings
      responses:
        '200':
          description: Success
  /api/content/{key}:
    get:
      tags:
      - Public
      summary: Get published CMS page by key or slug
      responses:
        '200':
          description: Success
      parameters:
      - name: key
        in: path
        required: true
        schema:
          type: string
  /api/admin/login:
    post:
      tags:
      - Authentication
      summary: Admin login
      responses:
        '200':
          description: Success
        '422':
          description: Validation error
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AdminLoginRequest'
  /api/admin/logout:
    post:
      tags:
      - Authentication
      summary: Admin logout
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
  /api/admin/me:
    get:
      tags:
      - Authentication
      summary: Get authenticated admin
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
  /api/admin/forgot-password:
    post:
      tags:
      - Authentication
      summary: Request admin password reset
      responses:
        '200':
          description: Success
        '422':
          description: Validation error
  /api/admin/reset-password:
    post:
      tags:
      - Authentication
      summary: Reset admin password
      responses:
        '200':
          description: Success
        '422':
          description: Validation error
  /api/admin/2fa/enable:
    post:
      tags:
      - Authentication
      summary: Generate TOTP 2FA setup
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
  /api/admin/2fa/confirm:
    post:
      tags:
      - Authentication
      summary: Confirm and enable TOTP 2FA
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
  /api/admin/2fa:
    delete:
      tags:
      - Authentication
      summary: Disable TOTP 2FA
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
  /api/admin/dashboard/metrics:
    get:
      tags:
      - Dashboard
      summary: Dashboard metrics
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
  /api/admin/dashboard/trends:
    get:
      tags:
      - Dashboard
      summary: Recruitment trends
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
  /api/admin/dashboard/top-studies:
    get:
      tags:
      - Dashboard
      summary: Top performing studies
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
  /api/admin/dashboard/leads-by-clinic:
    get:
      tags:
      - Dashboard
      summary: Leads by clinic
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
  /api/admin/dashboard/recruitment-by-region:
    get:
      tags:
      - Dashboard
      summary: Recruitment by region
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
  /api/admin/dashboard/participant-pipeline:
    get:
      tags:
      - Dashboard
      summary: Participant recruitment pipeline
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
  /api/admin/dashboard/recent-activity:
    get:
      tags:
      - Dashboard
      summary: Recent participant/content activity
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
  /api/admin/studies:
    get:
      tags:
      - Studies
      summary: List studies within access scope
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
    post:
      tags:
      - Studies
      summary: Create study
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StudyRequest'
  /api/admin/studies/{id}:
    get:
      tags:
      - Studies
      summary: Get study
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    put:
      tags:
      - Studies
      summary: Update study
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StudyRequest'
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    delete:
      tags:
      - Studies
      summary: Delete study when allowed
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/studies/{id}/publish:
    post:
      tags:
      - Studies
      summary: Toggle study publish state
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/studies/{id}/clone:
    post:
      tags:
      - Studies
      summary: Clone study into draft protocol
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/studies/{id}/builder:
    get:
      tags:
      - Studies
      summary: Get Study Builder configuration
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    put:
      tags:
      - Studies
      summary: Update Study Builder configuration
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/studies/{id}/questionnaire:
    get:
      tags:
      - Questionnaires
      summary: List study questionnaires
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    post:
      tags:
      - Questionnaires
      summary: Create study questionnaire
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/studies/{id}/questionnaire/{questionnaireId}:
    put:
      tags:
      - Questionnaires
      summary: Update study questionnaire
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: questionnaireId
        in: path
        required: true
        schema:
          type: string
    delete:
      tags:
      - Questionnaires
      summary: Delete study questionnaire
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: questionnaireId
        in: path
        required: true
        schema:
          type: string
  /api/admin/participants:
    get:
      tags:
      - Participants
      summary: List participant applications within clinic scope
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
  /api/admin/participants/export:
    get:
      tags:
      - Participants
      summary: Export permitted participant applications as CSV
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
  /api/admin/participants/{id}:
    get:
      tags:
      - Participants
      summary: Get participant application/profile/history
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    put:
      tags:
      - Participants
      summary: Update participant/application details
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/participants/{id}/update-status:
    post:
      tags:
      - Participants
      summary: Update recruitment status
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/participants/{id}/consent-documents:
    post:
      tags:
      - Participants
      summary: Upload participant consent PDF
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/consent-documents/{id}/download:
    get:
      tags:
      - Participants
      summary: Download authorized consent document
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/locations:
    get:
      tags:
      - Locations
      summary: List locations within access scope
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
    post:
      tags:
      - Locations
      summary: Create clinic location
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
  /api/admin/locations/{id}:
    get:
      tags:
      - Locations
      summary: Get clinic and assigned team
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    put:
      tags:
      - Locations
      summary: Update clinic
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    delete:
      tags:
      - Locations
      summary: Delete clinic when allowed
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/locations/{id}/assign-team:
    post:
      tags:
      - Locations
      summary: Replace clinic team role assignments
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/content:
    get:
      tags:
      - CMS
      summary: List CMS pages and sections
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
  /api/admin/content/pages:
    post:
      tags:
      - CMS
      summary: Create CMS page
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
  /api/admin/content/pages/{id}:
    put:
      tags:
      - CMS
      summary: Update CMS page/SEO/schedule
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/content/sections:
    post:
      tags:
      - CMS
      summary: Create CMS section
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
  /api/admin/content/sections/{id}:
    put:
      tags:
      - CMS
      summary: Update CMS section
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    delete:
      tags:
      - CMS
      summary: Delete CMS section
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/content/media:
    get:
      tags:
      - CMS
      summary: List CMS media
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
    post:
      tags:
      - CMS
      summary: Upload raster image or PDF
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
  /api/admin/content/media/{id}:
    put:
      tags:
      - CMS
      summary: Update media metadata
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    delete:
      tags:
      - CMS
      summary: Delete media asset
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/careers:
    get:
      tags:
      - Careers
      summary: List careers within access scope
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
    post:
      tags:
      - Careers
      summary: Create career posting
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
  /api/admin/careers/{id}:
    get:
      tags:
      - Careers
      summary: Get career and applications
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    put:
      tags:
      - Careers
      summary: Update career posting
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    delete:
      tags:
      - Careers
      summary: Delete career when no applications exist
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/careers/{id}/applications:
    get:
      tags:
      - Careers
      summary: List career applications
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/career-applications/{id}:
    put:
      tags:
      - Careers
      summary: Update career application status
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/career-applications/{id}/resume:
    get:
      tags:
      - Careers
      summary: Download authorized private CV
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/news:
    get:
      tags:
      - News
      summary: List news within access scope
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
    post:
      tags:
      - News
      summary: Create news article
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
  /api/admin/news/{id}:
    get:
      tags:
      - News
      summary: Get news article
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    put:
      tags:
      - News
      summary: Update news article
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    delete:
      tags:
      - News
      summary: Delete news article
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/users:
    get:
      tags:
      - Users & Roles
      summary: List admin users
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
    post:
      tags:
      - Users & Roles
      summary: Create/invite admin user
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
  /api/admin/users/{id}:
    get:
      tags:
      - Users & Roles
      summary: Get admin user
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    put:
      tags:
      - Users & Roles
      summary: Update admin user roles/locations
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
    delete:
      tags:
      - Users & Roles
      summary: Deactivate/delete admin user
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/roles:
    get:
      tags:
      - Users & Roles
      summary: List roles
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
    post:
      tags:
      - Users & Roles
      summary: Create role
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
  /api/admin/roles/{id}:
    put:
      tags:
      - Users & Roles
      summary: Update role permissions
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/permissions:
    get:
      tags:
      - Users & Roles
      summary: List permissions
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
  /api/admin/contact-messages:
    get:
      tags:
      - CMS
      summary: List contact messages within access scope
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
  /api/admin/contact-messages/{id}:
    put:
      tags:
      - CMS
      summary: Update contact message status
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
  /api/admin/settings:
    get:
      tags:
      - Settings
      summary: List site settings
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
      security:
      - sanctumCookie: []
    put:
      tags:
      - Settings
      summary: Update site settings
      responses:
        '200':
          description: Success
        '401':
          description: Unauthenticated
        '403':
          description: Forbidden by role/location scope
        '422':
          description: Validation error
      security:
      - sanctumCookie: []
components:
  securitySchemes:
    sanctumCookie:
      type: apiKey
      in: cookie
      name: laravel_session
      description: Laravel Sanctum stateful SPA session. Obtain CSRF cookie before
        login/mutations.
  schemas:
    AdminLoginRequest:
      type: object
      required:
      - email
      - password
      properties:
        email:
          type: string
          format: email
        password:
          type: string
          format: password
        code:
          type: string
          description: TOTP code when 2FA is enabled
    StudyRequest:
      type: object
      required:
      - abbreviation
      - therapeutic_area
      - full_title
      - status
      - location_ids
      properties:
        protocol_code:
          type:
          - string
          - 'null'
          description: Optional manual unique code; automatic BIO-### when omitted
        abbreviation:
          type: string
        therapeutic_area:
          type: string
        full_title:
          type: string
        status:
          type: string
          enum:
          - draft
          - recruiting
          - enrolling
          - completed
          - suspended
        protocol_description:
          type:
          - string
          - 'null'
        content:
          type:
          - string
          - 'null'
        start_date:
          type:
          - string
          - 'null'
          format: date
        end_date:
          type:
          - string
          - 'null'
          format: date
        target_participants:
          type:
          - integer
          - 'null'
          minimum: 1
        location_ids:
          type: array
          items:
            type: integer
    StudyApplicationRequest:
      type: object
      required:
      - first_name
      - last_name
      - email
      - location_id
      - consent_given
      properties:
        first_name:
          type: string
        last_name:
          type: string
        email:
          type: string
          format: email
        phone:
          type:
          - string
          - 'null'
        date_of_birth:
          type:
          - string
          - 'null'
          format: date
        country:
          type:
          - string
          - 'null'
        location_id:
          type: integer
        questionnaire_answers:
          type: object
          additionalProperties: true
        consent_given:
          type: boolean
          const: true
    ContactRequest:
      type: object
      required:
      - name
      - email
      - message
      properties:
        name:
          type: string
        email:
          type: string
          format: email
        phone:
          type:
          - string
          - 'null'
        subject:
          type:
          - string
          - 'null'
        message:
          type: string
        location_id:
          type:
          - integer
          - 'null'
