openapi: 3.0.1
info:
  title: Teams REST APIs
  description: Teams Internal REST APIs used by other Plumery services (e.g. authentication, session verification).
  version: '1'
servers:
  - url: 'https://api.plumery.com'
    description: Live Server
paths:
  '/internal/v1/invitations/{invitationId}':
    get:
      tags:
        - Internal Invitations
      description: |
        Retrieve detailed information about a specified invitation.
      operationId: getInvitationInternal
      summary: Retrieve invitation
      parameters:
        - $ref: '#/components/parameters/invitationId'
      responses:
        '200':
          description: A detailed information of a specified invitation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalInvitationInfo'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: Invitation not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  code:
                    type: string
                    enum:
                      - 'urn:plmr:teams:api:RESOURCE_UNKNOWN'
                      - 'urn:plmr:teams:api:INVITATION_NOT_FOUND'
                      - 'urn:plmr:teams:api:TEAM_NOT_FOUND'
                  message:
                    type: string
                  requestId:
                    type: string
        '500':
          $ref: '#/components/responses/InternalServerError'

  '/internal/v1/parties/{organisationPartyId}/teams:verify-active-membership':
    post:
      tags:
        - Internal Teams
      description: |
        Verifies whether the provided member has an active membership within any team of the organisation.
      operationId: verifyActiveMembership
      summary: Verify active membership
      parameters:
        - $ref: '#/components/parameters/organisationPartyId'
        - $ref: '#/components/parameters/requestId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerifyActiveMembershipRequest'
      responses:
        '200':
          description: Information about the member's access to organisation teams
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActiveMembershipVerificationResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: Member not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  code:
                    type: string
                    enum:
                      - 'urn:plmr:teams:api:RESOURCE_UNKNOWN'
                      - 'urn:plmr:teams:api:MEMBER_NOT_FOUND'
                  message:
                    type: string
                  requestId:
                    type: string
        '500':
          $ref: '#/components/responses/InternalServerError'

  '/internal/v1/parties/{organisationPartyId}/teams/{teamId}/members/{memberId}':
    get:
      tags:
        - Internal Teams
      description: |
        Retrieve internal team member details including status, assigned roles and the permissions
        granted through those roles.
      operationId: getTeamMember
      summary: Retrieve team member
      parameters:
        - $ref: '#/components/parameters/organisationPartyId'
        - $ref: '#/components/parameters/teamId'
        - $ref: '#/components/parameters/memberId'
        - $ref: '#/components/parameters/requestId'
      responses:
        '200':
          description: Team member details including status and roles
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalTeamMemberResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: Team or member not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  code:
                    type: string
                    enum:
                      - 'urn:plmr:teams:api:RESOURCE_UNKNOWN'
                      - 'urn:plmr:teams:api:TEAM_NOT_FOUND'
                      - 'urn:plmr:teams:api:MEMBER_NOT_FOUND'
                  message:
                    type: string
                  requestId:
                    type: string
        '500':
          $ref: '#/components/responses/InternalServerError'

components:
  parameters:
    requestId:
      in: header
      name: X-Request-ID
      description: Request ID used for tracing. A new one will be generated if not provided.
      required: false
      example: 36a22460-ebc8-4ffe-a213-1683c5a420c5
      schema:
        type: string

    organisationPartyId:
      in: path
      name: organisationPartyId
      required: true
      example: 6878951b-256b-4baa-9e81-ad4c577adc4e
      schema:
        type: string
      description: The unique identifier of the organisation party.

    teamId:
      in: path
      name: teamId
      required: true
      example: 3ae18e3d-afb1-4434-a7cc-e4a9e5e8fc31
      schema:
        type: string
      description: The unique identifier of the team.

    memberId:
      in: path
      name: memberId
      required: true
      example: 4c3882fd-ac4c-41da-9bc0-4d5ce5f55727
      schema:
        type: string
      description: The unique identifier of the team member.

    invitationId:
      in: path
      name: invitationId
      required: true
      example: d9721969-a328-47f4-b22b-e4cf35630eed
      schema:
        type: string
      description: The unique identifier of the invitation.

  responses:
    BadRequest:
      description: Invalid request was provided
      content:
        application/json:
          schema:
            type: object
            properties:
              code:
                type: string
                enum:
                  - 'urn:plmr:teams:api:BAD_REQUEST'
                  - 'urn:plmr:teams:api:INVALID_PARAM'
                  - 'urn:plmr:teams:api:WEB_APPLICATION'
              message:
                type: string
              requestId:
                type: string
              fieldErrors:
                type: array
                items:
                  $ref: '#/components/schemas/FieldError'

    Unauthorized:
      description: Session cookie missing or invalid
      content:
        application/json:
          schema:
            type: object
            properties:
              code:
                type: string
                enum:
                  - 'urn:plmr:teams:api:UNAUTHORIZED'
              message:
                type: string
              requestId:
                type: string

    InternalServerError:
      description: Internal server error occurred
      content:
        application/json:
          schema:
            type: object
            properties:
              code:
                type: string
                enum:
                  - 'urn:plmr:teams:api:INTERNAL_SERVER_ERROR'
              message:
                type: string
              requestId:
                type: string

  schemas:
    MemberStatus:
      type: string
      description: Status of a team member.
      enum:
        - PENDING
        - ACTIVE
        - SUSPENDED

    RoleId:
      type: string
      description: Identifier of a role assignable to a team member.
      example: ADMIN

    MemberId:
      type: string
      description: Identifier of a team member.
      example: 4c3882fd-ac4c-41da-9bc0-4d5ce5f55727

    InvitationDelivery:
      type: object
      description: Represents the delivery channel details of an invitation.
      properties:
        type:
          type: string
          description: The channel used to deliver the invitation (e.g., EMAIL, PHONE_NUMBER).
          example: EMAIL
        value:
          type: string
          description: The address or number the invitation is delivered to.
          example: user@example.com

    Team:
      type: object
      description: Minimal representation of a team.
      properties:
        teamId:
          description: Team unique identifier.
          type: string
          example: 3ae18e3d-afb1-4434-a7cc-e4a9e5e8fc31
        name:
          description: Team name.
          type: string
          example: Acme Corp

    InternalInvitationInfo:
      type: object
      description: Internal representation of an invitation.
      properties:
        delivery:
          $ref: '#/components/schemas/InvitationDelivery'
        organisationPartyId:
          description: The ID of the organisation party.
          type: string
          example: 6878951b-256b-4baa-9e81-ad4c577adc4e
        organisationLegalName:
          description: The legal name of the organisation party.
          type: string
          example: Plumery

    VerifyActiveMembershipRequest:
      type: object
      description: Request body for the verify-active-membership operation.
      required:
        - memberId
      properties:
        memberId:
          $ref: '#/components/schemas/MemberId'

    ActiveMembershipVerificationResponse:
      type: object
      description: Result of verifying whether a member has active memberships within an organisation.
      properties:
        userId:
          description: The unique identifier of the user linked to the member.
          type: string
          example: 3ae18e3d-afb1-4434-a7cc-e4a9e5e8fc31
        activeTeams:
          type: array
          items:
            $ref: '#/components/schemas/Team'

    InternalTeamMemberResponse:
      type: object
      description: Internal representation of a team member's status and assigned roles.
      properties:
        status:
          $ref: '#/components/schemas/MemberStatus'
        roles:
          type: array
          description: The set of role IDs assigned to the member.
          uniqueItems: true
          items:
            $ref: '#/components/schemas/RoleId'
        permissions:
          type: array
          description: The permissions granted to the member through their assigned role.
          items:
            $ref: '#/components/schemas/Permission'

    Permission:
      type: object
      description: A permission object represents a privilege granted to a role, mapping an action they can perform
        within a certain teams context on a specific resource.
      properties:
        resource:
          description: |
            This is the specific entity the permission applies to within the system. This could represent a system 
            feature or data object the user interacts with. For example, a 'resource' could be 'payments' or 'accounts'.
          type: string
        action:
          description: |
            The 'action' is what operation can be performed on the 'resource'. This is typically an action word, 
            indicating operations like 'create', 'read', 'update', 'remove', or others depending on resource. For 
            example, a user with 'read' action on 'payments' resource can view payments.
          type: string
        category:
          description: |
            'Category' provides a way to logically group related resources. This can be helpful for organizing
            permissions. For example, you might have categories such as 'Account Management', 'Payment Processing' and
            group related resources under these categories.
          type: string

    FieldError:
      type: object
      description: Represents a per-field validation error.
      properties:
        code:
          type: string
          example: 'urn:plmr:teams:api:NOT_NULL'
        message:
          type: string
        field:
          type: string