openapi: 3.1.0
info:
  title: Pulse Arena
  description: >
    Aldenburg event-ticketing verifier. 18+ purchases run OpenID4VP with a DCQL
    query for only `age_over_18` from `urn:aldenburg:pid` (dc+sd-jwt). Tickets
    store the boolean check result and a timestamp — no personal PID claims.
  version: 0.1.0
paths:
  /:
    get:
      summary: Public storefront listing 18+ and all-ages events
      responses:
        '200':
          description: HTML storefront
  /events/{eventId}/buy:
    post:
      summary: Start purchase. 18+ events redirect to an OpenID4VP age check.
      parameters:
        - in: path
          name: eventId
          required: true
          schema: { type: string }
      responses:
        '303':
          description: Redirect to /age-checks/{id} or /tickets/{id}
  /age-checks/{id}:
    get:
      summary: Same-device deep link + cross-device QR. Polls until direct_post.
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
      responses:
        '200':
          description: HTML age-check page or rejection page
        '303':
          description: Redirect to the issued ticket
  /tickets/{id}:
    get:
      summary: Anonymous ticket plus "what does the venue see?" panel
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
      responses:
        '200':
          description: HTML ticket page
  /api/events:
    get:
      summary: Event catalog
      responses:
        '200':
          description: JSON event list
  /api/events/{eventId}/age-checks:
    post:
      summary: Create an OpenID4VP authorization request (JAR, DCQL, direct_post)
      parameters:
        - in: path
          name: eventId
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Authorization request URI, deep link, DCQL, QR svg
          content:
            application/json:
              schema:
                type: object
                required: [id, authorization_request, deep_link, dcql]
                properties:
                  id: { type: string }
                  authorization_request: { type: string }
                  deep_link: { type: string }
                  nonce: { type: string }
                  audience: { type: string }
                  qr_svg: { type: string }
                  dcql: { type: object }
        '400':
          description: Event is not age-restricted
  /api/events/{eventId}/tickets:
    post:
      summary: Issue an all-ages ticket (no presentation)
      parameters:
        - in: path
          name: eventId
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Ticket with age_over_18=false and timestamp only
        '400':
          description: Event requires an age check
  /api/age-checks/{id}:
    get:
      summary: Poll age-check status after the wallet posts direct_post
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
      responses:
        '200':
          description: pending | verified | rejected. Verified includes venue_view.
  /api/tickets/{id}:
    get:
      summary: Anonymous ticket record (boolean + timestamp, no personal data)
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Ticket JSON
  /oid4vp/{verifierId}/authorize:
    post:
      summary: OpenID4VP direct_post response endpoint (Credo)
      parameters:
        - in: path
          name: verifierId
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Presentation accepted by the protocol layer
  /oid4vp/{verifierId}/authorization-requests/{authorizationRequestId}:
    get:
      summary: Hosted signed authorization request (JAR)
      parameters:
        - in: path
          name: verifierId
          required: true
          schema: { type: string }
        - in: path
          name: authorizationRequestId
          required: true
          schema: { type: string }
      responses:
        '200':
          description: application/oauth-authz-req+jwt
  /openapi.yaml:
    get:
      summary: This OpenAPI document
      responses:
        '200':
          description: YAML
