openapi: 3.0.3
info:
  title: 'Family Tree API — شجرة العائلة'
  description: "REST API for the Flutter app of one family: the full tree with every member's profile (alive or deceased), family news with comments and likes, and staff whose changes the admin approves."
  version: 1.0.0
servers:
  -
    url: 'https://api-production-34bd.up.railway.app'
tags:
  -
    name: Auth
    description: "\nRegistration, login and password reset. Every token is per device."
  -
    name: Meta
    description: "\nPublic lookup data for the app: languages, enum labels and public settings."
  -
    name: Family
    description: "\nThe app shows one family. Its details and settings live here; the persons, graph and news hang off it."
  -
    name: Persons
    description: "\nPeople of a tree. Text fields are translatable: send `{\"ar\": \"...\", \"en\": \"...\"}`,\nor a plain string together with the `Content-Language` header."
  -
    name: 'Family relations'
    description: "\nLineage goes through the father: every son and daughter belongs to their father, eldest first."
  -
    name: Graph
    description: "\nData for the canvas: `nodes` and `families` (each father in view with his sons and daughters, eldest first).\nSend `If-None-Match` with the last ETag to get 304 when nothing changed."
  -
    name: 'Family news'
    description: "\nPosts with images and tagged family members. Anyone can read published posts.\nStaff without `posts.direct` get `202` with a change request instead of saving."
  -
    name: 'Change requests'
    description: "\nStaff writes without a `*.direct` permission return `202` with a change request instead of saving.\nThe admin (or anyone with `changes.review`) approves or rejects it; approval applies the original call."
  -
    name: Notifications
    description: "\nIn-app notifications. The admin gets one for every staff action (saved directly or waiting for approval);\nstaff get one when their request is approved or rejected."
  -
    name: 'Admin — Users'
    description: "\nUsers and staff, managed by the admin from the app."
  -
    name: 'Admin — Languages'
    description: "\nLanguages available for translatable data. Adding one makes it accepted in every translatable field."
  -
    name: 'Admin — Settings'
    description: ''
  -
    name: 'Admin — System'
    description: ''
components:
  securitySchemes:
    default:
      type: http
      scheme: bearer
      description: 'Get a token from <code>POST /api/v1/auth/login</code> and send it as <code>Authorization: Bearer {TOKEN}</code>.'
security:
  -
    default: []
paths:
  /api/v1/auth/register:
    post:
      summary: Register
      operationId: register
      description: 'Creates an account with the `user` role and returns an API token.'
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Auth
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: 'يجب ألا يتجاوز طول value 150 حرفاً.'
                  example: vmqeopfuudtdsufvyvddq
                email:
                  type: string
                  description: 'يجب أن يكون value بريداً إلكترونياً صحيحاً. يجب ألا يتجاوز طول value 191 حرفاً.'
                  example: kunde.eloisa@example.com
                phone:
                  type: string
                  description: 'يجب ألا يتجاوز طول value 30 حرفاً.'
                  example: hfqcoynlazghdtqtqxbaj
                  nullable: true
                password:
                  type: string
                  description: ''
                  example: consequatur
                locale:
                  type: string
                  description: ''
                  example: null
                  nullable: true
                device_name:
                  type: string
                  description: 'يجب ألا يتجاوز طول value 100 حرفاً.'
                  example: mqeopfuudtdsufvyvddqa
                  nullable: true
              required:
                - name
                - email
                - password
      security: []
  /api/v1/auth/login:
    post:
      summary: Login
      operationId: login
      description: 'Returns a Bearer token; send it as `Authorization: Bearer <token>`. The Postman collection saves it automatically.'
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Auth
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  description: 'يجب أن يكون value بريداً إلكترونياً صحيحاً.'
                  example: qkunze@example.com
                password:
                  type: string
                  description: ''
                  example: 'O[2UZ5ij-e/dl4m{o,'
                device_name:
                  type: string
                  description: 'يجب ألا يتجاوز طول value 100 حرفاً.'
                  example: dqamniihfqcoynlazghdt
                  nullable: true
              required:
                - email
                - password
      security: []
  /api/v1/auth/forgot-password:
    post:
      summary: 'Forgot password'
      operationId: forgotPassword
      description: 'Sends a reset token by email. Always answers 200 so registered emails are not revealed.'
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Auth
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  description: 'يجب أن يكون value بريداً إلكترونياً صحيحاً.'
                  example: qkunze@example.com
              required:
                - email
      security: []
  /api/v1/auth/reset-password:
    post:
      summary: 'Reset password'
      operationId: resetPassword
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Auth
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                token:
                  type: string
                  description: ''
                  example: consequatur
                email:
                  type: string
                  description: 'يجب أن يكون value بريداً إلكترونياً صحيحاً.'
                  example: carolyne.luettgen@example.org
                password:
                  type: string
                  description: ''
                  example: consequatur
              required:
                - token
                - email
                - password
      security: []
  /api/v1/auth/logout:
    post:
      summary: 'Logout (current device)'
      operationId: logoutcurrentDevice
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Auth
  /api/v1/auth/logout-all:
    post:
      summary: 'Logout from all devices'
      operationId: logoutFromAllDevices
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Auth
  /api/v1/auth/me:
    get:
      summary: 'My profile, roles and permissions'
      operationId: myProfileRolesAndPermissions
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Auth
    patch:
      summary: 'Update my profile'
      operationId: updateMyProfile
      description: '`locale` is the default response language when no Accept-Language header is sent.'
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Auth
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: 'يجب ألا يتجاوز طول value 150 حرفاً.'
                  example: vmqeopfuudtdsufvyvddq
                email:
                  type: string
                  description: 'يجب أن يكون value بريداً إلكترونياً صحيحاً. يجب ألا يتجاوز طول value 191 حرفاً.'
                  example: kunde.eloisa@example.com
                phone:
                  type: string
                  description: 'يجب ألا يتجاوز طول value 30 حرفاً.'
                  example: hfqcoynlazghdtqtqxbaj
                  nullable: true
                locale:
                  type: string
                  description: ''
                  example: null
    delete:
      summary: 'Delete my account'
      operationId: deleteMyAccount
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Auth
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                password:
                  type: string
                  description: ''
                  example: 'O[2UZ5ij-e/dl4m{o,'
              required:
                - password
  /api/v1/auth/me/password:
    put:
      summary: 'Change my password'
      operationId: changeMyPassword
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Auth
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                current_password:
                  type: string
                  description: ''
                  example: consequatur
                password:
                  type: string
                  description: ''
                  example: consequatur
              required:
                - current_password
                - password
  /api/v1/meta/languages:
    get:
      summary: 'Active languages'
      operationId: activeLanguages
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Meta
      security: []
  /api/v1/meta/enums:
    get:
      summary: 'Enums with translated labels'
      operationId: enumsWithTranslatedLabels
      description: 'Gendered Arabic labels are returned as `{ male, female }`.'
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Meta
      security: []
  /api/v1/meta/settings:
    get:
      summary: 'Public settings'
      operationId: publicSettings
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Meta
      security: []
  /api/v1/family:
    get:
      summary: 'Family details'
      operationId: familyDetails
      description: 'Name, description, root person, settings and counters.'
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Family
      security: []
    patch:
      summary: 'Update the family'
      operationId: updateTheFamily
      description: 'Admin only (`family.update`). `settings.lineage_depth` / `lineage_format` shape the lineage name ("محمد بن أحمد بن علي").'
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Family
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: object
                  description: Translatable.
                  example:
                    ar: 'عائلة الأطرش'
                    en: 'Al-Atrash Family'
                  properties: {  }
                description:
                  type: object
                  description: Translatable.
                  example:
                    ar: 'شجرة عائلة الأطرش'
                  properties: {  }
                  nullable: true
                default_locale:
                  type: string
                  description: ''
                  example: null
                root_person_id:
                  type: string
                  description: ''
                  example: null
                  nullable: true
                settings:
                  type: object
                  description: ''
                  example: null
                  properties:
                    lineage_depth:
                      type: integer
                      description: 'يجب أن تكون قيمة value 1 على الأقل. يجب ألا تتجاوز قيمة value 10.'
                      example: 9
                    lineage_format:
                      type: string
                      description: ''
                      example: null
                  nullable: true
  /api/v1/family/stats:
    get:
      summary: 'Family statistics'
      operationId: familyStatistics
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Family
      security: []
  /api/v1/persons:
    get:
      summary: 'List persons'
      operationId: listPersons
      description: ''
      parameters:
        -
          in: query
          name: 'filter[gender]'
          description: ''
          example: male
          required: false
          schema:
            type: string
            description: ''
            example: male
        -
          in: query
          name: 'filter[life_status]'
          description: 'alive, deceased or unknown.'
          example: alive
          required: false
          schema:
            type: string
            description: 'alive, deceased or unknown.'
            example: alive
        -
          in: query
          name: 'filter[father_id]'
          description: 'Children of a father.'
          example: consequatur
          required: false
          schema:
            type: string
            description: 'Children of a father.'
            example: consequatur
        -
          in: query
          name: 'filter[generation]'
          description: ''
          example: '1'
          required: false
          schema:
            type: string
            description: ''
            example: '1'
        -
          in: query
          name: 'filter[search]'
          description: 'Name search in every language (Arabic normalized).'
          example: محمد
          required: false
          schema:
            type: string
            description: 'Name search in every language (Arabic normalized).'
            example: محمد
        -
          in: query
          name: sort
          description: 'birth_date, -birth_date, created_at, generation, birth_order.'
          example: birth_date
          required: false
          schema:
            type: string
            description: 'birth_date, -birth_date, created_at, generation, birth_order.'
            example: birth_date
        -
          in: query
          name: per_page
          description: 'Max 100.'
          example: '25'
          required: false
          schema:
            type: string
            description: 'Max 100.'
            example: '25'
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Persons
      security: []
    post:
      summary: 'Create a person'
      operationId: createAPerson
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Persons
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                first_name:
                  type: object
                  description: Translatable.
                  example:
                    ar: فاطمة
                    en: Fatima
                  properties: {  }
                last_name:
                  type: object
                  description: Translatable.
                  example:
                    ar: الخضري
                    en: Al-Khudari
                  properties: {  }
                title:
                  type: object
                  description: 'Translatable honorific shown before the name (الحاج، الشيخ، الدكتور…).'
                  example:
                    ar: الحاج
                    en: Hajj
                  properties: {  }
                ref_no:
                  type: integer
                  description: "The family's reference number, unique in the tree (REF_NO_TAKEN)."
                  example: 1190
              required:
                - first_name
  /api/v1/persons/search:
    get:
      summary: 'Quick search'
      operationId: quickSearch
      description: "Short results for pickers (e.g. choosing a father). Matches every language,\nwith Arabic normalization: \"احمد\" finds \"أحمد\". A number finds the person with that reference number (`ref_no`)."
      parameters:
        -
          in: query
          name: q
          description: 'A name, or a reference number.'
          example: احمد
          required: true
          schema:
            type: string
            description: 'A name, or a reference number.'
            example: احمد
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Persons
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                q:
                  type: string
                  description: 'يجب أن يكون طول value 1 أحرف على الأقل. يجب ألا يتجاوز طول value 100 حرفاً.'
                  example: vmqeopfuudtdsufvyvddq
              required:
                - q
      security: []
  '/api/v1/persons/{id}':
    get:
      summary: 'Person details'
      operationId: personDetails
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Persons
      security: []
    patch:
      summary: 'Update a person (partial)'
      operationId: updateAPersonpartial
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Persons
    delete:
      summary: 'Delete a person (soft)'
      operationId: deleteAPersonsoft
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Persons
    parameters:
      -
        in: path
        name: id
        description: 'The ID of the person.'
        example: 01m43f8hfmfzqfv37t8d6f058v
        required: true
        schema:
          type: string
  '/api/v1/persons/{person_id}/card':
    get:
      summary: 'Person card (Bottom Sheet)'
      operationId: personCardBottomSheet
      description: "Everything the bottom sheet shows: lineage name, father, counts,\nthe children (sons and daughters) eldest first, and the allowed actions in `can`."
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Persons
      security: []
    parameters:
      -
        in: path
        name: person_id
        description: 'The ID of the person.'
        example: 01m43f8hfmfzqfv37t8d6f058v
        required: true
        schema:
          type: string
  /api/v1/trash/persons:
    get:
      summary: 'Deleted persons (trash)'
      operationId: deletedPersonstrash
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Persons
  '/api/v1/persons/{personId}/restore':
    post:
      summary: 'Restore a deleted person'
      operationId: restoreADeletedPerson
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Persons
    parameters:
      -
        in: path
        name: personId
        description: ''
        example: 01m43f8hfmfzqfv37t8d6f058v
        required: true
        schema:
          type: string
  '/api/v1/persons/{personId}/force':
    delete:
      summary: 'Delete a person permanently (owner)'
      operationId: deleteAPersonPermanentlyowner
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Persons
    parameters:
      -
        in: path
        name: personId
        description: ''
        example: 01m43f8hfmfzqfv37t8d6f058v
        required: true
        schema:
          type: string
  '/api/v1/persons/{person_id}/father':
    put:
      summary: 'Set the father'
      operationId: setTheFather
      description: "Applies the lineage rules: the father is a man of the family, not a descendant of this person,\nand at least 12 years older when both birth dates are known. `null` clears it."
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Persons
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                father_id:
                  type: string
                  description: "The father's id, or null."
                  example: null
                  nullable: true
              required:
                - father_id
    parameters:
      -
        in: path
        name: person_id
        description: 'The ID of the person.'
        example: 01m43f8hfmfzqfv37t8d6f058v
        required: true
        schema:
          type: string
  '/api/v1/persons/{person_id}/photo':
    post:
      summary: 'Upload the profile photo'
      operationId: uploadTheProfilePhoto
      description: "multipart/form-data, field `photo` (jpg, png, webp — max 5 MB).\nGenerates `thumb` (96×96 WebP, for the canvas nodes) and `preview` (400px, for the bottom sheet)."
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Persons
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                photo:
                  type: string
                  format: binary
                  description: 'يجب أن يكون value صورة. يجب ألا يتجاوز حجم value 5120 كيلوبايت.'
              required:
                - photo
    delete:
      summary: 'Delete the profile photo'
      operationId: deleteTheProfilePhoto
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Persons
    parameters:
      -
        in: path
        name: person_id
        description: 'The ID of the person.'
        example: 01m43f8hfmfzqfv37t8d6f058v
        required: true
        schema:
          type: string
  '/api/v1/persons/{person_id}/relatives':
    get:
      summary: 'Relatives: father, grandfather, siblings, children, paternal uncles and aunts'
      operationId: relativesFatherGrandfatherSiblingsChildrenPaternalUnclesAndAunts
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family relations'
      security: []
    post:
      summary: 'Add a relative (the + button)'
      operationId: addARelativethe+Button
      description: "Creates the person and links them through the father in one step. Gender comes from `relation`.\n- son / daughter: of this person (a man).\n- father: when this person has none yet (PARENT_ALREADY_SET otherwise).\n- brother / sister: needs this person's father (PARENTS_REQUIRED_FOR_SIBLING otherwise).\n\nThe response includes the updated graph around the anchor, so the canvas can merge it without reloading."
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family relations'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                relation:
                  type: string
                  description: 'father, son, daughter, brother or sister.'
                  example: son
                person:
                  type: object
                  description: 'The new person.'
                  example:
                    first_name:
                      ar: أحمد
                      en: Ahmad
                    birth_date: '1990-03-12'
                  properties: {  }
              required:
                - relation
                - person
    parameters:
      -
        in: path
        name: person_id
        description: 'The ID of the person.'
        example: 01m43f8hfmfzqfv37t8d6f058v
        required: true
        schema:
          type: string
  '/api/v1/persons/{person_id}/family':
    get:
      summary: 'Family: father and children'
      operationId: familyFatherAndChildren
      description: "The person, their father, and their children (sons and daughters together) eldest first.\n`meta` has the counts of sons, daughters and living children."
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family relations'
      security: []
    parameters:
      -
        in: path
        name: person_id
        description: 'The ID of the person.'
        example: 01m43f8hfmfzqfv37t8d6f058v
        required: true
        schema:
          type: string
  '/api/v1/persons/{person_id}/relationship/{relative_id}':
    get:
      summary: 'Relationship between two people'
      operationId: relationshipBetweenTwoPeople
      description: "Finds the closest shared ancestor through the father's line and returns a display label plus\nmachine-readable distances."
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family relations'
      security: []
    parameters:
      -
        in: path
        name: person_id
        description: 'The ID of the person.'
        example: 01m43f8hfmfzqfv37t8d6f058v
        required: true
        schema:
          type: string
      -
        in: path
        name: relative_id
        description: 'The ID of the relative.'
        example: 01m43f8hfmfzqfv37t8d6f058v
        required: true
        schema:
          type: string
  '/api/v1/persons/{person_id}/children':
    get:
      summary: Children
      operationId: children
      description: 'Sons and daughters, eldest first.'
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family relations'
      security: []
    parameters:
      -
        in: path
        name: person_id
        description: 'The ID of the person.'
        example: 01m43f8hfmfzqfv37t8d6f058v
        required: true
        schema:
          type: string
  '/api/v1/persons/{person_id}/ancestors':
    get:
      summary: "Ancestors (the father's line)"
      operationId: ancestorstheFathersLine
      description: ''
      parameters:
        -
          in: query
          name: depth
          description: 'Generations up, max 20.'
          example: '4'
          required: false
          schema:
            type: string
            description: 'Generations up, max 20.'
            example: '4'
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family relations'
      security: []
    parameters:
      -
        in: path
        name: person_id
        description: 'The ID of the person.'
        example: 01m43f8hfmfzqfv37t8d6f058v
        required: true
        schema:
          type: string
  '/api/v1/persons/{person_id}/descendants':
    get:
      summary: Descendants
      operationId: descendants
      description: 'Each level lists the children of the previous one, with their `father_id`.'
      parameters:
        -
          in: query
          name: depth
          description: 'Generations down, max 10.'
          example: '3'
          required: false
          schema:
            type: string
            description: 'Generations down, max 10.'
            example: '3'
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family relations'
      security: []
    parameters:
      -
        in: path
        name: person_id
        description: 'The ID of the person.'
        example: 01m43f8hfmfzqfv37t8d6f058v
        required: true
        schema:
          type: string
  '/api/v1/persons/{person_id}/children/order':
    put:
      summary: 'Reorder children manually'
      operationId: reorderChildrenManually
      description: "For twins or children without a birth date. Send every child of this father in the new order.\nChildren with known dates are re-sorted by date whenever a sibling is added or a date changes."
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family relations'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                order:
                  type: array
                  description: "All the father's children, eldest first."
                  example:
                    - consequatur
                  items:
                    type: string
              required:
                - order
    parameters:
      -
        in: path
        name: person_id
        description: 'The ID of the person.'
        example: 01m43f8hfmfzqfv37t8d6f058v
        required: true
        schema:
          type: string
  /api/v1/graph:
    get:
      summary: 'Tree graph'
      operationId: treeGraph
      description: ''
      parameters:
        -
          in: query
          name: root
          description: 'Person to center on (default: the tree root).'
          example: consequatur
          required: false
          schema:
            type: string
            description: 'Person to center on (default: the tree root).'
            example: consequatur
        -
          in: query
          name: depth_up
          description: "Generations of the father's line, max 12."
          example: '2'
          required: false
          schema:
            type: string
            description: "Generations of the father's line, max 12."
            example: '2'
        -
          in: query
          name: depth_down
          description: 'Generations of descendants, max 12.'
          example: '3'
          required: false
          schema:
            type: string
            description: 'Generations of descendants, max 12.'
            example: '3'
        -
          in: query
          name: max_nodes
          description: 'Max 2000.'
          example: '300'
          required: false
          schema:
            type: string
            description: 'Max 2000.'
            example: '300'
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Graph
      security: []
  '/api/v1/graph/expand/{person_id}':
    get:
      summary: 'Expand a node'
      operationId: expandANode
      description: "Loads the hidden branch around a node (when `has_more_up` / `has_more_down` is true).\nMerge the result into the canvas by id."
      parameters:
        -
          in: query
          name: direction
          description: 'up, down or both.'
          example: down
          required: false
          schema:
            type: string
            description: 'up, down or both.'
            example: down
        -
          in: query
          name: depth
          description: ''
          example: '2'
          required: false
          schema:
            type: string
            description: ''
            example: '2'
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Graph
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                direction:
                  type: string
                  description: ''
                  example: null
                depth:
                  type: integer
                  description: 'يجب أن تكون قيمة value 1 على الأقل.'
                  example: 73
      security: []
    parameters:
      -
        in: path
        name: person_id
        description: 'The ID of the person.'
        example: 01m43f8hfmfzqfv37t8d6f058v
        required: true
        schema:
          type: string
  '/api/v1/persons/{person_id}/posts':
    get:
      summary: 'News about a person'
      operationId: newsAboutAPerson
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family news'
      security: []
    parameters:
      -
        in: path
        name: person_id
        description: 'The ID of the person.'
        example: 01m43f8hfmfzqfv37t8d6f058v
        required: true
        schema:
          type: string
  /api/v1/posts:
    get:
      summary: 'News feed'
      operationId: newsFeed
      description: 'Pinned posts first, then newest. Drafts and scheduled posts are only listed for users who can write posts (`status=draft`).'
      parameters:
        -
          in: query
          name: type
          description: 'news, obituary, wedding, birth, event or announcement.'
          example: news
          required: false
          schema:
            type: string
            description: 'news, obituary, wedding, birth, event or announcement.'
            example: news
        -
          in: query
          name: person_id
          description: 'Only posts about this person.'
          example: 01j9z3q4r5s6t7v8w9x0y1z2a3
          required: false
          schema:
            type: string
            description: 'Only posts about this person.'
            example: 01j9z3q4r5s6t7v8w9x0y1z2a3
        -
          in: query
          name: q
          description: 'Search in titles.'
          example: زفاف
          required: false
          schema:
            type: string
            description: 'Search in titles.'
            example: زفاف
        -
          in: query
          name: status
          description: 'draft or published (writers only).'
          example: published
          required: false
          schema:
            type: string
            description: 'draft or published (writers only).'
            example: published
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family news'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                type:
                  type: string
                  description: ''
                  example: announcement
                  enum:
                    - news
                    - obituary
                    - wedding
                    - birth
                    - event
                    - announcement
                status:
                  type: string
                  description: ''
                  example: published
                  enum:
                    - draft
                    - published
                person_id:
                  type: string
                  description: ''
                  example: null
                q:
                  type: string
                  description: 'يجب ألا يتجاوز طول value 100 حرفاً.'
                  example: vmqeopfuudtdsufvyvddq
      security: []
    post:
      summary: 'Create a post'
      operationId: createAPost
      description: "JSON, or multipart/form-data to attach `images[]` (jpg, png, webp, up to 10 × 10 MB).\n`status=published` with no `published_at` publishes now; a future `published_at` schedules it."
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family news'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                title:
                  type: object
                  description: Translatable.
                  example:
                    ar: 'زفاف محمد'
                    en: "Mohammed's wedding"
                  properties: {  }
                body:
                  type: object
                  description: Translatable.
                  example:
                    ar: 'يسرّ العائلة دعوتكم…'
                  properties: {  }
                type:
                  type: string
                  description: 'news, obituary, wedding, birth, event or announcement.'
                  example: wedding
                person_ids:
                  type: array
                  description: 'Family members the post is about.'
                  example: []
                  items:
                    type: string
              required:
                - title
  '/api/v1/posts/{id}':
    get:
      summary: 'Post details'
      operationId: postDetails
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family news'
      security: []
    patch:
      summary: 'Update a post'
      operationId: updateAPost
      description: 'Partial. Add images with `POST /posts/{post}/images`.'
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family news'
    delete:
      summary: 'Delete a post'
      operationId: deleteAPost
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family news'
    parameters:
      -
        in: path
        name: id
        description: 'The ID of the post.'
        example: 01m485akfnz4pemfrhv19ch6kc
        required: true
        schema:
          type: string
  '/api/v1/posts/{post_id}/comments':
    get:
      summary: 'Comments of a post'
      operationId: commentsOfAPost
      description: 'Oldest first. Empty when comments are turned off for the post.'
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family news'
      security: []
    post:
      summary: 'Add a comment'
      operationId: addAComment
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family news'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                body:
                  type: string
                  description: ''
                  example: 'ألف مبروك'
              required:
                - body
    parameters:
      -
        in: path
        name: post_id
        description: 'The ID of the post.'
        example: 01m485akfnz4pemfrhv19ch6kc
        required: true
        schema:
          type: string
  '/api/v1/posts/{post_id}/likes':
    get:
      summary: 'Who liked a post'
      operationId: whoLikedAPost
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family news'
      security: []
    parameters:
      -
        in: path
        name: post_id
        description: 'The ID of the post.'
        example: 01m485akfnz4pemfrhv19ch6kc
        required: true
        schema:
          type: string
  '/api/v1/comments/{id}':
    delete:
      summary: 'Delete a comment'
      operationId: deleteAComment
      description: 'The author, or anyone with `comments.moderate`.'
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family news'
    parameters:
      -
        in: path
        name: id
        description: 'The ID of the comment.'
        example: 01m485art56yasqdgam4gyrjzc
        required: true
        schema:
          type: string
  '/api/v1/posts/{post_id}/like':
    post:
      summary: 'Like a post'
      operationId: likeAPost
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family news'
    delete:
      summary: 'Remove my like'
      operationId: removeMyLike
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family news'
    parameters:
      -
        in: path
        name: post_id
        description: 'The ID of the post.'
        example: 01m485akfnz4pemfrhv19ch6kc
        required: true
        schema:
          type: string
  '/api/v1/posts/{post_id}/images':
    post:
      summary: 'Add images'
      operationId: addImages
      description: 'multipart/form-data, `images[]` (jpg, png, webp — 10 MB each, 10 per post).'
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family news'
      requestBody:
        required: false
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                images:
                  type: array
                  description: 'يجب أن يكون value صورة. يجب ألا يتجاوز حجم value 10240 كيلوبايت.'
                  items:
                    type: string
                    format: binary
    parameters:
      -
        in: path
        name: post_id
        description: 'The ID of the post.'
        example: 01m485akfnz4pemfrhv19ch6kc
        required: true
        schema:
          type: string
  '/api/v1/posts/{post_id}/images/{media}':
    delete:
      summary: 'Delete an image'
      operationId: deleteAnImage
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Family news'
    parameters:
      -
        in: path
        name: post_id
        description: 'The ID of the post.'
        example: 01m485akfnz4pemfrhv19ch6kc
        required: true
        schema:
          type: string
      -
        in: path
        name: media
        description: ''
        example: consequatur
        required: true
        schema:
          type: string
  /api/v1/change-requests:
    get:
      summary: 'Change requests'
      operationId: changeRequests
      description: "Reviewers see everyone's requests; staff see their own. `meta.pending_count` is for the badge."
      parameters:
        -
          in: query
          name: status
          description: 'pending, approved, rejected or cancelled.'
          example: pending
          required: false
          schema:
            type: string
            description: 'pending, approved, rejected or cancelled.'
            example: pending
        -
          in: query
          name: area
          description: 'persons or posts.'
          example: persons
          required: false
          schema:
            type: string
            description: 'persons or posts.'
            example: persons
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Change requests'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                status:
                  type: string
                  description: ''
                  example: pending
                  enum:
                    - pending
                    - approved
                    - rejected
                    - cancelled
                area:
                  type: string
                  description: ''
                  example: null
  '/api/v1/change-requests/{changeRequest_id}':
    get:
      summary: 'Change request details'
      operationId: changeRequestDetails
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Change requests'
    delete:
      summary: 'Cancel my pending request'
      operationId: cancelMyPendingRequest
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Change requests'
    parameters:
      -
        in: path
        name: changeRequest_id
        description: 'The ID of the changeRequest.'
        example: consequatur
        required: true
        schema:
          type: string
  '/api/v1/change-requests/{changeRequest_id}/approve':
    post:
      summary: Approve
      operationId: approve
      description: "Applies the original call as the staff member who made it. If the tree changed in between\nand the call now fails, the response is `409 CHANGE_REQUEST_FAILED` with the reason, and the request stays pending."
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Change requests'
    parameters:
      -
        in: path
        name: changeRequest_id
        description: 'The ID of the changeRequest.'
        example: consequatur
        required: true
        schema:
          type: string
  '/api/v1/change-requests/{changeRequest_id}/reject':
    post:
      summary: Reject
      operationId: reject
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Change requests'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                note:
                  type: string
                  description: 'The reason, shown to the staff member.'
                  example: 'The birth date is wrong'
                  nullable: true
    parameters:
      -
        in: path
        name: changeRequest_id
        description: 'The ID of the changeRequest.'
        example: consequatur
        required: true
        schema:
          type: string
  /api/v1/notifications:
    get:
      summary: 'My notifications'
      operationId: myNotifications
      description: ''
      parameters:
        -
          in: query
          name: unread
          description: 'Only unread ones.'
          example: true
          required: false
          schema:
            type: boolean
            description: 'Only unread ones.'
            example: true
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Notifications
  /api/v1/notifications/unread-count:
    get:
      summary: 'Unread count (for the badge)'
      operationId: unreadCountforTheBadge
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Notifications
  /api/v1/notifications/read-all:
    post:
      summary: 'Mark all as read'
      operationId: markAllAsRead
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Notifications
  '/api/v1/notifications/{id}/read':
    post:
      summary: 'Mark one as read'
      operationId: markOneAsRead
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Notifications
    parameters:
      -
        in: path
        name: id
        description: 'The ID of the notification.'
        example: consequatur
        required: true
        schema:
          type: string
  '/api/v1/notifications/{id}':
    delete:
      summary: 'Delete a notification'
      operationId: deleteANotification
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - Notifications
    parameters:
      -
        in: path
        name: id
        description: 'The ID of the notification.'
        example: consequatur
        required: true
        schema:
          type: string
  /api/v1/admin/users:
    get:
      summary: 'List users'
      operationId: listUsers
      description: ''
      parameters:
        -
          in: query
          name: 'filter[status]'
          description: 'active or suspended.'
          example: consequatur
          required: false
          schema:
            type: string
            description: 'active or suspended.'
            example: consequatur
        -
          in: query
          name: 'filter[role]'
          description: ''
          example: admin
          required: false
          schema:
            type: string
            description: ''
            example: admin
        -
          in: query
          name: 'filter[search]'
          description: 'Name or email.'
          example: consequatur
          required: false
          schema:
            type: string
            description: 'Name or email.'
            example: consequatur
        -
          in: query
          name: 'filter[trashed]'
          description: 'with or only.'
          example: consequatur
          required: false
          schema:
            type: string
            description: 'with or only.'
            example: consequatur
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — Users'
    post:
      summary: 'Create a user'
      operationId: createAUser
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — Users'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: 'يجب ألا يتجاوز طول value 150 حرفاً.'
                  example: vmqeopfuudtdsufvyvddq
                email:
                  type: string
                  description: 'يجب أن يكون value بريداً إلكترونياً صحيحاً. يجب ألا يتجاوز طول value 191 حرفاً.'
                  example: kunde.eloisa@example.com
                phone:
                  type: string
                  description: 'يجب ألا يتجاوز طول value 30 حرفاً.'
                  example: hfqcoynlazghdtqtqxbaj
                  nullable: true
                password:
                  type: string
                  description: ''
                  example: consequatur
                locale:
                  type: string
                  description: ''
                  example: null
                  nullable: true
                roles:
                  type: array
                  description: ''
                  example:
                    - consequatur
                  items:
                    type: string
              required:
                - name
                - email
                - password
  '/api/v1/admin/users/{userId}':
    get:
      summary: 'User details'
      operationId: userDetails
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — Users'
    parameters:
      -
        in: path
        name: userId
        description: ''
        example: consequatur
        required: true
        schema:
          type: string
  '/api/v1/admin/users/{id}':
    patch:
      summary: 'Update a user'
      operationId: updateAUser
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — Users'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: 'يجب ألا يتجاوز طول value 150 حرفاً.'
                  example: vmqeopfuudtdsufvyvddq
                email:
                  type: string
                  description: 'يجب أن يكون value بريداً إلكترونياً صحيحاً. يجب ألا يتجاوز طول value 191 حرفاً.'
                  example: kunde.eloisa@example.com
                phone:
                  type: string
                  description: 'يجب ألا يتجاوز طول value 30 حرفاً.'
                  example: hfqcoynlazghdtqtqxbaj
                  nullable: true
                password:
                  type: string
                  description: ''
                  example: null
                locale:
                  type: string
                  description: ''
                  example: null
    delete:
      summary: 'Delete a user (soft)'
      operationId: deleteAUsersoft
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — Users'
    parameters:
      -
        in: path
        name: id
        description: 'The ID of the user.'
        example: 01m43erdn58sh1pmh2hfbzaqqk
        required: true
        schema:
          type: string
  '/api/v1/admin/users/{userId}/restore':
    post:
      summary: 'Restore a deleted user'
      operationId: restoreADeletedUser
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — Users'
    parameters:
      -
        in: path
        name: userId
        description: ''
        example: 01m43erdn58sh1pmh2hfbzaqqk
        required: true
        schema:
          type: string
  '/api/v1/admin/users/{user_id}/suspend':
    post:
      summary: 'Suspend a user (revokes their tokens)'
      operationId: suspendAUserrevokesTheirTokens
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — Users'
    parameters:
      -
        in: path
        name: user_id
        description: 'The ID of the user.'
        example: 01m43erdn58sh1pmh2hfbzaqqk
        required: true
        schema:
          type: string
  '/api/v1/admin/users/{user_id}/activate':
    post:
      summary: 'Activate a suspended user'
      operationId: activateASuspendedUser
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — Users'
    parameters:
      -
        in: path
        name: user_id
        description: 'The ID of the user.'
        example: 01m43erdn58sh1pmh2hfbzaqqk
        required: true
        schema:
          type: string
  '/api/v1/admin/users/{user_id}/roles':
    put:
      summary: 'Set system roles'
      operationId: setSystemRoles
      description: 'Only `super_admin` can grant or remove `admin` / `super_admin`.'
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — Users'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                roles:
                  type: array
                  description: ''
                  example:
                    - consequatur
                  items:
                    type: string
    parameters:
      -
        in: path
        name: user_id
        description: 'The ID of the user.'
        example: 01m43erdn58sh1pmh2hfbzaqqk
        required: true
        schema:
          type: string
  '/api/v1/admin/users/{user_id}/permissions':
    put:
      summary: 'Set staff permissions'
      operationId: setStaffPermissions
      description: "The user's own permissions, on top of their role. Grant `persons.direct` / `posts.direct`\nto let a staff member save without approval. Allowed values: `GET /admin/permissions` → `grantable`."
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — Users'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                permissions:
                  type: array
                  description: ''
                  example:
                    - persons.create
                    - persons.update
                    - persons.direct
                    - posts.create
                  items:
                    type: string
              required:
                - permissions
    parameters:
      -
        in: path
        name: user_id
        description: 'The ID of the user.'
        example: 01m43erdn58sh1pmh2hfbzaqqk
        required: true
        schema:
          type: string
  /api/v1/admin/languages:
    get:
      summary: 'All languages (active and inactive)'
      operationId: allLanguagesactiveAndInactive
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — Languages'
    post:
      summary: 'Add a language'
      operationId: addALanguage
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — Languages'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
                  description: 'Must contain only letters. يجب أن يكون طول value 2 أحرف.'
                  example: vm
                name:
                  type: string
                  description: 'يجب ألا يتجاوز طول value 50 حرفاً.'
                  example: qeopfuudtdsufvyvddqam
                native_name:
                  type: string
                  description: 'يجب ألا يتجاوز طول value 50 حرفاً.'
                  example: niihfqcoynlazghdtqtqx
                direction:
                  type: string
                  description: ''
                  example: consequatur
                is_active:
                  type: boolean
                  description: ''
                  example: false
                sort_order:
                  type: integer
                  description: 'يجب أن تكون قيمة value 0 على الأقل.'
                  example: 45
              required:
                - code
                - name
                - native_name
                - direction
  '/api/v1/admin/languages/{id}':
    patch:
      summary: 'Update / activate / make default'
      operationId: updateActivateMakeDefault
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — Languages'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: 'يجب ألا يتجاوز طول value 50 حرفاً.'
                  example: vmqeopfuudtdsufvyvddq
                native_name:
                  type: string
                  description: 'يجب ألا يتجاوز طول value 50 حرفاً.'
                  example: amniihfqcoynlazghdtqt
                direction:
                  type: string
                  description: ''
                  example: null
                is_active:
                  type: boolean
                  description: ''
                  example: false
                is_default:
                  type: boolean
                  description: 'Must be accepted.'
                  example: true
                sort_order:
                  type: integer
                  description: 'يجب أن تكون قيمة value 0 على الأقل.'
                  example: 56
    delete:
      summary: 'Delete a language (not the default one)'
      operationId: deleteALanguagenotTheDefaultOne
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — Languages'
    parameters:
      -
        in: path
        name: id
        description: 'The ID of the language.'
        example: 1
        required: true
        schema:
          type: integer
  /api/v1/admin/settings:
    get:
      summary: 'All settings'
      operationId: allSettings
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — Settings'
    put:
      summary: 'Update settings'
      operationId: updateSettings
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — Settings'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                settings:
                  type: array
                  description: ''
                  example:
                    -
                      key: app.name
                      value:
                        ar: 'شجرة العائلة'
                        en: 'Family Tree'
                      group: general
                      is_public: true
                  items:
                    type: object
                    properties:
                      key:
                        type: string
                        description: 'Must match the regex /^[a-z0-9_.]+$/. يجب ألا يتجاوز طول value 191 حرفاً.'
                        example: vmqeopfuudtdsufvyvddq
                      value:
                        type: string
                        description: ''
                        example: null
                      group:
                        type: string
                        description: 'يجب ألا يتجاوز طول value 50 حرفاً.'
                        example: amniihfqcoynlazghdtqt
                      is_public:
                        type: boolean
                        description: ''
                        example: false
                    required:
                      - key
              required:
                - settings
  /api/v1/admin/stats:
    get:
      summary: 'System statistics'
      operationId: systemStatistics
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — System'
  /api/v1/admin/permissions:
    get:
      summary: 'All permissions with translated labels'
      operationId: allPermissionsWithTranslatedLabels
      description: '`grantable` marks the ones an admin can give to staff with `PUT /admin/users/{user}/permissions`.'
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — System'
  /api/v1/admin/roles:
    get:
      summary: 'Roles with their permissions'
      operationId: rolesWithTheirPermissions
      description: ''
      parameters:
        -
          in: header
          name: Accept-Language
          description: ''
          example: ar
          schema:
            type: string
      responses: {  }
      tags:
        - 'Admin — System'
