openapi: 3.0.3
info:
  title: VeritaMetrics API
  description: Privacy-focused server-side web analytics API.
  version: 1.0.0
  contact:
    url: https://www.kirokuforms.com

servers:
  - url: https://www.kirokuforms.com
    description: Production

paths:
  /api/track-pageview:
    get:
      summary: Track a page view
      description: Main tracking endpoint used by the tracking pixel. Returns a 1x1 transparent image.
      tags: [Tracking]
      parameters:
        - name: url
          in: query
          required: true
          schema: { type: string }
          description: The page path being visited
        - name: site
          in: query
          required: true
          schema: { type: string }
          description: The site identifier
      responses:
        '200':
          description: 1x1 tracking pixel
          content:
            image/gif: {}

  /api/event:
    post:
      summary: Track a custom event
      tags: [Tracking]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [eventName, url]
              properties:
                eventName: { type: string }
                url: { type: string }
                properties:
                  type: object
                  additionalProperties: true
      responses:
        '200':
          description: Event recorded

  /api/analytics/data:
    get:
      summary: Get dashboard analytics data
      tags: [Analytics]
      parameters:
        - name: range
          in: query
          schema: { type: string, example: '30d' }
        - name: site
          in: query
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Analytics data
          content:
            application/json: {}

  /api/analytics/export:
    get:
      summary: Export analytics data
      tags: [Analytics]
      parameters:
        - name: type
          in: query
          schema: { type: string, enum: [pageviews, sessions, events] }
        - name: format
          in: query
          schema: { type: string, enum: [csv, json] }
        - name: startDate
          in: query
          schema: { type: string, format: date }
        - name: endDate
          in: query
          schema: { type: string, format: date }
      responses:
        '200':
          description: Exported data

  /api/analytics/raw-events:
    get:
      summary: Get raw event data
      tags: [Analytics]
      responses:
        '200':
          description: Raw event records

  /api/analytics/sessions:
    get:
      summary: List sessions
      tags: [Analytics]
      responses:
        '200':
          description: Session list

  /api/analytics/sessions/{visitId}:
    get:
      summary: Get session details
      tags: [Analytics]
      parameters:
        - name: visitId
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Session details

  /api/auth/login:
    post:
      summary: Log in with email and password
      tags: [Auth]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email, password]
              properties:
                email: { type: string, format: email }
                password: { type: string }
      responses:
        '200':
          description: Login successful
        '401':
          description: Invalid credentials

  /api/auth/register:
    post:
      summary: Register a new account
      tags: [Auth]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email, password]
              properties:
                email: { type: string, format: email }
                password: { type: string }
      responses:
        '201':
          description: Account created

  /api/auth/logout:
    post:
      summary: Log out
      tags: [Auth]
      responses:
        '200':
          description: Logged out

  /api/auth/google:
    get:
      summary: Initiate Google OAuth flow
      tags: [Auth]
      responses:
        '302':
          description: Redirect to Google

  /api/auth/github:
    get:
      summary: Initiate GitHub OAuth flow
      tags: [Auth]
      responses:
        '302':
          description: Redirect to GitHub

  /api/auth/verify-email:
    get:
      summary: Verify email address
      tags: [Auth]
      responses:
        '200':
          description: Email verified

  /api/auth/send-password-reset:
    post:
      summary: Send a password reset email
      tags: [Auth]
      responses:
        '200':
          description: Reset email sent

  /api/account/set-password:
    post:
      summary: Set password for OAuth users
      description: Allows users who signed up via OAuth to set an email/password credential.
      tags: [Account]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [newPassword]
              properties:
                newPassword:
                  type: string
                  minLength: 8
                  maxLength: 128
      responses:
        '200':
          description: Password set successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
        '400':
          description: Validation error or password already set
        '401':
          description: Unauthorized

  /api/account/change-password:
    post:
      summary: Change existing password
      tags: [Account]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [currentPassword, newPassword]
              properties:
                currentPassword: { type: string }
                newPassword: { type: string, minLength: 8, maxLength: 128 }
      responses:
        '200':
          description: Password changed
        '400':
          description: Validation error
        '401':
          description: Unauthorized

  /api/account/update:
    post:
      summary: Update account profile
      tags: [Account]
      responses:
        '200':
          description: Profile updated

  /api/account/delete:
    post:
      summary: Delete account
      tags: [Account]
      responses:
        '200':
          description: Account deleted

  /api/account/export:
    get:
      summary: Export account data
      tags: [Account]
      responses:
        '200':
          description: Account data export

  /api/sites:
    get:
      summary: List sites
      tags: [Sites]
      responses:
        '200':
          description: List of sites
    post:
      summary: Create a new site
      tags: [Sites]
      responses:
        '201':
          description: Site created

  /api/sites/{id}:
    get:
      summary: Get site details
      tags: [Sites]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Site details
    put:
      summary: Update a site
      tags: [Sites]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Site updated
    delete:
      summary: Delete a site
      tags: [Sites]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Site deleted

  /api/sites/{id}/goals:
    get:
      summary: List goals for a site
      tags: [Sites]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Goal list

  /api/sites/{id}/team/members:
    get:
      summary: List team members for a site
      tags: [Sites]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Team member list

  /api/sites/{id}/team/invitations:
    get:
      summary: List team invitations
      tags: [Sites]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Invitation list
    post:
      summary: Create a team invitation
      tags: [Sites]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        '201':
          description: Invitation created

  /api/apikeys:
    get:
      summary: List API keys
      tags: [API Keys]
      responses:
        '200':
          description: List of API keys
    post:
      summary: Create an API key
      tags: [API Keys]
      responses:
        '201':
          description: API key created

  /api/apikeys/{id}:
    delete:
      summary: Delete an API key
      tags: [API Keys]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: API key deleted

  /api/notifications:
    get:
      summary: List notifications
      tags: [Notifications]
      responses:
        '200':
          description: Notification list

  /api/notifications/{id}/read:
    post:
      summary: Mark a notification as read
      tags: [Notifications]
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Notification marked as read

  /api/health:
    get:
      summary: Health check
      tags: [System]
      responses:
        '200':
          description: Service is healthy

  /api/admin/stats:
    get:
      summary: Get admin statistics
      tags: [Admin]
      description: Restricted to admin users.
      responses:
        '200':
          description: Admin statistics
        '403':
          description: Forbidden

  /api/billing/create-checkout-session:
    post:
      summary: Create a Stripe checkout session
      tags: [Billing]
      responses:
        '200':
          description: Checkout session URL

  /api/billing/cancel:
    post:
      summary: Cancel subscription
      tags: [Billing]
      responses:
        '200':
          description: Subscription cancelled

  /api/billing/resume:
    post:
      summary: Resume subscription
      tags: [Billing]
      responses:
        '200':
          description: Subscription resumed
