swagger: "2.0"

info:
  version: 1.0.0
  title: API Specifications

schemes:
  - https
host: qa-ows-permissions.theorchard.io

definitions:
  Identity:
    type: object
    properties:
      name:
        type: string
      email:
        type: string
      first_name:
        type: string
      last_name:
        type: string
      localization:
        type: string
        enum: [en, de, es, fr, it, ja, ko, pt, ru, tr, zh-CN, zh-TW]
      number_format:
        type: string
        enum: [us, eu]
    required:
      - name
      - email

  resource_access:
    type: object
    properties:
      resource_type:
        type: string
        enum: [ LabelParticipant, Subaccount, Vendor ]
      uuid:
        type: string
      roles:
        enum: [ accounting, admin, administrator, advertising, analytics, catalog, insight, marketing, producer ]
      overwrite_existing_access:
        type: boolean
    required:
      - resource_type
      - uuid
      - roles

  resource: # TODO: fill this out, was referenced with no definition
    type: object

  profile_role_access: # TODO: fill this out, was referenced with no definition
    type: object

  tenant:
    type: object
    properties:
      tenant_type:
        type: string
        description: The type of the tenant.
        example: account
      tenant_uuid:
        type: string
        description: The unique identifier of the tenant.
        example: valid-uuid

paths:
  /:
    get:
      summary: Hello World path.
      responses:
        200:
          description: 200 OK
          examples:
            text/html: "Hello Bill!"
  /{username}:
    get:
      summary: Hello World with an optional GET param "username".
      parameters:
        - in: path
          name: username
          required: true
          type: string
      responses:
        200:
          description: 200 OK
          examples:
            text/html: "Hello Bill!"

  /hello/:
    get:
      summary: Check the health of the application.
      responses:
        200:
          description: 200 OK
          examples:
            application/json: { "status": "ok" }

  /identity/resources/{resource_type}:
    get:
      summary: Get batch resources with an optional role check.
      parameters:
      - name: resource_type
        in: path
        description: Type of resources like vendor, label, artistinfo
        required: true
        type: string
      - name: profile_type
        in: query
        description: Type of profile like LabelProfile, InsightsProfile.
        required: true
        type: string
      - name: role
        in: query
        description: Role constraint for filtering resources like admin, analytics, insight.
        required: false
        type: string
      responses:
        200:
          description: 200 OK
          examples:
            application/json:
              {
                "items": [
                  {
                    "name": "Thirty Tigers",
                    "id": 21989
                  }
                ],
                "pagination": {
                  "type": "none",
                  "total_records": 1
                }
              }

  /identity/{identity_id}/direct-access/resources/{resource_type}:
    get:
      summary: Get resources the identity_id has direct access to, and the admin can administer. Called by Settings for permissioning.
      parameters:
      - name: identity_id
        in: path
        description: Identity uuid for user being viewed. Can be the same as the admins, or the user the admin is fetching resources for.
        required: true
        type: string
      - name: resource_type
        in: path
        description: Type of resource. ex. vendor, label, subaccount, vendor star
        required: true
        type: string
      responses:
        200:
          description: 200 OK
          examples:
            application/json:
              {
                "items": [
                  {
                    "name": "Thirty Tigers",
                    "id": 21989,
                    "vendor_id": 1234,
                    "uuid": "123-alpha-num-uuid",
                    "touched_by_backfill": "2021-06-01T10:51:56:450000",
                    "type": "Vendor",
                    "profile_access": {
                      "roles": ["administrator"]
                    }
                  }
                ],
                "pagination": {
                  "type": "standard",
                  "total_records": 1,
                  "limit": 50,
                  "offset": 0,
                  "active": true
                }
              }

  /admin/profile-type/{profile_type}/profile/{profile_id}/access/{resource_type}:
    get:
      summary: Get all immediate accessible resources of type resource_type and their ids. Will be called by other microservices only.
      parameters:
      - name: profile_type
        in: path
        description: Type of profile like ArtistProfile, LabelProfile.
        required: true
        type: string
      - name: profile_id
        in: path
        description: User's current profile identifier.
        required: true
        type: integer
      - name: resource_type
        in: path
        description: Type of resource like ArtistInfo, Product, Project etc or ALL.
        required: true
        type: string
      responses:
        200:
          description: 200 OK
          examples:
            application/json:
              {
                "items": [
                  {
                    "type": "ArtistInfo",
                    "name": "Ozuna",
                    "id": 1346777
                  },
                  {
                    "isDeleted": false,
                    "name": "Dancing Eagle",
                    "id": 48348,
                    "type": "Subaccount",
                    "roles": [
                      "analytics"
                    ],
                    "vendorId": 21989,
                    "vendorName": "Thirty Tigers"
                  }
                ],
                "pagination": {
                  "type": "none",
                  "total_records": 2
                }
              }

  /identity/admin/resources/all/:
    get:
      summary: Get all resources (by resource type) which this authenticated user has admin access.
      responses:
        200:
          description: 200 OK
          examples:
            application/json:
              {
                "items": [
                  {
                    "type": "Vendor",
                    "id": 7123,
                    "uuid": "573d0372-7f2f-48a6-8deb-c9a6558f9549"
                  },
                  {
                    "type": "Subaccount",
                    "id": 111111111,
                    "uuid": "a2dbe1e9-e100-4ec1-88ae-75d4f8cec8f6"
                  }
                ],
                "pagination": {
                  "type": "none",
                  "total_records": 2
                }
              }

  /identity/admin/profiles:
    get:
      summary: Get profiles an admin can administer with optional profile_type filter.
      parameters:
      - name: identity_id
        in: header
        description: Identity identifier, either an auth0 user id or uuid.
        required: true
        type: string
      - name: profile_type
        in: query
        description: Type of profile like LabelProfile, InsightsProfile.
        required: false
        type: string
      - name: limit
        in: query
        description: Limit number of records.
        type: integer
        default: 50
      - name: offset
        in: query
        description: Offset result set.
        type: integer
      - name: term
        in: query
        description: Search term. Search is case-insensitive.
        type: string
      - name: active
        in: query
        type: string
        description: Filter by active/inactive users.
        enum: [ 'Y', 'N' ]
      - name: pending
        in: query
        type: string
        description: Filter by users that haven't accepted auth0 invitation / have accepted auth0 invitation.
        enum: [ 'Y', 'N' ]
      - name: resource_access
        in: query
        description: Filter by uuid of a node.
        type: string
      - name: parent_vendor_filter
        in: query
        description: Filter results to parent vendor uuids.
        type: string
      - name: include_subaccount_users
        in: query
        description: Whether to include subaccount users for D3 admins when "resource_access" is specified.
        type: boolean
        default: True
      responses:
        200:
          description: 200 OK
          examples:
            application/json:
              {
                "items": [
                  {
                    "lastName": "Last",
                    "firstName": "First",
                    "name": "First Last",
                    "googleUserId": "google-id-123",
                    "active": "Y",
                    "id": "08ac815d-9006-403a-8a0b-67417e5c2099",
                    "auth0UserId": "auth0-id-123",
                    "email": "email@example.com"
                  }
                ],
                "pagination": {
                  "type": "standard",
                  "total_records": 1,
                  "limit": 50,
                  "offset": 0
                }
              }

  /v2/identity/self/all-label-access:
    summary: Get whether the identity of the caller has super admin privileges.
    get:
      responses:
        200:
          description: 200 OK
          examples:
            application/json:
              {"has_access": false}

  /associated-labels/{resource_type}/{artist_id}:
    get:
      summary: Get label information for an artist id.
      parameters:
      - name: resource_type
        in: path
        description: Type of artist resource. Only accepts ArtistInfo and LabelParticipant.
        required: true
        type: string
      - name: artist_id
        in: path
        description: id of the ArtistInfo or LabelParticipant node you want the label of.
        required: true
        type: integer
      responses:
        200:
          description: 200 OK
          examples:
            application/json:
              {
                "isDistributor": "N",
                "labelIdentifier": "Catalog",
                "name": "Soundlink",
                "vendorId": 15829,
                "id": 15829,
                "uuid": "d506c127-fbdf-47a7-8431-970ecd1c923e",
                "status": "signed",
                "type": "Vendor"
              }

  /e2e/resource/{resource_type}/{resource_id}:
    get:
      summary: Get node details of type/label resource Type.
      parameters:
      - name: resource_type
        in: path
        description: Type of resource like Identity, ArtistInfo, Product, Project etc.
        required: true
        type: string
      - name: resource_id
        in: path
        description: identifier for resource like productId or artistinfo id.
        required: true
        type: integer
      responses:
        200:
          description: 200 OK
          examples:
            application/json:
              {
                "name": "Ginesa Ortega",
                "vendorId": 10986,
                "id": 67878,
                "type": "ArtistInfo"
              }
    post:
      summary: Create a new node of type/label resource Type.
      parameters:
      - name: resource_type
        in: path
        description: Type of resource like Identity, ArtistInfo, Product, Project etc.
        required: true
        type: string
      - name: resource_id
        in: path
        description: identifier for resource like productId or artistinfo id.
        required: true
        type: integer
      - name: details
        in: body
        description: UPC, name or other extra metadata for that node.
        schema:
          type: object
          properties:
            name:
              type: string
      responses:
        200:
          description: 200 OK
          examples:
            application/json:
              {
                "name": "Test Artist",
                "id": 500,
                "type": "ArtistInfo"
              }
    delete:
      summary: Delete an existing node of type/label resource Type.
      parameters:
      - name: resource_type
        in: path
        description: Type of resource like Identity, ArtistInfo Product, Project etc.
        required: true
        type: string
      - name: resource_id
        in: path
        description: identifier for resource like productId or artistinfo id.
        required: true
        type: integer
      responses:
        200:
          description: 204 No Content

  /ows/profile/{profile_type}/{profile_id}/has-access-to/resource/{resource_type}/{resource_id}:
    post:
      summary: Give an existing profile access to an existing resources. This adds a relationship between those nodes.
      parameters:
      - name: profile_type
        in: path
        description: Type of profile like ArtistProfile, LabelProfile.
        required: true
        type: string
      - name: profile_id
        in: path
        description: identifier for profile.
        required: true
        type: integer
      - name: resource_type
        in: path
        description: Type of resource like Identity, ArtistInfo, Product, Project etc.
        required: true
        type: string
      - name: resource_id
        in: path
        description: identifier for resource like productId or artistinfo id.
        required: true
        type: integer
      - name: details
        in: body
        description: access roles for that relationship.
        schema:
          type: object
          properties:
            roles:
              type: array
              items:
                type: string
      responses:
        201:
          description: 201 Created
          examples:
            application/json:
              {
                resource_type: "ArtistInfo",
                resource_id: 1234,
                profile_type: "ArtistProfile",
                profile_id: 766678,
                roles: ["analytics"]
              }

    delete:
      summary: Delete profile's access to a resources. This deletes the relationship between those nodes.
      parameters:
      - name: profile_type
        in: path
        description: Type of profile like ArtistProfile, LabelProfile.
        required: true
        type: string
      - name: profile_id
        in: path
        description: identifier for profile.
        required: true
        type: integer
      - name: resource_type
        in: path
        description: Type of resource like Identity, ArtistInfo, Product, Project etc.
        required: true
        type: string
      - name: resource_id
        in: path
        description: identifier for resource like productId or artistinfo id.
        required: true
        type: integer
      responses:
        204:
          description: 204 No Content

  /identity/add-resources-profiles:
    post:
      summary: Used by settings app to create new users.
      parameters:
      - name: details
        in: body
        description: post body.
        schema:
          type: object
          properties:
            identity:
              $ref: "#/definitions/Identity"
            resource_access:
                type: array
                items:
                  $ref: "#/definitions/resource_access"
            send_password_reset:
              type: boolean
            set_email_verified:
              type: boolean
            overwrite_existing_access:
              type: boolean
            brand:
              type: string
              enum: [awal, theorchard, sme-affiliates]
            user_metadata:
              type: object
              description: Additional metadata to be stored on the user creation

      responses:
        200:
          description: 200 Created
          examples:
            application/json:
              {
                'profiles_affected': [
                  { 'new profile' : '1' },
                  { 'new profile' : '2' }
                ],
                'identities_affected': { 'new' : 'identity data' },
                'identity_created': true }

  /identity/{identity_id}/edit-resources-profiles:
    post:
      summary: Used by settings app to edit a user.
      parameters:
      - name: identity_id
        in: path
        required: true
        type: string
        description: identity UUID.
      - name: details
        in: body
        description: post body.
        schema:
          type: object
          properties:
            resource_access:
                type: array
                items:
                  $ref: "#/definitions/resource_access"

      responses:
        200:
          description: 200 Created
          examples:
            application/json:
              {
                'updated' : 'identity data'
              }

  /identity/{identity_id}/remove-profile-resource:
    post:
      summary: Soft delete identity access to single resource.
      parameters:
        - name: identity_id
          in: path
          required: true
          type: string
          description: identity UUID.
        - name: details
          in: body
          description: post body.
          schema:
            type: object
            properties:
              resource:
                $ref: "#/definitions/resource"
              profile_role_access:
                type: array
                items:
                  $ref: "#/definitions/profile_role_access"

      responses:
        200:
          description: 200 OK
          examples:
            application/json:
              {
                'identity_id': '0a4d96d4-0eee-46bc-8656-7024549a85d9',
                'edited_profile_roles': [
                  {
                    'profile_id': 146777,
                    'profile_type': 'LabelProfile',
                    'roles_added': [],
                    'roles_removed': ['administrator']
                  }
                ],
                'resource': {
                  'resource_uuid': 'abe59ba4-a7f1-44e5-b9a4-67d9d98bdiic',
                  'resource_type': 'Vendor'
                }
              }

  /v2/identity/self/tenant-type:
    get:
      summary: Get all tenant types which this authenticated user has admin access.
      responses:
        200:
          description: 200 OK. tenant_count returns 1 if the requesting admin can administer access to just one corresponding tenant type. Otherwise, tenant_count returns > 1 if the requesting admin can administer access to multiple corresponding tenant types. Note that tenant_count is not the exact total number of tenant types the requesting admin can administer.
          examples:
            application/json:
              [
                  {
                      "tenant_type": "account",
                      "tenant_count": 1
                  },
                  {
                      "tenant_type": "label_participant",
                      "tenant_count": 1
                  },
                  {
                      "tenant_type": "collaborator",
                      "tenant_count": 2
                  }
              ]

  /v2/identity/self/tenant-access:
    post:
      summary: Check admin access to tenants
      description: Endpoint to check which tenant types an admin can access.
      tags:
        - Tenant Access
      parameters:
        - name: body
          in: body
          required: true
          schema:
            type: object
            properties:
              tenants:
                type: array
                items:
                  type: object
                  properties:
                    tenant_type:
                      type: string
                      description: The type of tenant.
                      enum:
                        - account
                        - subaccount
                        - label_participant
                        - collaborator
                      example: account
                    tenant_uuid:
                      type: string
                      description: The unique identifier of the tenant.
                      example: valid-uuid
            required:
              - tenants
      responses:
        '200':
          description: Successful response
          examples:
            application/json:
              {
                'tenants': [
                  { 'uuid': '25364b17-36df-4ff8-96cd-65456778dac5', 'type': 'account', 'access': False },
                  { 'uuid': 'ec1fd7e2-9c95-4e09-a037-e924e0244283', 'type': 'subaccount', 'access': True },
                  { 'uuid': 'f62d7c5b-1d8c-4c1f-b527-f21ea798d337', 'type': 'label_participant', 'access': False },
                  { 'uuid': '1a8a2945-f5c8-47b0-b160-ef3c1a781b45', 'type': 'collaborator', 'access': True }
                ]
              }
        '401':
          description: Unauthorized
          schema:
            type: object
            properties:
              code:
                type: string
                example: unauthorized
              message:
                type: string
                example: Request context has no identity uuid.
        '403':
          description: Forbidden
          schema:
            type: object
            properties:
              code:
                type: string
                example: authorization_error
              message:
                type: string
                example: user is forbidden

  /v2/identity/{identity_id}/tenants:
    get:
      summary: Get all tenants this identity can access that the caller can administer.
      parameters:
        - name: identity_id
          in: path
          required: true
          type: string
          description: identity UUID.
      responses:
        200:
          description: 200 OK
          examples:
            application/json:
              {
                'tenants': [
                  {
                    "tenant_uuid": "573d0372-7f2f-48a6-8deb-c9a6558f9549",
                    "tenant_type": "account",
                    "roles": ['COLLABORATORS_BASE_ROLE']
                  },
                  {
                    "tenant_uuid": "fff741c2-6def-4493-bfdf-c2bcb1128e02",
                    "tenant_type": "account",
                    "roles": [
                      'INSIGHTS_PROFILE_BASE_ROLE',
                      'WORKSTATION_CATALOG_ROLE',
                      'WORKSTATION_MARKETING_ROLE',
                      'WORKSTATION_ANALYTICS_BASE_ROLE',
                      'WORKSTATION_ADVERTISING_ROLE',
                      'COLLABORATORS_BASE_ROLE',
                    ]
                  }
                ]
              }

  /v2/identities/{identity_id}/tenants/{tenant_type}/{tenant_uuid}:
    delete:
      summary: Remove an identity's access to a tenant.
      parameters:
        - name: identity_id
          in: path
          required: true
          type: string
          description: identity UUID.
        - name: tenant_type
          in: path
          required: true
          type: string
          description: The type of the tenant.
        - name: tenant_uuid
          in: path
          required: true
          type: string
          description: The unique identifier of the tenant.
      responses:
        '204':
          description: Success
        '404':
          description: Tenant not found
          schema:
            type: object
            properties:
              code:
                type: string
                example: not_found
              message:
                type: string
                example: Tenant not found.

  /v2/identities/tenants/dataloader:
    post:
      summary: Get adminable tenants for multiple identities.
      description: Dataloader endpoint to fetch tenants for multiple identities in a single query.
      tags:
        - Identities Dataloader
      parameters:
        - name: body
          in: body
          required: true
          schema:
            type: object
            properties:
              identity_uuids:
                type: array
                items:
                  type: string
                  format: uuid
            required:
              - identity_uuids
      responses:
        '200':
          description: Successful response
          schema:
            type: object
            properties:
              identities:
                type: array
                items:
                  type: object
                  properties:
                    identity_uuid:
                      type: string
                      format: uuid
                    tenants:
                      type: array
                      items:
                        type: object
                        properties:
                          tenant_uuid:
                            type: string
                          tenant_type:
                            type: string
                          roles:
                            type: array
                            items:
                              type: string
        '401':
          description: Unauthorized

  /v2/identities:
    post:
      summary: Create a new identity v2 and assign the first set of roles to its first tenant.
      description: Endpoint to check to reate a new identity and assign the first set of roles to its first tenant.
      tags:
        - Create Identity V2
      parameters:
        - name: body
          in: body
          required: true
          schema:
            type: object
            properties:
              first_name:
                type: string
              last_name:
                type: string
              email:
                type: string
                format: email
                maxLength: 254
                description: >
                  Email address. Must satisfy Auth0 constraints: total length
                  must be 254 characters or fewer, and the local part (before @)
                  must be 64 characters or fewer.
              roles_to_attach:
                type: array
                items:
                  type: string
              tenant:
                $ref: "#/definitions/tenant"
              master_contact:
                type: boolean
              send_invite:
                type: boolean
            required:
              - first_name
              - last_name
              - email
              - roles_to_attach
              - tenant
      responses:
        '200':
          description: Successful response
          examples:
            application/json:
              {
                'id': '883fdd7a-5bda-476c-beec-e051e2ffc8b2'
              }
        '400':
          description: Validation error
          schema:
            type: object
            properties:
              code:
                type: string
                example: validation_error
              message:
                type: object
                example:
                  email:
                    - Email exceeds maximum length of 254 characters.
        '401':
          description: Unauthorized
          schema:
            type: object
            properties:
              code:
                type: string
                example: unauthorized
              message:
                type: string
                example: Request context has no identity uuid.
        '404':
          description: Tenant not found
          schema:
            type: object
            properties:
              code:
                type: string
                example: not_found
              message:
                type: string
                example: Tenant not found.

  /v2/identities/{identity_id}:
    patch:
      parameters:
        - name: identity_id
          in: path
          required: true
          type: string
        - name: body
          in: body
          required: true
          schema:
            type: object
            properties:
              roles_to_attach:
                type: array
                items:
                  type: string
              roles_to_detach:
                type: array
                items:
                  type: string
              tenant:
                $ref: "#/definitions/tenant"
            required:
              - roles_to_attach
              - roles_to_detach
              - tenant
      responses:
        '200':
          description: Success
          schema:
            type: object
            properties:
              id:
                type: string
        '404':
          description: Tenant not found
          schema:
            type: object
            properties:
              code:
                type: string
                example: not_found
              message:
                type: string
                example: Tenant not found.
    delete:
      parameters:
        - name: identity_id
          in: path
          required: true
          type: string
      responses:
        '204':
          description: Success

  /v2/profile/self/vendors/direct-access:
    get:
      summary: Get directly accessible vendors by profile
      description: |
        Get all vendors that the authenticated profile has direct access to.
        This endpoint retrieves a list of all vendors to which the authenticated profile
        has direct access permissions. The endpoint requires a valid JWT token and the
        context type must be 'profile'.
      parameters:
        - in: header
          name: Orchard-Profile-Type
          required: true
          type: string
          description: Type of the profile
        - in: header
          name: Orchard-Profile-Id
          required: true
          type: string
          description: ID of the profile
        - in: header
          name: Authorization
          required: true
          type: string
          pattern: '^Bearer [A-Za-z0-9-_=]+\.[A-Za-z0-9-_=]+\.[A-Za-z0-9-_.+/=]*'
          description: Bearer token
      responses:
        '200':
          description: Successfully retrieved list of accessible vendors
          schema:
            type: object
            properties:
              vendors:
                type: array
                items:
                  type: object
                  properties:
                    vendor_uuid:
                      type: string
                      example: "vendor_uuid_1"
                    vendor_id:
                      type: integer
                      example: 123
                  required:
                    - vendor_uuid
                    - vendor_id
            required:
              - vendors
        '401':
          description: Unauthorized
          schema:
            type: object
            properties:
              code:
                type: string
                example: unauthorized
              message:
                type: string
                example: Request context has no identity uuid.
        '403':
          description: Forbidden
          schema:
            type: object
            properties:
              code:
                type: string
                example: authorization_error
              message:
                type: string
                example: access denied

  /v2/profile/self/subaccounts/direct-access:
    get:
      summary: Get directly accessible subaccounts by profile
      description: |
        Get all subaccounts that the authenticated profile has direct access to.
        This endpoint retrieves a list of all subaccounts to which the authenticated profile
        has direct access permissions. The endpoint requires a valid JWT token and the
        context type must be 'profile'.
      parameters:
        - in: header
          name: Orchard-Profile-Type
          required: true
          type: string
          description: Type of the profile
        - in: header
          name: Orchard-Profile-Id
          required: true
          type: string
          description: ID of the profile
        - in: header
          name: Authorization
          required: true
          type: string
          pattern: '^Bearer [A-Za-z0-9-_=]+\.[A-Za-z0-9-_=]+\.[A-Za-z0-9-_.+/=]*'
          description: Bearer token
      responses:
        '200':
          description: Successfully retrieved list of accessible subaccounts
          schema:
            type: object
            properties:
              subaccounts:
                type: array
                items:
                  type: object
                  properties:
                    subaccount_uuid:
                      type: string
                      example: "subaccount_uuid_1"
                    subaccount_id:
                      type: integer
                      example: 123
                  required:
                    - subaccount_uuid
                    - subaccount_id
            required:
              - subaccounts
        '401':
          description: Unauthorized
          schema:
            type: object
            properties:
              code:
                type: string
                example: unauthorized
              message:
                type: string
                example: Request context has no identity uuid.
        '403':
          description: Forbidden
          schema:
            type: object
            properties:
              code:
                type: string
                example: authorization_error
              message:
                type: string
                example: access denied

  /v2/profile/self/all-label-access:
    get:
      summary: Check if profile has access to all labels
      description: |
        Check if the profile has access to all labels.
        This endpoint checks if the profile specified in the headers
        has access to all labels. It returns a boolean indicating whether the profile
        has such access. It returns false if the profile does not exist or has no access.
        It is meant to be a replacement endpoint for cypher access checks before a proper PDP adoption.
      parameters:
        - in: header
          name: Orchard-Identity-Id
          required: true
          type: string
          description: Identity UUID
        - in: header
          name: Orchard-Profile-Type
          required: true
          type: string
          description: Type of the profile
        - in: header
          name: Orchard-Profile-Id
          required: true
          type: string
          description: ID of the profile
      responses:
        '200':
          description: Successfully checked all label access
          schema:
            type: object
            properties:
              has_access:
                type: boolean
                description: Boolean indicating whether the profile has access to all labels
                example: true
            required:
              - has_access
        '403':
          description: Forbidden
          schema:
            type: object
            properties:
              code:
                type: string
                example: authorization_error
              message:
                type: string
                example: access denied

  /internal/v2/identities:
    post:
      summary: Internal endpoint to create an employee identity.  Should not be accessible outside VPN.
      parameters:
        - name: body
          in: body
          required: true
          schema:
            type: object
            properties:
              first_name:
                type: string
              last_name:
                type: string
              email:
                type: string
                format: email
                maxLength: 254
                description: >
                  Email address. Must satisfy Auth0 constraints: total length
                  must be 254 characters or fewer, and the local part (before @)
                  must be 64 characters or fewer.
              tenant:
                $ref: "#/definitions/tenant"
              brand:
                type: string
              roles_to_attach:
                type: array
                items:
                  type: string
            required:
              - first_name
              - last_name
              - email
              - tenant
              - brand
              - roles_to_attach
      responses:
        '201':
          description: Successfully created employee identity
          schema:
            type: object
            properties:
              id:
                type: string
                description: id of the created employee identity
        '400':
          description: Validation error
          schema:
            type: object
            properties:
              code:
                type: string
                example: validation_error
              message:
                type: object
                example:
                  email:
                    - Email exceeds maximum length of 254 characters.
        '403':
          description: Forbidden
          schema:
            type: object
            properties:
              code:
                type: string
                example: authorization_error
              message:
                type: string
                example: User is forbidden
        '401':
          description: Unauthorized
          schema:
            type: object
            properties:
              code:
                type: string
                example: unauthorized
              message:
                type: string
                example: Request context has no identity uuid.

  /internal/v2/identities/{identity_id}:
    patch:
      summary: Internal endpoint to update an employee identity. Should not be accessible outside VPN.
      parameters:
        - name: identity_id
          in: path
          required: true
          type: string
          description: The UUID of the identity to update
        - name: body
          in: body
          required: true
          schema:
            type: object
            properties:
              tenant:
                $ref: "#/definitions/tenant"
              roles_to_attach:
                type: array
                items:
                  type: string
              roles_to_detach:
                type: array
                items:
                  type: string
            required:
              - tenant
      responses:
        '200':
          description: Successfully updated employee identity
          schema:
            type: object
            properties:
              id:
                type: string
                description: id of the updated employee identity
        '400':
          description: Bad Request
          schema:
            type: object
            properties:
              code:
                type: string
                example: bad_request
              message:
                type: string
                example: Cannot remove all roles for a tenant via this endpoint. Please use revoke access endpoint instead.
        '403':
          description: Forbidden
          schema:
            type: object
            properties:
              code:
                type: string
                example: authorization_error
              message:
                type: string
                example: User is forbidden
        '404':
          description: User not found
          schema:
            type: object
            properties:
              code:
                type: string
                example: not_found
              message:
                type: string
                example: User does not exist
    delete:
      summary: Internal endpoint to delete an employee identity by revoking all access. Should not be accessible outside VPN.
      parameters:
        - name: identity_id
          in: path
          required: true
          type: string
          description: The UUID of the identity to delete
      responses:
        '204':
          description: Successfully deleted employee identity (no content)
        '403':
          description: Forbidden
          schema:
            type: object
            properties:
              code:
                type: string
                example: authorization_error
              message:
                type: string
                example: User is forbidden
        '404':
          description: User not found
          schema:
            type: object
            properties:
              code:
                type: string
                example: not_found
              message:
                type: string
                example: User does not exist

  /internal/v2/identities/{identity_id}/tenants/{tenant_type}/{tenant_uuid}:
    delete:
      summary: Internal endpoint to revoke an employee identity's access to a single account tenant. Should not be accessible outside VPN.
      description: Only the account tenant type is supported. The identity is never deactivated, even if this was their last tenant.
      parameters:
        - name: identity_id
          in: path
          required: true
          type: string
          description: The UUID of the identity whose access is being revoked.
        - name: tenant_type
          in: path
          required: true
          type: string
          description: The type of the tenant. Only "account" is supported.
        - name: tenant_uuid
          in: path
          required: true
          type: string
          description: The unique identifier of the tenant.
      responses:
        '204':
          description: Successfully revoked tenant access (no content)
        '400':
          description: Bad Request
          schema:
            type: object
            properties:
              code:
                type: string
                example: bad_request
              message:
                type: string
                example: Invalid tenant type
        '403':
          description: Forbidden
          schema:
            type: object
            properties:
              code:
                type: string
                example: authorization_error
              message:
                type: string
                example: User is forbidden
        '404':
          description: User or tenant not found
          schema:
            type: object
            properties:
              code:
                type: string
                example: not_found
              message:
                type: string
                example: Tenant not found.
