openapi: 3.0.3
info:
  title: Shoehorn Teams API
  description: Team management, members, group mappings, and role assignments.
  version: 1.0.0

servers:
  - url: https://shoehorn.example.com/api/v1
    description: Production

paths:
  /teams:
    get:
      summary: List teams (public)
      description: Returns teams visible to the current user.
      tags: [Teams]
      parameters:
        - name: limit
          in: query
          schema: { type: integer, default: 20 }
        - name: cursor
          in: query
          schema: { type: string }
      responses:
        '200':
          description: List of teams

  /teams/{id_or_slug}:
    get:
      summary: Get team by ID or slug (public)
      description: Accepts either a UUID or a team slug.
      tags: [Teams]
      parameters:
        - name: id_or_slug
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Team details with members, mappings, and audit log
          content:
            application/json:
              schema: { $ref: '#/components/schemas/TeamDetailsResponse' }

  /admin/teams:
    get:
      summary: List all teams (admin)
      tags: [Admin Teams]
      responses:
        '200':
          description: All teams

    post:
      summary: Create team
      tags: [Admin Teams]
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/CreateTeamRequest' }
      responses:
        '201':
          description: Team created

  /admin/teams/{id}:
    get:
      summary: Get team (admin)
      tags: [Admin Teams]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Team details

    put:
      summary: Update team
      tags: [Admin Teams]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/UpdateTeamRequest' }
      responses:
        '200':
          description: Team updated

    delete:
      summary: Delete team
      tags: [Admin Teams]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        '204':
          description: Team deleted

  /admin/teams/{id}/members:
    get:
      summary: List team members
      tags: [Admin Teams]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Team members

    post:
      summary: Add team member
      tags: [Admin Teams]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [user_id, role]
              properties:
                user_id: { type: string }
                role: { type: string, enum: [lead, member, viewer] }
      responses:
        '201':
          description: Member added

  /admin/teams/{id}/members/{memberId}:
    delete:
      summary: Remove team member
      tags: [Admin Teams]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
        - name: memberId
          in: path
          required: true
          schema: { type: string }
      responses:
        '204':
          description: Member removed

  /admin/teams/{id}/mappings:
    get:
      summary: List group mappings
      tags: [Admin Teams]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Group-to-team mappings

    post:
      summary: Add group mapping
      tags: [Admin Teams]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [group_name, provider]
              properties:
                group_name: { type: string }
                provider: { type: string }
                role: { type: string, enum: [lead, member, viewer] }
      responses:
        '201':
          description: Mapping created

  /admin/teams/{id}/mappings/{mappingId}:
    delete:
      summary: Remove group mapping
      tags: [Admin Teams]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
        - name: mappingId
          in: path
          required: true
          schema: { type: string }
      responses:
        '204':
          description: Mapping removed

  /admin/teams/{id}/roles:
    get:
      summary: Get team role assignments
      tags: [Admin Teams]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Roles assigned to team

    post:
      summary: Assign role to team
      tags: [Admin Teams]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [role_id]
              properties:
                role_id: { type: string }
      responses:
        '201':
          description: Role assigned

  /admin/teams/{id}/roles/{roleId}:
    delete:
      summary: Remove role from team
      tags: [Admin Teams]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
        - name: roleId
          in: path
          required: true
          schema: { type: string }
      responses:
        '204':
          description: Role removed

components:
  schemas:
    TeamDetailsResponse:
      type: object
      properties:
        team: { $ref: '#/components/schemas/Team' }
        members:
          type: array
          items: { $ref: '#/components/schemas/TeamMember' }
        group_mappings:
          type: array
          items: { $ref: '#/components/schemas/GroupMapping' }
        audit_log:
          type: array
          items: { type: object }

    Team:
      type: object
      properties:
        id: { type: string, format: uuid }
        name: { type: string }
        slug: { type: string }
        description: { type: string }
        metadata: { type: object }
        parent_id: { type: string, format: uuid }
        created_at: { type: string, format: date-time }
        updated_at: { type: string, format: date-time }

    TeamMember:
      type: object
      properties:
        user_id: { type: string }
        name: { type: string }
        email: { type: string }
        role: { type: string, enum: [lead, member, viewer] }

    GroupMapping:
      type: object
      properties:
        id: { type: string, format: uuid }
        group_name: { type: string }
        provider: { type: string }
        role: { type: string }

    CreateTeamRequest:
      type: object
      required: [name]
      properties:
        name: { type: string }
        slug: { type: string }
        description: { type: string }
        parent_id: { type: string }
        metadata: { type: object }

    UpdateTeamRequest:
      type: object
      properties:
        name: { type: string }
        description: { type: string }
        parent_id: { type: string }
        metadata: { type: object }
