---
openapi: 3.0.3
info:
  title: CodeFirst Backend API
  contact:
    name: CodeFirst Support
    email: codefirst@example.com
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
  version: 1.0.1
tags:
- name: Kubernetes
  description: Kubernetes resources.
- name: Gitlab
  description: Gitlab resources.
- name: Keycloak
  description: Keycloak resources.
- name: Monitoring
  description: Admin API for backend monitoring.
- name: Issues
  description: API to manage Codefisrt instance issues opened by its users.
- name: Health
- name: Users
- name: Version
- name: Admin audit
- name: Admin gamification
- name: Platform announcements
- name: Platform settings
- name: Admin statistics
- name: Admin user features
- name: Admin whitelist
- name: Impersonation
- name: Gamification
- name: Features
- name: Organisation
- name: Quota Requests
- name: Portfolio
- name: Migration
- name: Platform
paths:
  /admin/announcements:
    get:
      tags:
      - Platform announcements
      summary: "Admin only - Liste toutes les annonces (planifiées, actives, expiré\
        es, désactivées)."
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: "Every announcement (scheduled, active, expired and disabled)."
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AdminPlatformAnnouncementDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
    post:
      tags:
      - Platform announcements
      summary: Admin only - Crée une annonce et la publie sur GitLab (fenêtre dates
        = activation).
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpsertPlatformAnnouncementDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: The announcement has been created and published to GitLab.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AdminPlatformAnnouncementDTO'
        "400":
          description: "Invalid announcement payload (missing body, empty message\
            \ or end date before start date)."
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/announcements/{id}:
    put:
      tags:
      - Platform announcements
      summary: Admin only - Met à jour une annonce active/planifiée et resynchronise
        GitLab.
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpsertPlatformAnnouncementDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: The active/scheduled announcement has been updated and resynchronised
            with GitLab.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AdminPlatformAnnouncementDTO'
        "400":
          description: "Invalid id, invalid payload, or the announcement is disabled."
        "404":
          description: No announcement with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
    delete:
      tags:
      - Platform announcements
      summary: Admin only - Supprime définitivement une annonce (Mongo + GitLab).
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The announcement has been permanently deleted (Mongo + GitLab).
        "400":
          description: Invalid id.
        "404":
          description: No announcement with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/announcements/{id}/disable:
    post:
      tags:
      - Platform announcements
      summary: Admin only - Coupe une annonce publiée (retrait Néon + GitLab).
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: The published announcement has been switched off (removed from
            Neon + GitLab).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AdminPlatformAnnouncementDTO'
        "400":
          description: Invalid id.
        "404":
          description: No announcement with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/audit-logs:
    get:
      tags:
      - Admin audit
      summary: "Admin only: paginated audit trail (most recent first)"
      parameters:
      - name: page
        in: query
        schema:
          format: int32
          default: 0
          type: integer
      - name: size
        in: query
        schema:
          format: int32
          default: 20
          type: integer
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Paginated audit log entries.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PageDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/gamification/students:
    get:
      tags:
      - Admin gamification
      summary: Admin only - paginated list of students with at least one completed
        quest and gamification summary
      parameters:
      - name: page
        in: query
        schema:
          format: int32
          default: 0
          type: integer
      - name: search
        in: query
        schema:
          type: string
      - name: size
        in: query
        schema:
          format: int32
          default: 20
          type: integer
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: "Paginated list of students who have completed at least one\
            \ quest, with their gamification summary."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AdminStudentGamificationPageDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/gamification/students/{username}:
    get:
      tags:
      - Admin gamification
      summary: Admin only - quest progress detail for one student
      parameters:
      - name: username
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Detailed quest progress for the requested student.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AdminStudentGamificationDetailDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/impersonation/eligible-users:
    get:
      tags:
      - Impersonation
      summary: Admin only - Liste les utilisateurs éligibles à l’impersonnalisation
        (sync récente ou admin whitelisté).
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Users eligible for impersonation (recently synced users plus
            whitelisted admins).
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/UserDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/impersonation/{username}:
    post:
      tags:
      - Impersonation
      summary: Admin only - Échange le JWT admin contre un JWT utilisateur cible (token
        exchange Keycloak).
      parameters:
      - name: username
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Returns the impersonation token obtained from the Keycloak
            token exchange for the target user.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImpersonationTokenDTO'
        "404":
          description: No eligible user with this username exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/jobs:
    get:
      tags:
      - Monitoring
      summary: Admin only - list all registered cron jobs
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List every registered cron job with its current schedule and
            effective enabled state.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CronJobDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/jobs/{name}:
    get:
      tags:
      - Monitoring
      summary: Admin only - get a single cron job state
      parameters:
      - name: name
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Return the current state of a single cron job.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CronJobDTO'
        "404":
          description: No cron job with this name is registered.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/jobs/{name}/enabled:
    patch:
      tags:
      - Monitoring
      summary: Admin only - toggle a cron job on or off
      parameters:
      - name: name
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateCronJobEnabledDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: The cron job has been enabled or disabled.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CronJobDTO'
        "400":
          description: Missing `enabled` field in the request body.
        "404":
          description: No cron job with this name is registered.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/jobs/{name}/logs:
    get:
      tags:
      - Monitoring
      summary: Admin only - fetch execution history for a cron job
      parameters:
      - name: name
        in: path
        required: true
        schema:
          type: string
      - name: limit
        in: query
        schema:
          format: int32
          default: 50
          type: integer
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Execution history (most recent first) for the requested cron
            job.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CronJobExecutionLogDTO'
        "404":
          description: No cron job with this name is registered.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/jobs/{name}/parameters:
    patch:
      tags:
      - Monitoring
      summary: Admin only - update a cron job's configurable parameters
      parameters:
      - name: name
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateCronJobParametersDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: The cron job parameters have been updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CronJobDTO'
        "400":
          description: Missing/unknown parameter or invalid value.
        "404":
          description: No cron job with this name is registered.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/jobs/{name}/trigger:
    post:
      tags:
      - Monitoring
      summary: "Admin only - manually trigger a cron job (async, bypasses the enabled\
        \ flag)"
      parameters:
      - name: name
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "202":
          description: "The cron job has been accepted for asynchronous execution\
            \ on a worker thread. Poll `/admin/jobs/{name}/logs` to observe the outcome."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CronJobDTO'
        "404":
          description: No cron job with this name is registered.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/k8s/portfolios/audit:
    get:
      tags:
      - Kubernetes
      summary: Admin only — best-effort audit of portfolios (orphans / duplicates)
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/k8s/rbac/tokens/available/count:
    get:
      tags:
      - Kubernetes
      summary: Admin only
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Count all available RBAC token left in the database.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CountDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/k8s/rbac/tokens/history/secret/{secret}:
    get:
      tags:
      - Kubernetes
      summary: Admin only
      parameters:
      - name: secret
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Retrieve assignations history for a dedicated token secret.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RbacTokenHistoryDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/k8s/rbac/tokens/history/used-by/{usedBy}:
    get:
      tags:
      - Kubernetes
      summary: Admin only
      parameters:
      - name: usedBy
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Retrieve history of token assignations for the requested namespace.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RbacTokenHistoryDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/k8s/rbac/tokens/history/username/{username}:
    get:
      tags:
      - Kubernetes
      summary: Admin only
      parameters:
      - name: username
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Retrieve history of token assignations made by the requested
            username.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RbacTokenHistoryDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/k8s/rbac/tokens/import:
    post:
      tags:
      - Kubernetes
      summary: Admin only
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: '#/components/schemas/ImportRbacTokenDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: "Status of the import once it is done, gives the number of\
            \ token imported."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImportStatus'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/k8s/rbac/tokens/portfolio/{username}:
    delete:
      tags:
      - Kubernetes
      summary: Admin only - revoke the dedicated portfolio token of a student (removes
        their Role/RoleBinding from the shared namespace and frees the token)
      parameters:
      - name: username
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: Portfolio token revoked and returned to the pool.
        "400":
          description: The student has no dedicated portfolio token.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/k8s/rbac/tokens/used:
    get:
      tags:
      - Kubernetes
      summary: Admin only
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List all used RBAC token.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RbacTokenDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/settings/default-namespace-quota:
    get:
      tags:
      - Platform settings
      summary: Admin only - Lit les quotas namespace par défaut (Mongo settings /
        défauts CodeFirst si absent).
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: "Current default namespace quotas (from Mongo settings, falling\
            \ back to CodeFirst defaults)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DefaultNamespaceQuotaSettingDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
    put:
      tags:
      - Platform settings
      summary: Admin only - Met à jour les quotas namespace par défaut dans Mongo
        (clé DEFAULT_NAMESPACE_QUOTA).
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DefaultNamespaceQuotaSettingDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: The default namespace quotas have been updated in Mongo (key
            DEFAULT_NAMESPACE_QUOTA).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DefaultNamespaceQuotaSettingDTO'
        "400":
          description: Missing body or invalid Kubernetes quantity for one of the
            quota fields.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/statistics/overview:
    get:
      tags:
      - Admin statistics
      summary: Admin only - Platform and API aggregate stats (admin or feature STATISTICS)
      parameters:
      - name: since
        in: query
        schema:
          $ref: '#/components/schemas/Date'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: "Aggregated platform and API statistics, optionally limited\
            \ to events since the given date."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StatisticsOverviewDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /admin/user-features:
    get:
      tags:
      - Admin user features
      summary: "Admin only: active features per user (read-only), sorted by username"
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/whitelist:
    get:
      tags:
      - Admin whitelist
      summary: "Admin only - Liste fusionnée : admins délégués (Mongo) + super-admins\
        \ config seule (managedInDatabase=false)."
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Merged list of delegated admins (Mongo) and config-only super-admins
            (managedInDatabase=false).
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AdminWhitelistEntryDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
    post:
      tags:
      - Admin whitelist
      summary: "Admin only - Ajoute un admin délégué : utilisateur Keycloak existant\
        \ + groupe Keycloak admin + entrée Mongo."
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateAdminWhitelistEntryDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: The delegated admin has been added (existing Keycloak user
            + Keycloak admin group + Mongo entry).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AdminWhitelistEntryDTO'
        "400":
          description: "Invalid email, email already whitelisted, email reserved for\
            \ a configuration super-admin, or Keycloak operation failed."
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /admin/whitelist/{id}:
    put:
      tags:
      - Admin whitelist
      summary: "Admin only - Met à jour l’e-mail : ajout au groupe admin Keycloak\
        \ pour le nouveau compte, retrait pour l’ancien."
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateAdminWhitelistEntryDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: "The email has been updated: the new account joins the Keycloak\
            \ admin group and the old one is removed."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AdminWhitelistEntryDTO'
        "400":
          description: "Invalid id/email, duplicate email, email already in the static\
            \ configuration, or Keycloak operation failed."
        "404":
          description: No whitelist entry with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
    delete:
      tags:
      - Admin whitelist
      summary: Admin only - Supprime l’entrée Mongo et retire l’utilisateur du groupe
        Keycloak admin.
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The Mongo entry has been deleted and the user removed from
            the Keycloak admin group.
        "400":
          description: Invalid id or Keycloak operation failed.
        "404":
          description: No whitelist entry with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /features:
    get:
      tags:
      - Features
      summary: List all available features
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List all available features.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/FeatureDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /features/{id}/username/{username}/assign:
    post:
      tags:
      - Features
      summary: Admin only
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: username
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The feature has been assigned to the user.
        "404":
          description: No feature with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /features/{id}/username/{username}/revoke:
    post:
      tags:
      - Features
      summary: Admin only
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: username
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The feature has been revoked from the user.
        "404":
          description: No feature with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /gitlab/groups:
    get:
      tags:
      - Gitlab
      summary: List the Gitlab groups visible to the current user (admins and SAE
        declarants may request all groups)
      parameters:
      - name: all
        in: query
        description: "ADMIN ou enseignant avec le droit DECLARE_AS_SAE (WRITE) : si\
          \ true, renvoie TOUS les groupes GitLab du cache, sans filtre sur l'appartenance\
          \ de l'utilisateur."
        schema:
          default: false
          type: boolean
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List all existing gitlab groups on which the current user has
            visibility.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CacheGitlabGroupDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
    post:
      tags:
      - Gitlab
      summary: Create a new Gitlab group for a SAE project or a teacher course
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InputGroupDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Create a new group onto the gitlab instance for SAE projects
            and teacher courses.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GroupDTO'
        "400":
          description: The group name or organization id is missing.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/groups/user/{id}:
    get:
      tags:
      - Gitlab
      summary: Teacher and admin only
      parameters:
      - name: id
        in: path
        required: true
        schema:
          format: int64
          type: integer
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List all groups where the user is a member.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/GroupDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/groups/{gitlabId}:
    delete:
      tags:
      - Gitlab
      summary: Delete an existing Gitlab group
      parameters:
      - name: gitlabId
        in: path
        required: true
        schema:
          format: int64
          type: integer
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The Gitlab group has been deleted.
        "404":
          description: The group does not exist.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
    patch:
      tags:
      - Gitlab
      summary: ADMIN only or feature DECLARE_AS_SAE / DECLARE_USE_PERSISTENT_VOLUMES
        / DECLARE_GROUPS_CAN_CONTAIN_CONTAINERS
      parameters:
      - name: gitlabId
        in: path
        required: true
        schema:
          format: int64
          type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateCacheGitlabGroupDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Update an existing Gitlab group.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CacheGitlabGroupDetailsDTO'
        "400":
          description: Disabling the requested feature is blocked because the group
            still uses a persistent volume.
        "404":
          description: The group does not exist.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/groups/{id}:
    get:
      tags:
      - Gitlab
      summary: Get the details of a single Gitlab group visible to the current user
      parameters:
      - name: id
        in: path
        required: true
        schema:
          format: int64
          type: integer
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Get details of an existing gitlab group on which the current
            user has visibility.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CacheGitlabGroupDetailsDTO'
        "404":
          description: No group or user matches the requested identifier.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/groups/{id}/members/add:
    post:
      tags:
      - Gitlab
      summary: Add users and student-list groups to an existing Gitlab group
      parameters:
      - name: id
        in: path
        required: true
        schema:
          format: int64
          type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GitlabGroupMembersDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The requested users and student-list groups have been added
            to the group.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/groups/{id}/members/groups/{groupId}:
    delete:
      tags:
      - Gitlab
      summary: Teacher and admin only
      parameters:
      - name: groupId
        in: path
        required: true
        schema:
          format: int64
          type: integer
      - name: id
        in: path
        required: true
        schema:
          format: int64
          type: integer
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The shared group has been removed from the group.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/groups/{id}/members/users/{userId}:
    delete:
      tags:
      - Gitlab
      summary: Remove a user from an existing Gitlab group
      parameters:
      - name: id
        in: path
        required: true
        schema:
          format: int64
          type: integer
      - name: userId
        in: path
        required: true
        schema:
          format: int64
          type: integer
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The user has been removed from the group.
        "404":
          description: The group does not exist.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/groups/{id}/subgroups:
    get:
      tags:
      - Gitlab
      summary: "List the direct subgroups of a Gitlab group, straight from GitLab\
        \ (inherited access included)"
      parameters:
      - name: id
        in: path
        required: true
        schema:
          format: int64
          type: integer
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List the direct GitLab subgroups of a group visible to the
            current user.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CacheGitlabGroupDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/projects:
    post:
      tags:
      - Gitlab
      summary: Students API
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InputProjectDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "201":
          description: Create a new Gitlab project inside the requested parent group
            on behalf of the current student.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProjectDTO'
        "404":
          description: The parent group does not exist.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/projects/groups/{groupId}:
    get:
      tags:
      - Gitlab
      summary: Get all projects for a Gitlab Group (must be at least Maintainer on
        projects)
      parameters:
      - name: groupId
        in: path
        required: true
        schema:
          format: int64
          type: integer
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List the Gitlab projects of a group that the current user is
            allowed to see.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProjectDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/projects/{id}:
    delete:
      tags:
      - Gitlab
      summary: Delete a Gitlab project (must be at least Maintainer on the project)
      parameters:
      - name: id
        in: path
        required: true
        schema:
          format: int64
          type: integer
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The Gitlab project has been deleted.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/projects/{id}/members:
    get:
      tags:
      - Gitlab
      summary: Teacher and admin only
      parameters:
      - name: id
        in: path
        required: true
        schema:
          format: int64
          type: integer
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Return the direct members and shared student-list groups of
            a Gitlab project.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProjectMembersDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/projects/{id}/members/add:
    post:
      tags:
      - Gitlab
      summary: Teacher and admin only
      parameters:
      - name: id
        in: path
        required: true
        schema:
          format: int64
          type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GitlabGroupMembersDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The requested users and student-list groups have been added
            to the project.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/projects/{id}/members/groups/{groupId}:
    delete:
      tags:
      - Gitlab
      summary: Teacher and admin only
      parameters:
      - name: groupId
        in: path
        required: true
        schema:
          format: int64
          type: integer
      - name: id
        in: path
        required: true
        schema:
          format: int64
          type: integer
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The shared group has been removed from the project.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/projects/{id}/members/students/clear:
    post:
      tags:
      - Gitlab
      summary: Teacher and admin only
      parameters:
      - name: id
        in: path
        required: true
        schema:
          format: int64
          type: integer
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: Every non-teacher student member has been removed from the
            project.
        "404":
          description: The project does not exist.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/projects/{id}/members/users/{userId}:
    delete:
      tags:
      - Gitlab
      summary: Teacher and admin only
      parameters:
      - name: id
        in: path
        required: true
        schema:
          format: int64
          type: integer
      - name: userId
        in: path
        required: true
        schema:
          format: int64
          type: integer
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The user has been removed from the project.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/templates:
    get:
      tags:
      - Gitlab
      summary: List all Gitlab templates
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List all available Gitlab templates.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/GitlabTemplateDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
    post:
      tags:
      - Gitlab
      summary: Create a new Gitlab template
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateGitlabTemplateDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "201":
          description: Create a new Gitlab template.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GitlabTemplateDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/templates/{id}:
    get:
      tags:
      - Gitlab
      summary: Get a single Gitlab template by id
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Return a single Gitlab template by its identifier.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GitlabTemplateDTO'
        "404":
          description: No template matches the requested identifier.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
    put:
      tags:
      - Gitlab
      summary: Update an existing Gitlab template
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateGitlabTemplateDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Update an existing Gitlab template.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GitlabTemplateDTO'
        "404":
          description: No template matches the requested identifier.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
    delete:
      tags:
      - Gitlab
      summary: Delete a Gitlab template
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The Gitlab template has been deleted.
        "404":
          description: No template matches the requested identifier.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/templates/{id}/archive:
    post:
      tags:
      - Gitlab
      summary: Download a rendered ZIP archive of a Gitlab template
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TemplateVariablesDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: "Clone the template repository, apply FreeMarker on text files\
            \ and return a ZIP archive without the `.git` folder."
          content:
            application/zip:
              schema:
                format: binary
                type: string
        "404":
          description: No template matches the requested identifier.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/templates/{id}/create-project:
    post:
      tags:
      - Gitlab
      summary: Create a GitLab project from a template in the user's personal namespace
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateProjectFromTemplateDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Project created in the user's personal namespace.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreatedProjectDTO'
        "400":
          description: "No PAT configured, invalid PAT, missing project name, or project\
            \ name already taken."
        "404":
          description: No template matches the requested identifier.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/templates/{id}/describe:
    get:
      tags:
      - Gitlab
      summary: Get the parsed describe metadata of a Gitlab template
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Read and parse the `.describe.yml` file at the root of the
            template repository.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateDescribeDTO'
        "404":
          description: No template matches the requested identifier.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/users/me/color-mode/{id}:
    post:
      tags:
      - Gitlab
      summary: Teacher and admin only
      parameters:
      - name: id
        in: path
        required: true
        schema:
          format: int32
          type: integer
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Update the GitLab color mode of the current user and return
            the resulting status.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserUpdateStatusDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /gitlab/users/me/customization:
    get:
      tags:
      - Gitlab
      summary: Teacher and admin only
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Return the GitLab customization settings of the current user.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GitlabUserCustomization'
        "404":
          description: No GitLab user matches the current username.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /health:
    get:
      tags:
      - Health
      summary: Public API
      responses:
        "200":
          description: The service is up and returns the plain string "OK".
          content:
            application/json:
              schema:
                type: string
  /issues:
    get:
      tags:
      - Issues
      summary: Admin only or feature ISSUES
      parameters:
      - name: closed
        in: query
        schema:
          type: boolean
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List all issues open for the codefirst instance.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/IssueDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
    post:
      tags:
      - Issues
      summary: Create a new issue authored by the current user
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateIssueDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "201":
          description: The issue has been created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IssueDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /issues/me:
    get:
      tags:
      - Issues
      summary: List the current user's own issues and quota requests (open or closed)
      parameters:
      - name: closed
        in: query
        schema:
          type: boolean
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List all issues open for the codefirst instance.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/IssueDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /issues/quota:
    get:
      tags:
      - Issues
      summary: Admin only or feature QUOTA_REQUESTS
      parameters:
      - name: closed
        in: query
        schema:
          type: boolean
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List all quota requests open for the codefirst instance.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/IssueDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /issues/{id}:
    get:
      tags:
      - Issues
      summary: Get one of the current user's issues by id
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Return a single issue authored by the current user.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IssueDTO'
        "404":
          description: No issue with this id was found for the current user.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
    patch:
      tags:
      - Issues
      summary: Update an issue (severity can only be changed by admins)
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateIssueDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: The issue has been updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IssueDTO'
        "404":
          description: No issue with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /issues/{id}/assignee/{username}:
    post:
      tags:
      - Issues
      summary: "Assign an issue to a user (self-assignment, or any user for admins)"
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: username
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The issue has been assigned to the user.
        "404":
          description: No issue with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /issues/{id}/comments:
    post:
      tags:
      - Issues
      summary: Add a comment to an issue (author or admin only)
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CommentDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: The comment has been added to the issue.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IssueDTO'
        "404":
          description: No issue with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /issues/{id}/comments/{commentId}:
    delete:
      tags:
      - Issues
      summary: Admin only
      parameters:
      - name: commentId
        in: path
        required: true
        schema:
          type: string
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: The comment has been removed from the issue.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IssueDTO'
        "404":
          description: No issue with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /issues/{id}/transition/{state}:
    post:
      tags:
      - Issues
      summary: Open or close an issue (author or admin only)
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: state
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The issue has transitioned to the requested state.
        "400":
          description: Unknown target state (expected OPEN or CLOSE).
        "404":
          description: No issue with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /k8s/deployments/pods/name/{podName}:
    delete:
      tags:
      - Kubernetes
      summary: Delete the deployment owning the pod with the given name in a namespace
      parameters:
      - name: podName
        in: path
        required: true
        schema:
          type: string
      - name: namespace
        in: query
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: "The deployment owning the given pod has been deleted, or no\
            \ matching deployment was found."
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /k8s/events/logs:
    get:
      tags:
      - Kubernetes
      summary: Get the aggregated Kubernetes event logs of a namespace
      parameters:
      - name: namespace
        in: query
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Return the logs of the namespace.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/KubernetesLogsDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /k8s/namespaces:
    get:
      tags:
      - Kubernetes
      summary: List all namespaces visible to the current user
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List all namespaces according to user visibility.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/NamespaceDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
    post:
      tags:
      - Kubernetes
      summary: Create a namespace for the current user
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NamespaceDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "201":
          description: Namespace resource created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NamespaceDTO'
        "400":
          description: Namespace creation is not allowed for the associated group.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /k8s/namespaces/name/{name}:
    get:
      tags:
      - Kubernetes
      summary: "Get namespace details with quota, pods and persistent volume claims"
      parameters:
      - name: name
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Give namespace details with quota and all the pods.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NamespaceDetailDTO'
        "404":
          description: No namespace with this name exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
    delete:
      tags:
      - Kubernetes
      summary: Delete a namespace by name
      parameters:
      - name: name
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: No Content
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /k8s/persistent-volume-claims:
    get:
      tags:
      - Kubernetes
      summary: List the persistent volume claims of a namespace
      parameters:
      - name: namespace
        in: query
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List all persistent volume claims of the given namespace.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PersistentVolumeClaimDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
    post:
      tags:
      - Kubernetes
      summary: Create a persistent volume claim in a namespace
      parameters:
      - name: namespace
        in: query
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "201":
          description: The persistent volume claim has been created in the given namespace.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PersistentVolumeClaimDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /k8s/persistent-volume-claims/{name}:
    delete:
      tags:
      - Kubernetes
      summary: Delete a persistent volume claim by name in a namespace
      parameters:
      - name: name
        in: path
        required: true
        schema:
          type: string
      - name: namespace
        in: query
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The persistent volume claim has been deleted.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /k8s/pods/{name}/logs:
    get:
      tags:
      - Kubernetes
      summary: Get the most recent logs of a pod (last 1000 lines max)
      parameters:
      - name: name
        in: path
        required: true
        schema:
          type: string
      - name: lines
        in: query
        schema:
          format: int32
          default: 150
          type: integer
      - name: namespace
        in: query
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Return the logs of the pod with the given name and namespace
            (Maximum last 1000 lines).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/KubernetesLogsDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /k8s/pods/{name}/logs/full:
    get:
      tags:
      - Kubernetes
      summary: Get the full logs of a pod
      parameters:
      - name: name
        in: path
        required: true
        schema:
          type: string
      - name: namespace
        in: query
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Return all the logs of the pod with the given name and namespace.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/KubernetesLogsDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /k8s/rbac/tokens/assign:
    post:
      tags:
      - Kubernetes
      summary: Assign an available RBAC token to a namespace
      parameters:
      - name: namespace
        in: query
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Assign a random available token to the requested namespace
            if none already assigned.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RbacTokenDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /k8s/rbac/tokens/portfolio:
    post:
      tags:
      - Kubernetes
      summary: "Provision the current user's portfolio RBAC token (per-student, resourceNames-scoped)"
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Provision (idempotent) the current user's portfolio RBAC token
            + role and return its deploy config.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PortfolioTokenDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /k8s/stats/objects/count:
    get:
      tags:
      - Kubernetes
      summary: Admin only or feature STATISTICS
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Number of namespaces and pods currently present in the cluster.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CountObjectDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /k8s/stats/quota/sum:
    get:
      tags:
      - Kubernetes
      summary: Admin only or feature STATISTICS
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Total CPU and RAM limits used across all running pods of the
            cluster.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/KubernetesQuotaSumDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /keycloak/groups:
    get:
      tags:
      - Keycloak
      summary: Admin only
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List of groups in the master realm.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/KeycloakGroupDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /keycloak/groups/name/{groupName}/members:
    get:
      tags:
      - Keycloak
      summary: Admin only
      parameters:
      - name: groupName
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List of members for the requested group inside the master realm.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/KeycloakUserDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /keycloak/token:
    post:
      tags:
      - Keycloak
      summary: Public API
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CredentialsDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Bridge to log in into keycloak without using its UI.
          content:
            application/json:
              example:
                access_token: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJLM3A1Z2pxQUJsUUNUS3FISkZrM1RaUHBIbGttUWZhVWl3blFEN1N6ZEZZIn0.XXXX.XXXXX
                expires_in: 36000
                refresh_expires_in: 1800
                refresh_token: eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIwNTJiZDlkYS1jOGQ4LTQ0ODMtODAwZS1jM2YxMDM5MDQ4MTgifQ.XXXX.XXXX
                token_type: Bearer
                not-before-policy: 0
                session_state: 8b5e089c-e3c5-4a65-adbd-bec46d85704b
                scope: email profile
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /migration/helper/username:
    get:
      tags:
      - Migration
      summary: Resolve a CodeFirst username from an email address
      parameters:
      - name: email
        in: query
        schema:
          type: string
      responses:
        "200":
          description: Return the CodeFirst username matching the given email address.
          content:
            application/json:
              schema:
                type: string
        "404":
          description: No user matches the given email address.
  /monitoring/kubernetes/tokens/count:
    get:
      tags:
      - Monitoring
      summary: Admin only or feature STATISTICS
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Return the total and available Kubernetes token counts for
            the cluster.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/KubernetesCountTokenDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /monitoring/requests/countByStatusCode:
    get:
      tags:
      - Monitoring
      summary: Admin only or feature STATISTICS
      parameters:
      - name: since
        in: query
        schema:
          $ref: '#/components/schemas/Date'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Return the number of responses grouped by HTTP status code
            since the given date.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CountByResponseStatusCodeDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /monitoring/requests/countPerRequest:
    get:
      tags:
      - Monitoring
      summary: Admin only or feature STATISTICS
      parameters:
      - name: since
        in: query
        schema:
          $ref: '#/components/schemas/Date'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Return the number of calls grouped by request path since the
            given date.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CountByRequestDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /monitoring/requests/errors:
    get:
      tags:
      - Monitoring
      summary: Admin only or feature STATISTICS
      parameters:
      - name: since
        in: query
        schema:
          $ref: '#/components/schemas/Date'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List recorded errors since the given date (defaults to the
            last seven days).
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ErrorMonitoringDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /monitoring/requests/errors/topClasses:
    get:
      tags:
      - Monitoring
      summary: Top exception classes by count (admin or feature STATISTICS)
      parameters:
      - name: limit
        in: query
        schema:
          format: int32
          default: 5
          type: integer
      - name: since
        in: query
        schema:
          $ref: '#/components/schemas/Date'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Return the top exception classes ranked by occurrence count
            since the given date.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CountByErrorClassDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /monitoring/requests/timeseries:
    get:
      tags:
      - Monitoring
      summary: Daily request and error volume (admin or feature STATISTICS)
      parameters:
      - name: since
        in: query
        schema:
          $ref: '#/components/schemas/Date'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Return the daily request and error volume since the given date.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RequestTimeseriesDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /organisations:
    get:
      tags:
      - Organisation
      summary: Admin only
      parameters:
      - name: page
        in: query
        schema:
          format: int32
          default: 0
          type: integer
      - name: size
        in: query
        schema:
          format: int32
          default: 20
          type: integer
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Paginated list of organisations.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PageDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
    post:
      tags:
      - Organisation
      summary: Admin only
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateOrganisationDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: "The organisation has been created, or the existing one with\
            \ its GitLab group ensured."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganisationDTO'
        "400":
          description: "A required field is missing (name, or odinDepartmentParameter\
            \ when the sync source is ODIN)."
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /organisations/me:
    get:
      tags:
      - Organisation
      summary: Get the organisations of the current user
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: The organisation the current user belongs to.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganisationDTO'
        "404":
          description: The current user could not be found.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /organisations/{id}/failed-users:
    get:
      tags:
      - Organisation
      summary: Admin only - Get users with failed sync status
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: The users of this organisation whose last synchronization failed.
        "404":
          description: No organisation with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /organisations/{id}/members/autocomplete:
    get:
      tags:
      - Organisation
      summary: List organisation members for autocompletion
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: "Members of the organisation, suitable for autocompletion (full\
            \ name and username)."
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AutocompleteMemberDTO'
        "404":
          description: No organisation with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /organisations/{id}/retry-failed:
    post:
      tags:
      - Organisation
      summary: Admin only - Retry failed users synchronization
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "202":
          description: Retry synchronization has been started in the background.
        "404":
          description: No organisation with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /organisations/{id}/sync:
    post:
      tags:
      - Organisation
      summary: Admin only - Asynchronous synchronization
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: scope
        in: query
        schema:
          default: ALL
          enum:
          - TEACHERS
          - STUDENTS
          - ALL
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "202":
          description: Synchronization has been started in the background.
        "404":
          description: No organisation with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /platform/announcements:
    get:
      tags:
      - Platform
      summary: Annonces actives affichées sur Néon (cloche notifications).
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List the platform announcements currently active for the authenticated
            user.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PlatformAnnouncementDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /portfolios/me/status:
    get:
      tags:
      - Portfolio
      summary: Cached reachability status of the current user's portfolio (K8s state
        + HTTP probe)
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /portfolios/me/status/refresh:
    post:
      tags:
      - Portfolio
      summary: Re-probe the current user's portfolio on demand (one call per user
        per 5 minutes)
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "429":
          description: A manual probe was already requested less than 5 minutes ago.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /quota-requests:
    post:
      tags:
      - Quota Requests
      summary: Create a quota request for a namespace the current user has access
        to
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateQuotaRequestDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The quota request has been created.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /quota-requests/{id}/approve:
    post:
      tags:
      - Quota Requests
      summary: Admin only
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QuotaReasonDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The quota request has been approved and the namespace quota
            updated.
        "404":
          description: No quota request with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /quota-requests/{id}/reject:
    post:
      tags:
      - Quota Requests
      summary: Admin only
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QuotaReasonDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The quota request has been rejected.
        "404":
          description: No quota request with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /teacher/portfolios:
    get:
      tags:
      - Portfolio
      summary: Teacher/admin - paginated students of the org with their portfolio
        reachability status
      parameters:
      - name: page
        in: query
        schema:
          format: int32
          default: 0
          type: integer
      - name: search
        in: query
        schema:
          type: string
      - name: size
        in: query
        schema:
          format: int32
          default: 20
          type: integer
      - name: status
        in: query
        schema:
          type: string
      - name: year
        in: query
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-teachers
        - cf-admin
  /teacher/portfolios/export:
    get:
      tags:
      - Portfolio
      summary: Teacher/admin - Excel export of all the org's students with their portfolio
        status
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-teachers
        - cf-admin
  /teacher/portfolios/{username}/probe:
    post:
      tags:
      - Portfolio
      summary: Teacher/admin - re-probe on demand the reachability of a single student's
        portfolio
      parameters:
      - name: username
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-teachers
        - cf-admin
  /users:
    get:
      tags:
      - Users
      summary: "Admin only: List all local users (paginated)"
      parameters:
      - name: page
        in: query
        schema:
          format: int32
          default: 0
          type: integer
      - name: size
        in: query
        schema:
          format: int32
          default: 20
          type: integer
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Paginated list of local users.
          content: {}
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
    post:
      tags:
      - Users
      summary: "Admin only: Create a new local user"
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateUserDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "201":
          description: Local user created successfully.
          content: {}
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /users/groups:
    get:
      tags:
      - Users
      summary: "List the GitLab groups the current user can access, with their namespaces"
      parameters:
      - name: full
        in: query
        schema:
          default: "false"
          type: boolean
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List all existing Gitlab Groups the current user has access
            to and their associated namespaces if any.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/UserGroupDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /users/me:
    get:
      tags:
      - Users
      summary: Get the current user's profile information
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Return the profile information of the currently logged in user.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserDTO'
        "404":
          description: No user matching the authenticated identity could be found.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /users/me/features:
    get:
      tags:
      - Users
      summary: List the features activated for the current user
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List all features activated for the logged in user.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/FeatureDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /users/me/features/{id}:
    delete:
      tags:
      - Users
      summary: Teacher and admin only
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The feature has been revoked from the current user.
        "404":
          description: No feature with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /users/me/features/{id}/assign:
    post:
      tags:
      - Users
      summary: Teacher and admin only
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The feature has been assigned to the current user.
        "404":
          description: No feature with this id exists.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /users/me/gamification/quests:
    get:
      tags:
      - Gamification
      summary: Catalogue des quêtes étudiant et progression (vide pour non-étudiants)
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/StudentQuestStatusDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /users/me/gamification/summary:
    get:
      tags:
      - Gamification
      summary: Synthèse XP / quêtes complétées
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GamificationSummaryDTO'
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /users/me/gitlab-token:
    put:
      tags:
      - Users
      summary: Save the current user's personal GitLab access token (PAT)
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SetGitlabTokenDTO'
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: The GitLab personal access token has been saved.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserDTO'
        "400":
          description: "The token is missing, invalid or expired."
        "404":
          description: No user matching the authenticated identity could be found.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
    delete:
      tags:
      - Users
      summary: Remove the current user's personal GitLab access token (PAT)
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: The GitLab personal access token has been removed.
        "404":
          description: No user matching the authenticated identity could be found.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme: []
  /users/organization/{organizationId}:
    get:
      tags:
      - Users
      summary: "Admin only: Get all local users by organization ID"
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: List of local users for the organization.
          content: {}
        "404":
          description: No local users found for the organization.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /users/username/{username}:
    get:
      tags:
      - Users
      summary: "Admin only: Get a local user by username"
      parameters:
      - name: username
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Local user found.
          content: {}
        "404":
          description: Local user not found.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /users/{id}:
    get:
      tags:
      - Users
      summary: "Admin only: Get a local user by ID"
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "200":
          description: Local user found.
          content: {}
        "404":
          description: Local user not found.
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
    delete:
      tags:
      - Users
      summary: "Admin only: Delete a local user by email"
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        "403":
          description: User does not have enough visibility to access the requested
            resource.
        "204":
          description: "Local user deleted successfully from Keycloak, GitLab, and\
            \ DB."
        "401":
          description: Not Authorized
      security:
      - SecurityScheme:
        - cf-admin
  /version:
    get:
      tags:
      - Version
      summary: Public backend version
      responses:
        "200":
          description: "Returns the backend version as {\"version\": \"...\"}."
          content:
            application/json:
              schema:
                type: string
components:
  schemas:
    AccessLevel:
      enum:
      - -1
      - 0
      - 5
      - 10
      - 20
      - 30
      - 40
      - 40
      - 50
      - 60
      type: string
    AdminPlatformAnnouncementDTO:
      type: object
      properties:
        id:
          type: string
        message:
          type: string
        startsAt:
          $ref: '#/components/schemas/Date'
        endsAt:
          $ref: '#/components/schemas/Date'
        dismissable:
          type: boolean
        theme:
          type: string
        disabled:
          type: boolean
        displayStatus:
          type: string
        gitlabBroadcastMessageId:
          format: int64
          type: integer
        gitlabSyncStatus:
          type: string
        gitlabSyncError:
          type: string
        createdAt:
          $ref: '#/components/schemas/Date'
        updatedAt:
          $ref: '#/components/schemas/Date'
    AdminStudentGamificationDetailDTO:
      type: object
      properties:
        username:
          type: string
        fullName:
          type: string
        summary:
          $ref: '#/components/schemas/GamificationSummaryDTO'
        quests:
          type: array
          items:
            $ref: '#/components/schemas/StudentQuestStatusDTO'
    AdminStudentGamificationPageDTO:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/AdminStudentGamificationRowDTO'
        total:
          format: int64
          type: integer
        page:
          format: int32
          type: integer
        size:
          format: int32
          type: integer
    AdminStudentGamificationRowDTO:
      type: object
      properties:
        username:
          type: string
        fullName:
          type: string
        summary:
          $ref: '#/components/schemas/GamificationSummaryDTO'
    AdminWhitelistEntryDTO:
      type: object
      properties:
        id:
          type: string
        email:
          type: string
        createdAt:
          $ref: '#/components/schemas/Date'
        managedInDatabase:
          type: boolean
    AnnotationDTO:
      type: object
      properties:
        key:
          type: string
        value:
          type: string
    ApiStatsDTO:
      type: object
      properties:
        totalResponses:
          format: int64
          type: integer
        count2xx:
          format: int64
          type: integer
        count4xx:
          format: int64
          type: integer
        count5xx:
          format: int64
          type: integer
        percent2xx:
          format: double
          type: number
        percent4xx:
          format: double
          type: number
        percent5xx:
          format: double
          type: number
        distinctErrors:
          format: int64
          type: integer
    AutocompleteMemberDTO:
      type: object
      properties:
        fullName:
          type: string
        username:
          type: string
    CacheGitlabGroupDTO:
      type: object
      properties:
        name:
          type: string
        gitlabGroupId:
          format: int64
          type: integer
        groupFullPath:
          type: string
        accessLevel:
          $ref: '#/components/schemas/AccessLevel'
        saeType:
          $ref: '#/components/schemas/SaeType'
        canAccessPVC:
          type: boolean
    CacheGitlabGroupDetailsDTO:
      type: object
      properties:
        name:
          type: string
        fullPath:
          type: string
        gitlabId:
          format: int64
          type: integer
        createdAt:
          $ref: '#/components/schemas/Date'
        saeType:
          $ref: '#/components/schemas/SaeType'
        canAccessPVC:
          type: boolean
        organizationId:
          $ref: '#/components/schemas/ObjectId'
        studentsCanCreateRepository:
          type: boolean
        directMembers:
          type: array
          items:
            $ref: '#/components/schemas/EmbedGitlabUserDTO'
        studentListGroups:
          type: array
          items:
            $ref: '#/components/schemas/EmbedStudentListGroupDTO'
    CleanedGroupStat:
      type: object
      properties:
        organisationName:
          type: string
        gitlabId:
          format: int64
          type: integer
        groupName:
          type: string
        removedMembers:
          format: int32
          type: integer
    CommentDTO:
      type: object
      properties:
        content:
          type: string
    CountByErrorClassDTO:
      type: object
      properties:
        javaClass:
          type: string
        count:
          format: int64
          type: integer
    CountByRequestDTO:
      type: object
      properties:
        count:
          format: int64
          type: integer
        uri:
          type: string
        method:
          type: string
    CountByResponseStatusCodeDTO:
      type: object
      properties:
        count:
          format: int64
          type: integer
        statusCode:
          type: string
    CountDTO:
      type: object
      properties:
        count:
          format: int64
          type: integer
    CountObjectDTO:
      type: object
      properties:
        namespaces:
          format: int64
          type: integer
        pods:
          format: int64
          type: integer
    CreateAdminWhitelistEntryDTO:
      type: object
      properties:
        email:
          type: string
    CreateGitlabTemplateDTO:
      required:
      - name
      - gitRepositoryUrl
      type: object
      properties:
        name:
          maxLength: 255
          pattern: \S
          type: string
        gitRepositoryUrl:
          maxLength: 2000
          pattern: \S
          type: string
    CreateIssueDTO:
      required:
      - title
      - type
      type: object
      properties:
        title:
          maxLength: 255
          pattern: \S
          type: string
        description:
          maxLength: 10000
          type: string
        type:
          pattern: \S
          type: string
        labels:
          type: array
          items:
            type: string
    CreateOrganisationDTO:
      required:
      - name
      - syncSource
      type: object
      properties:
        id:
          type: string
        name:
          maxLength: 255
          pattern: \S
          type: string
        syncSource:
          pattern: \S
          type: string
        createdAt:
          $ref: '#/components/schemas/Date'
        lastSyncAt:
          $ref: '#/components/schemas/Date'
        studentEmailPattern:
          type: string
        teacherEmailPattern:
          type: string
        temporaryTeacherEmailPattern:
          type: string
        odinDepartmentParameter:
          type: string
        ciGenActive:
          type: boolean
    CreateProjectFromTemplateDTO:
      required:
      - projectName
      type: object
      properties:
        projectName:
          maxLength: 255
          pattern: \S
          type: string
        variables:
          type: object
          additionalProperties:
            type: string
        description:
          maxLength: 2000
          type: string
    CreateQuotaRequestDTO:
      required:
      - namespace
      type: object
      properties:
        namespace:
          pattern: \S
          type: string
        cpu:
          type: string
        ram:
          type: string
        justification:
          maxLength: 2000
          type: string
    CreateUserDTO:
      required:
      - email
      - username
      - organizationId
      type: object
      properties:
        email:
          maxLength: 255
          pattern: \S
          type: string
        username:
          maxLength: 255
          pattern: \S
          type: string
        firstName:
          maxLength: 255
          type: string
        lastName:
          maxLength: 255
          type: string
        organizationId:
          pattern: \S
          type: string
        keycloakGroupName:
          maxLength: 255
          type: string
    CreatedProjectDTO:
      type: object
      properties:
        webUrl:
          type: string
        pathWithNamespace:
          type: string
        projectId:
          format: int64
          type: integer
    CredentialsDTO:
      type: object
      properties:
        username:
          type: string
        password:
          type: string
        clientId:
          type: string
        clientSecret:
          type: string
    CronJobDTO:
      type: object
      properties:
        name:
          type: string
        cronExpression:
          type: string
        enabled:
          type: boolean
        defaultEnabled:
          type: boolean
        parameterDefinitions:
          type: array
          items:
            $ref: '#/components/schemas/JobParameterDefinitionDTO'
        parameters:
          type: object
          additionalProperties:
            type: string
    CronJobExecutionLogDTO:
      type: object
      properties:
        id:
          type: string
        jobName:
          type: string
        at:
          $ref: '#/components/schemas/Date'
        endedAt:
          $ref: '#/components/schemas/Date'
        succeeded:
          type: boolean
        status:
          $ref: '#/components/schemas/JobExecutionStatus'
        triggeredBy:
          type: string
        errorMessage:
          type: string
        namespacesDeleted:
          format: int64
          type: integer
        projectsUpdated:
          format: int64
          type: integer
        projectsFailed:
          format: int64
          type: integer
        failedProjects:
          type: array
          items:
            type: string
        membersSyncReport:
          $ref: '#/components/schemas/MembersSyncJobReport'
        affectedResources:
          type: array
          items:
            $ref: '#/components/schemas/JobAffectedResource'
    DailyCount:
      type: object
      properties:
        date:
          type: string
        count:
          format: int64
          type: integer
    Date:
      format: date
      type: string
      example: 2022-03-10
    DefaultNamespaceQuotaSettingDTO:
      type: object
      properties:
        ramLimit:
          type: string
        ramRequest:
          type: string
        cpuLimit:
          type: string
        cpuRequest:
          type: string
    DescribeFieldDTO:
      type: object
      properties:
        type:
          type: string
        name:
          type: string
        question:
          type: string
        required:
          type: boolean
        default: {}
        fields:
          type: array
          items:
            $ref: '#/components/schemas/DescribeFieldDTO'
    EmbedGitlabUserDTO:
      type: object
      properties:
        name:
          type: string
        gitlabId:
          format: int64
          type: integer
        accessLevel:
          $ref: '#/components/schemas/AccessLevel'
        fullName:
          type: string
    EmbedOrganisationStudentGroupDTO:
      type: object
      properties:
        gitlabId:
          format: int64
          type: integer
        name:
          type: string
    EmbedStudentListGroupDTO:
      type: object
      properties:
        name:
          type: string
        gitlabId:
          format: int64
          type: integer
        accessLevel:
          $ref: '#/components/schemas/AccessLevel'
    ErrorMonitoringDTO:
      type: object
      properties:
        id:
          type: string
        exception:
          type: string
        cause:
          type: string
        at:
          $ref: '#/components/schemas/Date'
        stacktrace:
          type: string
        javaClass:
          type: string
        requestId:
          type: string
    FeatureDTO:
      type: object
      properties:
        name:
          type: string
        id:
          type: string
        featureId:
          $ref: '#/components/schemas/ObjectId'
        mode:
          type: string
        defaultVisibilityRole:
          type: string
    GamificationSummaryDTO:
      type: object
      properties:
        totalXp:
          format: int32
          type: integer
        completedQuests:
          format: int64
          type: integer
        totalQuestsInCatalog:
          format: int64
          type: integer
        currentLevel:
          format: int32
          type: integer
        xpIntoCurrentLevel:
          format: int32
          type: integer
        xpRequiredForNextLevel:
          format: int32
          type: integer
        progressPercentToNextLevel:
          format: int32
          type: integer
        maxLevelReached:
          type: boolean
    GitlabGroupMembersDTO:
      type: object
      properties:
        usernames:
          type: array
          items:
            type: string
        groupsIds:
          type: array
          items:
            format: int64
            type: integer
        accessLevel:
          $ref: '#/components/schemas/AccessLevel'
        orgId:
          type: string
    GitlabTemplateDTO:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        gitRepositoryUrl:
          type: string
        createdByUsername:
          type: string
        createdAt:
          $ref: '#/components/schemas/Date'
        updatedAt:
          $ref: '#/components/schemas/Date'
    GitlabUserCustomization:
      type: object
      properties:
        themeId:
          format: int32
          type: integer
        colorSchemeId:
          format: int64
          type: integer
        colorModeId:
          format: int32
          type: integer
    GroupDTO:
      type: object
      properties:
        id:
          format: int64
          type: integer
        name:
          type: string
        shortName:
          type: string
        path:
          type: string
        parentId:
          format: int64
          type: integer
    ImpersonationTokenDTO:
      type: object
      properties:
        accessToken:
          type: string
        expiresIn:
          format: int64
          type: integer
        username:
          type: string
        displayName:
          type: string
        isTeacher:
          type: boolean
        isAdmin:
          type: boolean
        teacher:
          type: boolean
        admin:
          type: boolean
    ImportRbacTokenDTO:
      type: object
      properties:
        user:
          type: string
        secret:
          type: string
    ImportStatus:
      type: object
      properties:
        count:
          format: int64
          type: integer
        status:
          $ref: '#/components/schemas/Status'
    InputGroupDTO:
      type: object
      properties:
        orgId:
          type: string
        name:
          type: string
        parentGroupId:
          format: int64
          type: integer
        studentsCanCreateRepository:
          type: boolean
    InputProjectDTO:
      type: object
      properties:
        name:
          type: string
        parentGroupId:
          format: int64
          type: integer
    IssueCommentDTO:
      type: object
      properties:
        id:
          type: string
        author:
          type: string
        createdAt:
          $ref: '#/components/schemas/Date'
        updatedAt:
          $ref: '#/components/schemas/Date'
        content:
          type: string
    IssueDTO:
      type: object
      properties:
        id:
          type: string
        title:
          maxLength: 255
          type: string
        description:
          maxLength: 10000
          type: string
        type:
          type: string
        labels:
          type: array
          items:
            type: string
        severity:
          type: string
        author:
          type: string
        assignee:
          type: string
        createdAt:
          $ref: '#/components/schemas/Date'
        updatedAt:
          $ref: '#/components/schemas/Date'
        closedAt:
          $ref: '#/components/schemas/Date'
        closedBy:
          type: string
        comments:
          type: array
          items:
            $ref: '#/components/schemas/IssueCommentDTO'
        namespace:
          type: string
        cpu:
          type: string
        status:
          type: string
        ram:
          type: string
        reason:
          type: string
    JobAffectedResource:
      type: object
      properties:
        resourceType:
          type: string
        resourceName:
          type: string
        action:
          type: string
        detail:
          type: string
    JobExecutionStatus:
      enum:
      - RUNNING
      - SUCCEEDED
      - FAILED
      type: string
    JobParameterDefinitionDTO:
      type: object
      properties:
        key:
          type: string
        label:
          type: string
        type:
          type: string
        defaultValue:
          type: string
        allowedValues:
          type: array
          items:
            type: string
    KeycloakGroupDTO:
      type: object
      properties:
        name:
          type: string
        path:
          type: string
    KeycloakUserDTO:
      type: object
      properties:
        username:
          type: string
        email:
          type: string
    KubernetesCountTokenDTO:
      type: object
      properties:
        total:
          format: int64
          type: integer
        available:
          format: int64
          type: integer
    KubernetesLogsDTO:
      type: object
      properties:
        logs:
          type: string
    KubernetesQuotaSumDTO:
      type: object
      properties:
        totalCPU:
          type: string
        totalRAM:
          type: string
    MembersSyncJobReport:
      type: object
      properties:
        retryJob:
          type: boolean
        organisationsProcessed:
          format: int32
          type: integer
        organisationsFailed:
          format: int32
          type: integer
        studentsAdded:
          format: int64
          type: integer
        studentsUpdated:
          format: int64
          type: integer
        teachersAdded:
          format: int64
          type: integer
        teachersUpdated:
          format: int64
          type: integer
        vacatairesAdded:
          format: int64
          type: integer
        vacatairesUpdated:
          format: int64
          type: integer
        failedMembers:
          format: int64
          type: integer
        retriesPerformed:
          format: int64
          type: integer
        gitlabRateLimitHits:
          format: int64
          type: integer
        retriedCount:
          format: int64
          type: integer
        succeededCount:
          format: int64
          type: integer
        stillFailedCount:
          format: int64
          type: integer
        failedMemberUsernames:
          type: array
          items:
            type: string
        studentGroups:
          type: array
          items:
            $ref: '#/components/schemas/StudentGroupStat'
        cleanedGroups:
          type: array
          items:
            $ref: '#/components/schemas/CleanedGroupStat'
        organisations:
          type: array
          items:
            $ref: '#/components/schemas/OrganisationSyncReport'
    MetadataDTO:
      type: object
      properties:
        owner:
          type: string
        createdAt:
          type: string
        name:
          type: string
    NamespaceDTO:
      type: object
      properties:
        metadata:
          $ref: '#/components/schemas/MetadataDTO'
        quota:
          $ref: '#/components/schemas/QuotaDTO'
    NamespaceDetailDTO:
      type: object
      properties:
        metadata:
          $ref: '#/components/schemas/MetadataDTO'
        quota:
          $ref: '#/components/schemas/QuotaDTO'
        pods:
          type: array
          items:
            $ref: '#/components/schemas/PodDTO'
        totalRamUsed:
          type: string
        totalCpuUsed:
          type: string
        totalRamUsage:
          type: number
        totalCpuUsage:
          type: number
        metricsAvailable:
          type: boolean
        persistentVolumeClaims:
          type: array
          items:
            $ref: '#/components/schemas/PersistentVolumeClaimDTO'
        saeType:
          $ref: '#/components/schemas/SaeType'
        canAccessPVC:
          type: boolean
    ObjectId:
      type: object
      properties:
        timestamp:
          format: int32
          type: integer
        counter:
          format: int32
          type: integer
        randomValue1:
          format: int32
          type: integer
        randomValue2:
          type: integer
        date:
          $ref: '#/components/schemas/Date'
    OrganisationDTO:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        syncSource:
          type: string
        createdAt:
          $ref: '#/components/schemas/Date'
        lastSyncAt:
          $ref: '#/components/schemas/Date'
        studentEmailPattern:
          type: string
        teacherEmailPattern:
          type: string
        temporaryTeacherEmailPattern:
          type: string
        gitlabTopLevelGroupId:
          format: int64
          type: integer
        gitlabStudentProjectsGroupId:
          format: int64
          type: integer
        studentGroups:
          type: array
          items:
            $ref: '#/components/schemas/EmbedOrganisationStudentGroupDTO'
    OrganisationSyncReport:
      type: object
      properties:
        organisationName:
          type: string
        ok:
          type: boolean
        errorMessage:
          type: string
        studentsAdded:
          format: int64
          type: integer
        studentsUpdated:
          format: int64
          type: integer
        teachersAdded:
          format: int64
          type: integer
        teachersUpdated:
          format: int64
          type: integer
        vacatairesAdded:
          format: int64
          type: integer
        vacatairesUpdated:
          format: int64
          type: integer
        failedMembers:
          format: int64
          type: integer
        failedMemberUsernames:
          type: array
          items:
            type: string
        studentGroups:
          type: array
          items:
            $ref: '#/components/schemas/StudentGroupStat'
        cleanedGroups:
          type: array
          items:
            $ref: '#/components/schemas/CleanedGroupStat'
    PageDTO:
      type: object
      properties:
        items:
          type: array
          items: {}
        total:
          format: int64
          type: integer
        page:
          format: int32
          type: integer
        size:
          format: int32
          type: integer
    PersistentVolumeClaimDTO:
      type: object
      properties:
        name:
          type: string
        namespace:
          type: string
        accessMode:
          type: string
        storage:
          type: number
    PlatformAnnouncementDTO:
      type: object
      properties:
        id:
          type: string
        message:
          type: string
        startsAt:
          $ref: '#/components/schemas/Date'
        endsAt:
          $ref: '#/components/schemas/Date'
        theme:
          type: string
        updatedAt:
          $ref: '#/components/schemas/Date'
    PlatformStatsDTO:
      type: object
      properties:
        pendingQuotaRequests:
          format: int64
          type: integer
        openIssues:
          format: int64
          type: integer
        studentsWithQuestProgress:
          format: int64
          type: integer
        totalStudents:
          format: int64
          type: integer
    PodDTO:
      type: object
      properties:
        name:
          type: string
        appLabel:
          type: string
        namespace:
          type: string
        image:
          type: string
        quota:
          $ref: '#/components/schemas/QuotaDTO'
        usage:
          $ref: '#/components/schemas/PodUsageDTO'
        status:
          $ref: '#/components/schemas/PodStatusDTO'
        annotations:
          type: array
          items:
            $ref: '#/components/schemas/AnnotationDTO'
        port:
          type: string
    PodStatusDTO:
      type: object
      properties:
        message:
          type: string
        phase:
          type: string
        reason:
          type: string
        startTime:
          type: string
        containerWaitingReason:
          type: string
        containerWaitingMessage:
          type: string
        restartCount:
          format: int32
          type: integer
    PodUsageDTO:
      type: object
      properties:
        cpuUsed:
          type: number
        ramUsed:
          type: number
        window:
          type: string
        timestamp:
          type: string
    PortfolioTokenDTO:
      type: object
      properties:
        token:
          type: string
        user:
          type: string
        namespace:
          type: string
        containerName:
          type: string
    ProjectDTO:
      type: object
      properties:
        id:
          format: int64
          type: integer
        name:
          type: string
        path:
          type: string
    ProjectMembersDTO:
      type: object
      properties:
        directMembers:
          type: array
          items:
            $ref: '#/components/schemas/EmbedGitlabUserDTO'
        studentListGroups:
          type: array
          items:
            $ref: '#/components/schemas/EmbedStudentListGroupDTO'
    QuotaDTO:
      type: object
      properties:
        cpuLimit:
          type: number
        ramLimit:
          type: number
    QuotaReasonDTO:
      type: object
      properties:
        reason:
          type: string
    RbacTokenDTO:
      type: object
      properties:
        id:
          type: string
        user:
          type: string
        secret:
          type: string
        inUseSince:
          $ref: '#/components/schemas/Date'
        inUseBy:
          type: string
        available:
          type: boolean
        portfolioOwner:
          type: string
    RbacTokenHistoryDTO:
      type: object
      properties:
        id:
          type: string
        who:
          type: string
        rbacToken:
          $ref: '#/components/schemas/RbacTokenDTO'
        action:
          type: string
    RequestTimeseriesDTO:
      type: object
      properties:
        requestVolume:
          type: array
          items:
            $ref: '#/components/schemas/DailyCount'
        errorVolume:
          type: array
          items:
            $ref: '#/components/schemas/DailyCount'
    ResponseStatus:
      enum:
      - FAILED
      - SUCCESS
      type: string
    SaeType:
      enum:
      - NONE
      - SAE_2A
      - SAE_3A
      - CAN_CONTAINS_CONTAINERS
      type: string
    SetGitlabTokenDTO:
      required:
      - token
      type: object
      properties:
        token:
          maxLength: 512
          pattern: \S
          type: string
    StatisticsOverviewDTO:
      type: object
      properties:
        platform:
          $ref: '#/components/schemas/PlatformStatsDTO'
        api:
          $ref: '#/components/schemas/ApiStatsDTO'
    Status:
      enum:
      - OK
      - KO
      type: string
    StudentGroupStat:
      type: object
      properties:
        organisationName:
          type: string
        groupName:
          type: string
        studentCount:
          format: int32
          type: integer
    StudentQuestStatusDTO:
      type: object
      properties:
        questId:
          type: string
        slug:
          type: string
        title:
          type: string
        descriptionPedagogique:
          type: string
        academicTier:
          type: string
        xpReward:
          format: int32
          type: integer
        completed:
          type: boolean
        completedAtEpochMs:
          format: int64
          type: integer
        prerequisitesMet:
          type: boolean
        prerequisiteTitles:
          type: array
          items:
            type: string
    TemplateDescribeDTO:
      type: object
      properties:
        fields:
          type: array
          items:
            $ref: '#/components/schemas/DescribeFieldDTO'
    TemplateVariablesDTO:
      type: object
      properties:
        variables:
          type: object
          additionalProperties:
            type: string
    UpdateAdminWhitelistEntryDTO:
      type: object
      properties:
        email:
          type: string
    UpdateCacheGitlabGroupDTO:
      type: object
      properties:
        saeType:
          $ref: '#/components/schemas/SaeType'
        canAccessPVC:
          type: boolean
    UpdateCronJobEnabledDTO:
      type: object
      properties:
        enabled:
          type: boolean
    UpdateCronJobParametersDTO:
      type: object
      properties:
        parameters:
          type: object
          additionalProperties:
            type: string
    UpdateGitlabTemplateDTO:
      type: object
      properties:
        name:
          type: string
        gitRepositoryUrl:
          type: string
    UpdateIssueDTO:
      type: object
      properties:
        id:
          type: string
        title:
          maxLength: 255
          type: string
        description:
          maxLength: 10000
          type: string
        type:
          type: string
        labels:
          type: array
          items:
            type: string
        severity:
          type: string
    UpsertPlatformAnnouncementDTO:
      type: object
      properties:
        message:
          type: string
        startsAt:
          $ref: '#/components/schemas/Date'
        endsAt:
          $ref: '#/components/schemas/Date'
        dismissable:
          type: boolean
        theme:
          type: string
    UserDTO:
      type: object
      properties:
        id:
          type: string
        createdAt:
          type: string
        username:
          type: string
        isTeacher:
          type: boolean
        isVacataire:
          type: boolean
        gitlabId:
          format: int64
          type: integer
        organizationId:
          type: string
        groups:
          uniqueItems: true
          type: array
          items:
            format: int64
            type: integer
        hasGitlabToken:
          type: boolean
    UserGroupDTO:
      type: object
      properties:
        name:
          type: string
        namespace:
          $ref: '#/components/schemas/UserGroupNamespaceDTO'
    UserGroupNamespaceDTO:
      type: object
      properties:
        name:
          type: string
        createdAt:
          type: string
        deletionTimestamp:
          type: string
        podsCount:
          format: int64
          type: integer
    UserUpdateStatusDTO:
      type: object
      properties:
        status:
          $ref: '#/components/schemas/ResponseStatus'
  securitySchemes:
    SecurityScheme:
      type: openIdConnect
      description: Authentication
      openIdConnectUrl: https://codefirst.iut.uca.fr/keycloak/realms/master/.well-known/openid-configuration
