"/admin/whoami":
    get:
        tags: [Accounts]
        operationId: whoami
        summary: Current authenticated account
        description: |
            Returns sanitized account info for the caller — the JWT subject's profile.
            Accepts an OAuth bearer with `openid` scope as well as legacy app-key bearers.
        responses:
            "200":
                description: Whoami payload — different shape than the regular sanitized account.
                content:
                    application/json:
                        schema:
                            type: object
                            required: [result, accountId]
                            properties:
                                result:
                                    type: string
                                    example: "successfully authenticated"
                                accountId: { type: string }
                                username: { type: string }
                                via:
                                    type: string
                                    enum: [oauth, first-party]
                                    description: Auth method that admitted the request.
                                client:
                                    type: string
                                    description: OAuth client id (only when `via = oauth`).
                                scope:
                                    type: string
                                    description: OAuth scopes on the access token (only when `via = oauth`).
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Moderator]
        x-scopes: ["openid"]

"/admin/access/admin":
    get:
        tags: [Accounts]
        operationId: accessAdmin
        summary: Probe — caller has Admin policy
        description: Returns `"OK"` if the caller has the `Admin` access policy, otherwise `403`. Used by arda to gate admin UI.
        responses:
            "200":
                description: Caller has Admin.
                content:
                    text/plain:
                        schema: { type: string, example: OK }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["admin:all"]

"/admin/access/community":
    get:
        tags: [Accounts]
        operationId: accessCommunity
        summary: Probe — caller has CommunityModerator policy
        responses:
            "200":
                description: Caller has CommunityModerator.
                content:
                    text/plain:
                        schema: { type: string, example: OK }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [CommunityModerator]
        x-scopes: ["admin:all"]

"/admin/access/default":
    get:
        tags: [Accounts]
        operationId: accessDefault
        summary: Probe — caller has BigscreenDefault policy
        responses:
            "200":
                description: Caller has BigscreenDefault.
                content:
                    text/plain:
                        schema: { type: string, example: OK }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [BigscreenDefault]
        x-scopes: ["admin:all"]

"/admin/access/fabricator":
    get:
        tags: [Accounts]
        operationId: accessFabricator
        summary: Probe — caller has Fabricator policy
        responses:
            "200":
                description: Caller has Fabricator.
                content:
                    text/plain:
                        schema: { type: string, example: OK }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Fabricator]
        x-scopes: ["admin:all"]

"/admin/access/inventory":
    get:
        tags: [Accounts]
        operationId: accessInventory
        summary: Probe — caller has Inventory policy
        responses:
            "200":
                description: Caller has Inventory.
                content:
                    text/plain:
                        schema: { type: string, example: OK }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Inventory]
        x-scopes: ["admin:all"]

"/admin/access/moderator":
    get:
        tags: [Accounts]
        operationId: accessModerator
        summary: Probe — caller has Moderator policy
        responses:
            "200":
                description: Caller has Moderator.
                content:
                    text/plain:
                        schema: { type: string, example: OK }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Moderator]
        x-scopes: ["admin:all"]

"/admin/access/reporting":
    get:
        tags: [Accounts]
        operationId: accessReporting
        summary: Probe — caller has Reporting policy
        responses:
            "200":
                description: Caller has Reporting.
                content:
                    text/plain:
                        schema: { type: string, example: OK }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Reporting]
        x-scopes: ["admin:all"]

"/admin/access/superuser":
    get:
        tags: [Accounts]
        operationId: accessSuperUser
        summary: Probe — caller has SuperUser policy
        responses:
            "200":
                description: Caller has SuperUser.
                content:
                    text/plain:
                        schema: { type: string, example: OK }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [SuperUser]
        x-scopes: ["admin:all"]

"/admin/accounts/staff":
    get:
        tags: [Accounts]
        operationId: getStaffAccounts
        summary: List staff accounts
        description: Returns every Bigscreen staff account.
        responses:
            "200":
                description: Array of sanitized staff account objects.
                content:
                    application/json:
                        schema:
                            type: array
                            items: { $ref: "../components/schemas/AdminAccount.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["accounts:read", "admin:all"]

"/admin/account":
    post:
        tags: [Accounts]
        operationId: createBasicAccount
        summary: Create an account with email/password
        description: Creates a new account by username + email + password. Used to bootstrap test accounts and integration accounts.
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [username, email, password]
                        properties:
                            username: { type: string }
                            email: { type: string, format: email, description: Validated and normalized. }
                            password: { type: string, minLength: 6 }
        responses:
            "200":
                description: Created account (sanitized).
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/AdminAccount.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "409":
                description: Email already in use.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
            "422":
                description: Validation error.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
        x-access-policies: [Admin]
        x-scopes: ["admin:all"]

"/admin/onboarding/account":
    post:
        tags: [Accounts]
        operationId: createOnboardingAccount
        summary: Create a Bigscreen onboarding account
        description: |
            Creates a Bigscreen onboarding account. Email must be `@bigscreenvr.com`. A
            temporary password is generated server-side and returned in the response so
            the operator can hand it to the new staff member.
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [username, email]
                        properties:
                            username: { type: string }
                            email:
                                type: string
                                format: email
                                description: Must be `@bigscreenvr.com`.
        responses:
            "200":
                description: Created onboarding account, with the generated temporary password attached.
                content:
                    application/json:
                        schema:
                            allOf:
                                - $ref: "../components/schemas/AdminAccount.yaml"
                                - type: object
                                  required: [temporaryPassword]
                                  properties:
                                      temporaryPassword:
                                          type: string
                                          description: Server-generated; hand off to the new staff member out-of-band.
            "400":
                description: Email is not `@bigscreenvr.com`.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "409":
                description: Email already in use.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
            "422":
                description: Validation error.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
        x-access-policies: [Admin]
        x-scopes: ["accounts:write", "admin:all"]

"/admin/account/{bigscreenAccountId}/access_policy/{accessPolicy}":
    parameters:
        - in: path
          name: bigscreenAccountId
          required: true
          schema: { type: string }
          description: Target account id.
        - in: path
          name: accessPolicy
          required: true
          schema: { type: string }
          description: One of `EditableAccessPolicies` (e.g. `Moderator`, `Fabricator`, `Inventory`).
    put:
        tags: [Accounts]
        operationId: addAccessPolicyToAccount
        summary: Grant an access policy to an account
        description: Adds an access policy to an account. Target account must have a `@bigscreenvr.com` email.
        responses:
            "200":
                description: Policy added.
            "400":
                description: Invalid domain or account already has the policy.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403":
                description: Caller lacks permission.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
            "404":
                description: Account not found.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
        x-access-policies: [Admin]
        x-scopes: ["accounts:write", "admin:all"]
    delete:
        tags: [Accounts]
        operationId: removeAccessPolicyFromAccount
        summary: Revoke an access policy from an account
        description: Removes an access policy from an account. Target must have a `@bigscreenvr.com` email.
        responses:
            "200":
                description: Policy removed.
            "400":
                description: Invalid domain or account does not have the policy.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403":
                description: Caller lacks permission.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
            "404":
                description: Account not found.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
        x-access-policies: [Admin]
        x-scopes: ["accounts:write", "admin:all"]

"/admin/account/{bigscreenAccountId}/security_groups":
    parameters:
        - in: path
          name: bigscreenAccountId
          required: true
          schema: { type: string }
    get:
        tags: [Accounts]
        operationId: getSecurityGroupInfo
        summary: AWS security group entries for an account
        description: Returns AWS EC2 security group IP entries filtered to the supplied account.
        responses:
            "200":
                description: Filtered AWS security group payload.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                GroupId: { type: string }
                                GroupName: { type: string }
                                Description: { type: string }
                                IpPermissions:
                                    type: array
                                    description: Per-rule permissions limited to entries tagged with this account.
                                    items:
                                        type: object
                                        properties:
                                            IpProtocol: { type: string }
                                            FromPort: { type: integer }
                                            ToPort: { type: integer }
                                            IpRanges:
                                                type: array
                                                items:
                                                    type: object
                                                    properties:
                                                        CidrIp: { type: string }
                                                        Description: { type: string }
                                            Ipv6Ranges:
                                                type: array
                                                items:
                                                    type: object
                                                    properties:
                                                        CidrIpv6: { type: string }
                                                        Description: { type: string }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: Account not found.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
        x-access-policies: [Admin]
        x-scopes: ["accounts:read", "admin:all"]

"/admin/account/{bigscreenAccountId}/security_groups/{ip}":
    parameters:
        - in: path
          name: bigscreenAccountId
          required: true
          schema: { type: string }
        - in: path
          name: ip
          required: true
          schema: { type: string }
          description: Valid IPv4 or IPv6 address. `/32` (v4) or `/128` (v6) suffix is auto-appended.
    put:
        tags: [Accounts]
        operationId: addSecurityGroupEntry
        summary: Allowlist an IP for an account
        description: Adds the supplied IP to the AWS security group, attributed to the supplied account.
        responses:
            "200":
                description: IP allowlisted.
            "400":
                description: IP already exists or account has no email.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403":
                description: Caller is not Admin.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
            "404":
                description: Account not found.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
        x-access-policies: [Admin]
        x-scopes: ["accounts:write", "admin:all"]
    delete:
        tags: [Accounts]
        operationId: removeSecurityGroupEntry
        summary: Remove an IP from an account's allowlist
        description: Removes the supplied IP from the AWS security group entry attributed to the supplied account.
        responses:
            "200":
                description: IP removed.
            "400":
                description: IP not found or account has no email.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403":
                description: Caller is not Admin.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
            "404":
                description: Account not found.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
        x-access-policies: [Admin]
        x-scopes: ["accounts:write", "admin:all"]
