openapi: 3.0.3
info:
  title: PUP - Tournament API v1
  description: >
    PUP is the universal player profile for padel. Players can use PUP to track their performance, playing style, and 
    statistics – no matter where they play.
  version: 1.0.0

servers:
  - url: https://api.gopup.app/
    description: Development server

x-tagGroups:
  - name: Tournament
    tags:
      - tournament

tags:
  - name: tournament
    x-displayName: "Tournament"
    description: Operations related to tournaments

paths:
  /tournament/v1/search:
    get:
      tags:
        - tournament
      summary: Search tournaments
      description: Returns paginated list of results
      operationId: searchTournaments
      parameters:
        - in: query
          name: term
          example: Championship
          description: Term to search tournaments by
          schema:
            type: string
        - in: query
          name: club
          example: Home padel
          schema:
            type: string
        - in: query
          name: date_from
          example: 2025-10-23
          description: >
            Date of tournament to filter on (range start)
          schema:
            type: string
            format: date
        - in: query
          name: date_to
          example: 2025-10-30
          description: >
            Date of tournament to filter on (range end)
          schema:
            type: string
            format: date
        - in: query
          name: registration_opens_at_from
          example: 2025-10-01
          description: >
            Registration open date of tournament to filter on (range start)
          schema:
            type: string
            format: date
        - in: query
          name: registration_opens_at_to
          example: 2025-10-10
          description: >
            Registration open date of tournament to filter on (range end)
          schema:
            type: string
            format: date
        - in: query
          name: registration_closes_at_from
          example: 2025-10-10
          description: >
            Registration close date of tournament to filter on (range start)
          schema:
            type: string
            format: date
        - in: query
          name: registration_closes_at_to
          example: 2025-10-15
          description: >
            Registration close date of tournament to filter on (range end)
          schema:
            type: string
            format: date
        - in: query
          name: geoloc_lat
          example: 52.3534646
          description: User geolocation latitude for searching nearby tournaments
          schema:
            type: number
            format: float
        - in: query
          name: geoloc_lng
          example: 4.9037305
          description: User geolocation longitude for searching nearby tournaments
          schema:
            type: number
            format: float
        - in: query
          name: geoloc_radius
          example: 20
          description: >
            Radius (in km) for searching nearby tournaments. Only works when geoloc_lat and geoloc_lng are also set
          schema:
            type: integer
        - in: query
          name: offset
          example: 20
          description: Results offset (useful for pagination)
          schema:
            type: integer
        - in: query
          name: limit
          example: 20
          description: Results limit (useful for pagination)
          schema:
            type: integer
      security:
        - OAuth2:
            - urn:pup:tournament:read
        - PAT: []
      responses:
        '200':
          description: The search results
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SearchResponse"
        '401':
          description: Unauthorized - invalid or missing JWT
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
                    example: "invalid or missing token"
        default:
          description: Generic error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /tournament/v1/tournament/{id}:
    get:
      parameters:
        - in: path
          name: id
          required: true
          description: Tournament identifier
          example: 914aedf2-4233-41f6-980b-4824ee185e82
          schema:
            type: string
      tags:
        - tournament
      summary: Show a tournament by ID
      description: Returns the details for a particular tournament
      operationId: getTournament
      security:
        - OAuth2:
            - urn:pup:tournament:read
        - PAT: []
      responses:
        '200':
          description: The requested tournament details
          content:
            application/json:
              schema:
                type: object
                required:
                  - tournament
                properties:
                  tournament:
                    $ref: '#/components/schemas/Tournament'
        '404':
          description: Tournament not found
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
                    example: "Tournament not found"
        '401':
          description: Unauthorized - invalid or missing JWT
          content:
            application/json:
              schema:
                type: object
                required:
                  - error
                properties:
                  error:
                    type: string
                    example: "invalid or missing token"
        default:
          description: Generic error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

components:
  schemas:
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          example: "An error message"
      description: Generic error response

    Tournament:
      type: object
      required:
        - id
        - club
        - name
        - date
        - location
        - registration
        - participants_limit
        - open_spots
      properties:
        id:
          type: string
          description: Unique identifier of the tournament
          example: 914aedf2-4233-41f6-980b-4824ee185e82
        club:
          type: string
          description: The name of the club hosting the event
          example: Home Padel
        image_url:
          type: string
          description: Tournament image
          format: url
          example: https://cdn.example.com/tournaments/home-padel-open-october-2025.png
        name:
          type: string
          description: Name of the tournament
          example: Home Padel Open 2025
        description:
          type: string
          description: Tournament description
          example: An open padel tournament for beginner, intermediate and advanced players
        date:
          type: string
          format: date
          description: Date of the event
          example: 2025-10-31
        location:
          type: object
          description: Tournament location
          required:
            - name
            - description
            - address
          properties:
            name:
              type: string
              description: Location name
              example: Home Padel
            description:
              type: string
              description: Location description
              example: Hoom Padel in Hoofddorp
            address:
              type: object
              description: Address
              required:
                - street
                - city
                - postal_code
                - country
                - geolocation
              properties:
                street:
                  type: string
                  description: Tournament location street address
                  example: Parellaan 70
                city:
                  type: string
                  description: Tournament location city
                  example: Hoofddorp
                postal_code:
                  type: string
                  description: Tournament location postal code
                  example: 2132 WS
                country:
                  type: string
                  description: Tournament location country code
                  example: NL
                  enum: [ AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM, AW, AU, AT, AZ, BS, BH, BD, BB, BY, BE, BZ, BJ, BM, BT, BO, BQ, BA, BW, BV, BR, IO, BN, BG, BF, BI, CV, KH, CM, CA, KY, CF, TD, CL, CN, CX, CC, CO, KM, CG, CD, CK, CR, CI, HR, CU, CW, CY, CZ, DK, DJ, DM, DO, EC, EG, SV, GQ, ER, EE, SZ, ET, FK, FO, FJ, FI, FR, GF, PF, TF, GA, GM, GE, DE, GH, GI, GR, GL, GD, GP, GU, GT, GG, GN, GW, GY, HT, HM, VA, HN, HK, HU, IS, IN, ID, IR, IQ, IE, IM, IL, IT, JM, JP, JE, JO, KZ, KE, KI, KP, KR, KW, KG, LA, LV, LB, LS, LR, LY, LI, LT, LU, MO, MG, MW, MY, MV, ML, MT, MH, MQ, MR, MU, YT, MX, FM, MD, MC, MN, ME, MS, MA, MZ, MM, NA, NR, NP, NL, NC, NZ, NI, NE, NG, NU, NF, MK, MP, "NO", OM, PK, PW, PS, PA, PG, PY, PE, PH, PN, PL, PT, PR, QA, RE, RO, RU, RW, BL, SH, KN, LC, MF, PM, VC, WS, SM, ST, SA, SN, RS, SC, SL, SG, SX, SK, SI, SB, SO, ZA, GS, SS, ES, LK, SD, SR, SJ, SE, CH, SY, TW, TJ, TZ, TH, TL, TG, TK, TO, TT, TN, TR, TM, TC, TV, UG, UA, AE, GB, US, UM, UY, UZ, VU, VE, VN, VG, VI, WF, EH, YE, ZM, ZW ]
                geolocation:
                  type: object
                  required:
                    - latitude
                    - longitude
                  properties:
                    latitude:
                      type: number
                      format: float
                      minimum: -90
                      maximum: 90
                      description: Location latitude
                      example: 52.289222
                    longitude:
                      type: number
                      format: float
                      minimum: -180
                      maximum: 180
                      description: Location longitude
                      example: 4.686748
        registration:
          type: object
          required:
            - opens_at
            - closes_at
            - url
          properties:
            opens_at:
              type: string
              format: date
              description: Registration open date
              example: 2025-10-01
            closes_at:
              type: string
              format: date
              description: Registration close date
              example: 2025-10-30
            url:
              type: string
              format: url
              description: Registration website
              example: https://example.com/register/padel-open-2025
        participants_limit:
          type: integer
          description: Limit of tournament participants
          example: 30
        open_spots:
          type: integer
          description: Open spots left
        distance:
          type: number
          format: float
          description: >
            Distance (in km) from user geolocation. Returned only when query includes user's geolocation

    ResponseMetaMany:
      type: object
      required:
        - pagination
      properties:
        pagination:
          type: object
          required:
            - total
            - returned
            - offset
            - limit
          properties:
            total:
              type: integer
              description: Total number of matching records
              example: 145
            returned:
              type: integer
              description: Number of records actually returned in this response
              example: 20
            offset:
              type: integer
              description: Offset used in the request
              example: 100
            limit:
              type: integer
              description: Limit used in the request
              example: 20
            next:
              type: string
              description: Relative path to next page of results
              example: /tournament/v1/search?term=something&offset=120&limit=20
            previous:
              type: string
              description: Relative path to previous page of results
              example: /tournament/v1/search?term=something&offset=80&limit=20

    SearchResponse:
      type: object
      required:
        - hits
        - meta
      properties:
        hits:
          type: array
          items:
            $ref: '#/components/schemas/Tournament'
        meta:
          $ref: '#/components/schemas/ResponseMetaMany'

  securitySchemes:
    OAuth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: "https://oauth2.gopup.app/oauth2/auth"
          tokenUrl: "https://oauth2.gopup.app/oauth2/token"
          scopes:
            urn:pup:tournament:read: "Read tournament data"
      description: OAuth2

    PAT:
      type: http
      scheme: bearer
      bearerFormat: PAT
      description: Personal Access Token
