openapi: 3.1.0
info:
  title: UrlShortener
  version: 0.1.0
  description: API for UrlShortener. Generated from formal specification.
servers:
- url: http://localhost:8000
  description: Local development
paths:
  /metrics:
    get:
      operationId: infra_metrics
      summary: Prometheus metrics
      description: Prometheus text exposition format.
      tags:
      - infrastructure
      responses:
        '200':
          description: Current metric values
          content:
            text/plain:
              schema:
                type:
                - string
  /urls:
    get:
      operationId: list_all
      summary: ListAll
      tags:
      - url_mapping
      parameters:
      - name: limit
        in: query
        required: false
        description: Number of items to return; default 50, clamped to [1, 100].
        schema:
          type:
          - integer
          format: int32
      - name: offset
        in: query
        required: false
        description: Number of items to skip; default 0, negative values are treated as 0.
        schema:
          type:
          - integer
          format: int32
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type:
                - array
                items:
                  $ref: '#/components/schemas/UrlMappingRead'
  /{code}:
    get:
      operationId: resolve
      summary: Resolve
      tags:
      - url_mapping
      parameters:
      - name: code
        in: path
        required: true
        schema:
          type:
          - string
          minLength: 6
          maxLength: 10
          pattern: ^[a-zA-Z0-9]+$
      responses:
        '302':
          description: Redirect
          headers:
            Location:
              description: Target URL
              schema:
                type:
                - string
                format: uri
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      operationId: delete
      summary: Delete
      tags:
      - url_mapping
      parameters:
      - name: code
        in: path
        required: true
        schema:
          type:
          - string
          minLength: 6
          maxLength: 10
          pattern: ^[a-zA-Z0-9]+$
      responses:
        '204':
          description: No content
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /health:
    get:
      operationId: infra_health_check
      summary: Health check
      description: Returns 200 if the service is running.
      tags:
      - infrastructure
      responses:
        '200':
          description: Service is healthy
          content:
            application/json:
              schema:
                type:
                - object
                required:
                - status
                properties:
                  status:
                    type:
                    - string
                    enum:
                    - ok
  /ready:
    get:
      operationId: infra_readiness_check
      summary: Readiness check
      description: Returns 200 when the database answers a probe query, 503 otherwise.
      tags:
      - infrastructure
      responses:
        '200':
          description: Service is ready
          content:
            application/json:
              schema:
                type:
                - object
                required:
                - status
                properties:
                  status:
                    type:
                    - string
                    enum:
                    - ready
        '503':
          description: Database is unreachable
          content:
            application/json:
              schema:
                type:
                - object
                required:
                - status
                properties:
                  status:
                    type:
                    - string
                    enum:
                    - unavailable
  /admin/state:
    get:
      operationId: admin_state
      summary: Export spec-level state
      description: Returns the service state projected onto the spec's state fields.
      tags:
      - admin
      responses:
        '200':
          description: State projection
          content:
            application/json:
              schema:
                type:
                - object
                additionalProperties: true
        '401':
          description: Missing or invalid admin credential
          headers:
            WWW-Authenticate:
              description: Bearer authentication challenge
              schema:
                type:
                - string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Admin surface disabled (no ADMIN_TOKEN configured on the service)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
      - AdminBearer: []
  /admin/reset:
    post:
      operationId: admin_reset
      summary: Re-initialize service state
      description: Deletes all entity rows and restores scalar state fields to their invariant-derived
        seeds.
      tags:
      - admin
      responses:
        '204':
          description: State re-initialized
        '401':
          description: Missing or invalid admin credential
          headers:
            WWW-Authenticate:
              description: Bearer authentication challenge
              schema:
                type:
                - string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Admin surface disabled (no ADMIN_TOKEN configured on the service)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
      - AdminBearer: []
  /shorten:
    post:
      operationId: shorten
      summary: Shorten
      tags:
      - url_mapping
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UrlMappingCreate'
      responses:
        '201':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UrlMappingRead'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    ErrorResponse:
      type:
      - object
      required:
      - detail
      properties:
        detail:
          type:
          - string
          description: Human-readable error description
      description: Standard error response body
    UrlMappingCreate:
      type:
      - object
      required:
      - code
      - url
      - created_at
      - click_count
      properties:
        code:
          type:
          - string
          minLength: 6
          maxLength: 10
          pattern: ^[a-zA-Z0-9]+$
        url:
          type:
          - string
          minLength: 1
        created_at:
          type:
          - string
          format: date-time
        click_count:
          type:
          - integer
          minimum: 0.0
      description: Create payload for UrlMapping
    UrlMappingRead:
      type:
      - object
      required:
      - id
      - code
      - url
      - created_at
      - click_count
      properties:
        url:
          type:
          - string
          minLength: 1
        code:
          type:
          - string
          minLength: 6
          maxLength: 10
          pattern: ^[a-zA-Z0-9]+$
        created_at:
          type:
          - string
          format: date-time
        click_count:
          type:
          - integer
          minimum: 0.0
        id:
          type:
          - integer
      description: Read view for UrlMapping
    UrlMappingUpdate:
      type:
      - object
      properties:
        code:
          type:
          - string
          - 'null'
          minLength: 6
          maxLength: 10
          pattern: ^[a-zA-Z0-9]+$
        url:
          type:
          - string
          - 'null'
          minLength: 1
        created_at:
          type:
          - string
          - 'null'
          format: date-time
        click_count:
          type:
          - integer
          - 'null'
          minimum: 0.0
      description: Update payload for UrlMapping
  securitySchemes:
    AdminBearer:
      type: http
      scheme: bearer
      description: Admin surface credential (ADMIN_TOKEN). With no token configured on the service, /admin
        routes answer 404.
tags:
- name: url_mapping
  description: UrlMapping operations
- name: infrastructure
  description: Health and metrics endpoints
- name: admin
  description: Bearer-guarded admin surface (state export / seed / reset)
x-invariant:
  allURLsValid: (all c in store | isValidURI(store[c]))
  metadataConsistent: (dom(store) = dom(metadata))
  clickCountNonNegative: (all c in metadata | (metadata[c].click_count >= 0))
