Ctrl K
ComunidadGuías…

docs/swagger.yaml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
basePath: /api
definitions:
  github_com_johnzastrow_actalog_internal_domain.AuditLog:
    properties:
      created_at:
        type: string
      details:
        description: JSON string
        type: string
      event_type:
        type: string
      id:
        type: integer
      ip_address:
        type: string
      target_user_email:
        description: Email of affected user
        type: string
      target_user_id:
        description: User affected by the action
        type: integer
      user_agent:
        type: string
      user_email:
        description: These fields are populated via JOIN queries and are not in the audit_logs table
        type: string
      user_id:
        description: User who performed the action (NULL for system)
        type: integer
    type: object
  github_com_johnzastrow_actalog_internal_domain.BackupMetadata:
    properties:
      created_at:
        type: string
      created_by_email:
        type: string
      database_driver:
        type: string
      database_name:
        type: string
      file_size:
        description: Size in bytes
        type: integer
      filename:
        type: string
      total_movements:
        type: integer
      total_users:
        type: integer
      total_wods:
        type: integer
      total_workouts:
        type: integer
      version:
        type: string
    type: object
  github_com_johnzastrow_actalog_internal_domain.DataChangeLog:
    properties:
      after_values:
        description: JSON of record after change (NULL for deletes)
        type: string
      before_values:
        description: JSON of record before change
        type: string
      created_at:
        type: string
      entity_id:
        description: ID of the record that was changed
        type: integer
      entity_name:
        description: Human-readable name (e.g., WOD name, movement name)
        type: string
      entity_type:
        description: wod, movement, workout, user_workout, etc.
        type: string
      id:
        type: integer
      ip_address:
        type: string
      operation:
        description: update, delete
        type: string
      user_agent:
        type: string
      user_email:
        description: Email for display (denormalized)
        type: string
      user_id:
        description: User who made the change
        type: integer
    type: object
  github_com_johnzastrow_actalog_internal_domain.Movement:
    properties:
      created_at:
        type: string
      created_by:
        description: User ID if custom
        type: integer
      description:
        type: string
      id:
        type: integer
      is_standard:
        description: True for predefined movements
        type: boolean
      name:
        type: string
      type:
        $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.MovementType'
      updated_at:
        type: string
    type: object
  github_com_johnzastrow_actalog_internal_domain.MovementType:
    enum:
    - weightlifting
    - bodyweight
    - cardio
    - gymnastics
    type: string
    x-enum-varnames:
    - MovementTypeWeightlifting
    - MovementTypeBodyweight
    - MovementTypeCardio
    - MovementTypeGymnastics
  github_com_johnzastrow_actalog_internal_domain.UserSettings:
    properties:
      admin_user_event_notifications:
        description: 'Admins: receive user event emails'
        type: boolean
      created_at:
        type: string
      data_export_format:
        description: JSON, CSV
        type: string
      distance_unit:
        description: miles, km
        type: string
      font_family:
        description: system, inter, roboto, lato, firasans, lexend, opendyslexic, atkinson, sourceserif, jetbrainsmono
        type: string
      id:
        type: integer
      notification_preferences:
        description: JSON format
        type: string
      theme:
        description: light, dark
        type: string
      timezone:
        description: IANA timezone identifier
        type: string
      updated_at:
        type: string
      user_id:
        type: integer
      weight_unit:
        description: lbs, kg
        type: string
    type: object
  github_com_johnzastrow_actalog_internal_domain.UserWorkoutMovement:
    properties:
      created_at:
        type: string
      distance:
        description: in meters or miles
        type: number
      id:
        type: integer
      is_pr:
        description: Personal record flag
        type: boolean
      movement:
        allOf:
        - $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.Movement'
        description: Related data (loaded via joins)
      movement_id:
        description: References movements table
        type: integer
      movement_name:
        description: Flattened for convenience
        type: string
      movement_type:
        description: Flattened for convenience
        type: string
      notes:
        type: string
      order_index:
        description: Order in the workout
        type: integer
      reps:
        type: integer
      sets:
        type: integer
      time_seconds:
        description: in seconds
        type: integer
      updated_at:
        type: string
      user_workout_id:
        description: References user_workouts (logged workout instance)
        type: integer
      weight:
        description: in lbs or kg
        type: number
      workout_date:
        description: From user_workouts.workout_date
        type: string
    type: object
  github_com_johnzastrow_actalog_internal_domain.UserWorkoutWOD:
    properties:
      created_at:
        type: string
      id:
        type: integer
      is_pr:
        description: Personal record flag
        type: boolean
      notes:
        type: string
      order_index:
        description: Order in the workout
        type: integer
      reps:
        description: Remaining reps in AMRAP
        type: integer
      rounds:
        description: For AMRAP WODs
        type: integer
      score_type:
        description: Time (HH:MM:SS), Rounds+Reps, Max Weight
        type: string
      score_value:
        description: Formatted score (e.g., "12:34", "10+15", "225.5")
        type: string
      time_seconds:
        description: For Time-based WODs
        type: integer
      updated_at:
        type: string
      user_workout_id:
        description: References user_workouts (logged workout instance)
        type: integer
      weight:
        description: For Max Weight WODs
        type: number
      wod:
        allOf:
        - $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.WOD'
        description: Related data (loaded via joins)
      wod_id:
        description: References wods table
        type: integer
      wod_name:
        description: Flattened for convenience
        type: string
      wod_score_type:
        description: WOD's defined score_type from wods table
        type: string
      wod_type:
        description: Flattened for convenience (Benchmark, Hero, Girl, etc.)
        type: string
      workout_date:
        description: From user_workouts.workout_date
        type: string
    type: object
  github_com_johnzastrow_actalog_internal_domain.WOD:
    properties:
      created_at:
        type: string
      created_by:
        description: User ID if custom WOD (NULL for standard)
        type: integer
      description:
        description: Full WOD description/instructions
        type: string
      id:
        type: integer
      is_standard:
        description: TRUE for pre-seeded WODs, FALSE for user-created
        type: boolean
      name:
        type: string
      notes:
        description: Additional notes
        type: string
      regime:
        description: EMOM, AMRAP, Fastest Time, Slowest Round, Get Stronger, Skills
        type: string
      score_type:
        description: Time (HH:MM:SS), Rounds+Reps, Max Weight
        type: string
      source:
        description: CrossFit, Other Coach, Self-recorded
        type: string
      type:
        description: Benchmark, Hero, Girl, Notables, Games, Endurance, Self-created
        type: string
      updated_at:
        type: string
      url:
        description: Optional video or reference URL
        type: string
    type: object
  github_com_johnzastrow_actalog_internal_domain.Workout:
    properties:
      created_at:
        type: string
      created_by:
        description: User who created (NULL for standard templates)
        type: integer
      id:
        type: integer
      movements:
        description: Related data (not stored directly in workout table, loaded via joins)
        items:
          $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.WorkoutMovement'
        type: array
      name:
        description: Template name (e.g., "Monday Strength", "Hero WOD")
        type: string
      notes:
        description: General template notes/description
        type: string
      updated_at:
        type: string
      wods:
        description: WODs in this template
        items:
          $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.WorkoutWODWithDetails'
        type: array
    type: object
  github_com_johnzastrow_actalog_internal_domain.WorkoutMovement:
    properties:
      created_at:
        type: string
      distance:
        description: in meters or miles
        type: number
      id:
        type: integer
      is_pr:
        description: Personal record flag
        type: boolean
      is_rx:
        description: Prescribed weight/standard
        type: boolean
      movement:
        allOf:
        - $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.Movement'
        description: Related data
      movement_id:
        description: References movements table
        type: integer
      notes:
        type: string
      order_index:
        description: Order in the workout
        type: integer
      reps:
        type: integer
      sets:
        type: integer
      time:
        description: in seconds
        type: integer
      updated_at:
        type: string
      weight:
        description: in lbs or kg
        type: number
      workout_id:
        description: References workout template
        type: integer
    type: object
  github_com_johnzastrow_actalog_internal_domain.WorkoutWODWithDetails:
    properties:
      created_at:
        type: string
      division:
        description: rx, scaled, beginner
        type: string
      id:
        type: integer
      is_pr:
        description: Personal record flag
        type: boolean
      order_index:
        description: Order in workout sequence
        type: integer
      score_value:
        description: Actual score when logged (time, rounds+reps, weight)
        type: string
      updated_at:
        type: string
      wod_description:
        type: string
      wod_id:
        description: References WOD
        type: integer
      wod_name:
        type: string
      wod_regime:
        type: string
      wod_score_type:
        type: string
      wod_type:
        type: string
      workout_id:
        description: References workout template
        type: integer
    type: object
  internal_handler.AuthResponse:
    description: Authentication response containing JWT token and user info
    properties:
      refresh_token:
        example: 550e8400-e29b-41d4-a716-446655440000
        type: string
      token:
        example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
        type: string
      user: {}
    type: object
  internal_handler.CancelSubscriptionRequest:
    description: Request to cancel a subscription
    properties:
      reason:
        example: User requested cancellation
        type: string
    type: object
  internal_handler.ChangePasswordRequest:
    description: Password change request
    properties:
      new_password:
        example: newSecurePassword456
        type: string
      old_password:
        example: currentPassword123
        type: string
    type: object
  internal_handler.CopyToStandardRequest:
    properties:
      new_name:
        type: string
    type: object
  internal_handler.CreateAnnouncementRequest:
    description: Admin announcement request
    properties:
      message:
        example: Scheduled maintenance tonight
        type: string
      organization_id:
        type: integer
      target_ids:
        description: org IDs or user IDs
        items:
          type: integer
        type: array
      target_type:
        description: '"all", "organization", or "users"'
        example: all
        type: string
      title:
        example: System Update
        type: string
    type: object
  internal_handler.CreateMovementRequest:
    description: Request to create a new custom movement
    properties:
      description:
        example: A hip hinge movement using a kettlebell
        type: string
      name:
        example: Kettlebell Swing
        type: string
      type:
        example: strength
        type: string
    type: object
  internal_handler.CreateOrganizationSubscriptionRequest:
    description: Request to create an organization subscription (admin only)
    properties:
      is_permanent_free:
        example: false
        type: boolean
      notes:
        example: Enterprise plan
        type: string
      organization_id:
        example: 1
        type: integer
      subscription_type:
        example: annual
        type: string
    type: object
  internal_handler.CreateUserSubscriptionRequest:
    description: Request to create a user subscription (admin only)
    properties:
      is_permanent_free:
        example: false
        type: boolean
      notes:
        example: Customer referral discount
        type: string
      subscription_type:
        description: '"free", "monthly", "annual"'
        example: monthly
        type: string
      user_id:
        example: 1
        type: integer
    type: object
  internal_handler.CreateWODRequest:
    description: Request to create a new WOD
    properties:
      description:
        example: 15 min AMRAP of 10 KB swings, 15 box jumps
        type: string
      name:
        example: My Custom WOD
        type: string
      notes:
        type: string
      regime:
        example: 15 min
        type: string
      score_type:
        example: rounds+reps
        type: string
      source:
        example: custom
        type: string
      type:
        example: AMRAP
        type: string
      url:
        type: string
    type: object
  internal_handler.ErrorResponse:
    description: Error response returned when a request fails
    properties:
      error:
        example: additional error details
        type: string
      message:
        example: Invalid credentials
        type: string
    type: object
  internal_handler.ForgotPasswordRequest:
    description: Request to initiate password reset
    properties:
      email:
        example: john@example.com
        type: string
    type: object
  internal_handler.LogWorkoutRequest:
    description: Request to log a workout (either from template or ad-hoc)
    properties:
      movements:
        description: Performance data
        items:
          $ref: '#/definitions/internal_handler.MovementPerformance'
        type: array
      notes:
        example: Felt strong today
        type: string
      total_time:
        description: Duration in seconds
        example: 1200
        type: integer
      wods:
        items:
          $ref: '#/definitions/internal_handler.WODPerformance'
        type: array
      workout_date:
        description: YYYY-MM-DD format
        example: '2024-01-15'
        type: string
      workout_id:
        description: Template ID (optional for ad-hoc workouts)
        example: 1
        type: integer
      workout_name:
        description: Name for ad-hoc workouts (required if workout_id is null)
        example: Fran
        type: string
      workout_type:
        example: AMRAP
        type: string
    type: object
  internal_handler.LoginRequest:
    description: User login request body
    properties:
      email:
        example: john@example.com
        type: string
      password:
        example: securePassword123
        type: string
      remember_me:
        example: true
        type: boolean
    type: object
  internal_handler.MarkUserSubscriptionAsPaidRequest:
    description: Request to mark a subscription as paid
    properties:
      duration_days:
        description: 'Optional: custom duration in days'
        example: 30
        type: integer
      payment_date:
        description: 'Optional: defaults to now'
        example: '2024-01-15'
        type: string
    type: object
  internal_handler.MessageResponse:
    description: Generic message response
    properties:
      message:
        example: Operation completed successfully
        type: string
    type: object
  internal_handler.MovementListResponse:
    description: List of movements
    properties:
      movements:
        items:
          $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.Movement'
        type: array
    type: object
  internal_handler.MovementPerformance:
    description: Performance data recorded for a movement in a workout
    properties:
      distance:
        example: 1000
        type: number
      movement_id:
        example: 1
        type: integer
      notes:
        example: Used belt
        type: string
      order_index:
        example: 0
        type: integer
      reps:
        example: 10
        type: integer
      sets:
        example: 5
        type: integer
      time:
        description: in seconds
        example: 300
        type: integer
      weight:
        example: 135.5
        type: number
    type: object
  internal_handler.ProfileResponse:
    description: User profile data
    properties:
      user: {}
    type: object
  internal_handler.RefreshTokenRequest:
    description: Request to refresh access token
    properties:
      refresh_token:
        example: 550e8400-e29b-41d4-a716-446655440000
        type: string
    type: object
  internal_handler.RegisterRequest:
    description: User registration request body
    properties:
      email:
        example: john@example.com
        type: string
      name:
        example: John Doe
        type: string
      password:
        example: securePassword123
        type: string
    type: object
  internal_handler.ResendVerificationRequest:
    description: Request to resend verification email
    properties:
      email:
        example: john@example.com
        type: string
    type: object
  internal_handler.ResetPasswordRequest:
    description: Request to complete password reset with token
    properties:
      new_password:
        example: newSecurePassword123
        type: string
      token:
        example: abc123def456
        type: string
    type: object
  internal_handler.RevokeTokenRequest:
    description: Request to revoke a refresh token (logout)
    properties:
      refresh_token:
        example: 550e8400-e29b-41d4-a716-446655440000
        type: string
    type: object
  internal_handler.SetUserSubscriptionPermanentRequest:
    description: Request to set subscription permanent status
    properties:
      is_permanent:
        example: true
        type: boolean
    type: object
  internal_handler.UpdateLoggedWorkoutRequest:
    description: Request to update an existing logged workout
    properties:
      movements:
        items:
          $ref: '#/definitions/internal_handler.MovementPerformance'
        type: array
      notes:
        example: Updated notes
        type: string
      total_time:
        example: 900
        type: integer
      wods:
        items:
          $ref: '#/definitions/internal_handler.WODPerformance'
        type: array
      workout_name:
        description: For ad-hoc workouts
        example: Custom WOD
        type: string
      workout_type:
        example: EMOM
        type: string
    type: object
  internal_handler.UpdateProfileRequest:
    description: User profile update request
    properties:
      birthday:
        description: 'Format: "YYYY-MM-DD" or empty'
        example: '1990-05-15'
        type: string
      email:
        example: john@example.com
        type: string
      name:
        example: John Doe
        type: string
    type: object
  internal_handler.UpdateWODRecordRequest:
    properties:
      notes:
        type: string
      reps:
        type: integer
      rounds:
        type: integer
      time_seconds:
        type: integer
      weight:
        type: number
    type: object
  internal_handler.UpdateWODRequest:
    description: Request to update an existing WOD
    properties:
      description:
        example: 21-15-9 thrusters and pull-ups
        type: string
      name:
        example: Updated WOD Name
        type: string
      notes:
        type: string
      regime:
        example: 21-15-9
        type: string
      score_type:
        example: time
        type: string
      source:
        example: custom
        type: string
      type:
        example: For Time
        type: string
      url:
        type: string
    type: object
  internal_handler.UserWorkoutResponse:
    description: Complete logged workout with performance data
    properties:
      created_at:
        example: '2024-01-15T10:30:00Z'
        type: string
      id:
        example: 1
        type: integer
      movements:
        description: Template movements
        items:
          $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.WorkoutMovement'
        type: array
      notes:
        example: Felt great
        type: string
      performance_movements:
        description: Actual performance
        items:
          $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.UserWorkoutMovement'
        type: array
      performance_wods:
        description: Actual performance
        items:
          $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.UserWorkoutWOD'
        type: array
      total_time:
        example: 1200
        type: integer
      updated_at:
        example: '2024-01-15T10:30:00Z'
        type: string
      user_id:
        example: 1
        type: integer
      wods:
        description: Template WODs
        items:
          $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.WorkoutWODWithDetails'
        type: array
      workout_date:
        example: '2024-01-15'
        type: string
      workout_id:
        description: Nullable for ad-hoc workouts
        example: 1
        type: integer
      workout_name:
        example: Fran
        type: string
      workout_notes:
        example: Template notes
        type: string
      workout_type:
        example: For Time
        type: string
    type: object
  internal_handler.WODListResponse:
    description: List of WODs
    properties:
      wods:
        items:
          $ref: '#/definitions/internal_handler.WODResponse'
        type: array
    type: object
  internal_handler.WODPerformance:
    description: Performance data recorded for a WOD in a workout
    properties:
      notes:
        example: PR attempt
        type: string
      order_index:
        example: 0
        type: integer
      reps:
        description: Remaining reps in AMRAP
        example: 12
        type: integer
      rounds:
        description: For AMRAP
        example: 5
        type: integer
      score_type:
        description: Time, Rounds+Reps, Max Weight
        example: Time
        type: string
      score_value:
        description: Formatted score
        example: '12:30'
        type: string
      time_seconds:
        description: For time-based WODs
        example: 750
        type: integer
      weight:
        description: For max weight WODs
        example: 225
        type: number
      wod_id:
        example: 1
        type: integer
    type: object
  internal_handler.WODResponse:
    description: WOD details response
    properties:
      created_at:
        example: '2024-01-15T10:30:00Z'
        type: string
      created_by:
        type: integer
      description:
        example: 21-15-9 thrusters and pull-ups
        type: string
      id:
        example: 1
        type: integer
      is_standard:
        example: true
        type: boolean
      name:
        example: Fran
        type: string
      notes:
        type: string
      regime:
        example: 21-15-9
        type: string
      score_type:
        example: time
        type: string
      source:
        example: CrossFit
        type: string
      type:
        example: For Time
        type: string
      updated_at:
        example: '2024-01-15T10:30:00Z'
        type: string
      url:
        type: string
    type: object
host: localhost:8080
info:
  contact:
    email: support@actalog.com
    name: ActaLog Support
    url: https://github.com/johnzastrow/actalog/issues
  description: ActaLog is a mobile-first CrossFit workout tracker API. It provides endpoints for user authentication, workout
    logging, movement tracking, personal records, and administrative functions.
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
  termsOfService: https://actalog.com/terms/
  title: ActaLog API
  version: 1.1.0-beta
paths:
  /admin/audit-logs/cleanup:
    post:
      consumes:
      - application/json
      description: Delete audit logs older than specified retention period
      parameters:
      - description: Retention days (must be positive)
        in: body
        name: request
        required: true
        schema:
          type: object
      produces:
      - application/json
      responses:
        '200':
          description: Deleted count and success message
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid request
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Forbidden
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Cleanup old audit logs (Admin)
      tags:
      - audit
  /admin/backups:
    get:
      consumes:
      - application/json
      description: Get a list of all available backup files
      produces:
      - application/json
      responses:
        '200':
          description: List of backups with count
          schema:
            additionalProperties: true
            type: object
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List backups (Admin)
      tags:
      - backups
    post:
      consumes:
      - application/json
      description: Create a new database backup
      produces:
      - application/json
      responses:
        '201':
          description: Backup created with filename and metadata
          schema:
            additionalProperties: true
            type: object
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Create backup (Admin)
      tags:
      - backups
  /admin/backups/upload:
    post:
      consumes:
      - multipart/form-data
      description: Upload a backup ZIP file from another system
      parameters:
      - description: Backup ZIP file
        in: formData
        name: file
        required: true
        type: file
      produces:
      - application/json
      responses:
        '201':
          description: Upload success with filename and metadata
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid file or format
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Upload backup (Admin)
      tags:
      - backups
  /admin/backups/{filename}:
    delete:
      consumes:
      - application/json
      description: Delete a backup file
      parameters:
      - description: Backup filename
        in: path
        name: filename
        required: true
        type: string
      produces:
      - application/json
      responses:
        '200':
          description: Success message with filename
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid filename
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Delete backup (Admin)
      tags:
      - backups
    get:
      consumes:
      - application/json
      description: Download a backup file
      parameters:
      - description: Backup filename
        in: path
        name: filename
        required: true
        type: string
      produces:
      - application/zip
      responses:
        '200':
          description: Backup ZIP file
          schema:
            type: file
        '400':
          description: Invalid filename
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Backup not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Download backup (Admin)
      tags:
      - backups
  /admin/backups/{filename}/metadata:
    get:
      consumes:
      - application/json
      description: Get metadata information for a specific backup file
      parameters:
      - description: Backup filename
        in: path
        name: filename
        required: true
        type: string
      produces:
      - application/json
      responses:
        '200':
          description: Backup metadata
          schema:
            $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.BackupMetadata'
        '400':
          description: Invalid filename
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Backup not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get backup metadata (Admin)
      tags:
      - backups
  /admin/backups/{filename}/restore:
    post:
      consumes:
      - application/json
      description: Restore database from a backup file (requires confirmation)
      parameters:
      - description: Backup filename
        in: path
        name: filename
        required: true
        type: string
      - description: Restore options (confirm, mode)
        in: body
        name: request
        required: true
        schema:
          type: object
      produces:
      - application/json
      responses:
        '200':
          description: Restore result
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid request or filename
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Restore backup (Admin)
      tags:
      - backups
  /admin/benchmark/data:
    delete:
      consumes:
      - application/json
      description: Delete all benchmark data from the database
      produces:
      - application/json
      responses:
        '200':
          description: Cleanup result
          schema:
            additionalProperties:
              type: string
            type: object
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Forbidden
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Cleanup all benchmark data (Admin)
      tags:
      - benchmark
  /admin/data-change-logs/cleanup:
    post:
      consumes:
      - application/json
      description: Delete data change logs older than specified retention period
      parameters:
      - description: Retention days (must be positive)
        in: body
        name: request
        required: true
        schema:
          type: object
      produces:
      - application/json
      responses:
        '200':
          description: Deleted count and success message
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid request
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Forbidden
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Cleanup old data change logs (Admin)
      tags:
      - admin
  /admin/data-quality/duplicates:
    get:
      description: Scan all entity types for duplicate records
      produces:
      - application/json
      responses:
        '200':
          description: Duplicate scan results for all entities
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Scan for duplicates
      tags:
      - admin-data-quality
  /admin/data-quality/duplicates/merge/confirm:
    post:
      consumes:
      - application/json
      description: Execute a duplicate merge operation. Updates FK references and deletes duplicate records.
      produces:
      - application/json
      responses:
        '200':
          description: Merge results
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Confirm duplicate merge
      tags:
      - admin-data-quality
  /admin/data-quality/duplicates/merge/preview:
    post:
      consumes:
      - application/json
      description: Preview a duplicate merge operation showing FK reference impact
      produces:
      - application/json
      responses:
        '200':
          description: Merge preview with FK impact
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Preview duplicate merge
      tags:
      - admin-data-quality
  /admin/data-quality/duplicates/summary:
    get:
      description: Get a quick summary of duplicate counts by entity type
      produces:
      - application/json
      responses:
        '200':
          description: Summary of duplicates per entity type
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get duplicate summary
      tags:
      - admin-data-quality
  /admin/data-quality/duplicates/{entity}:
    get:
      description: Scan a specific entity type for duplicates (movements, wods, user_workouts, users, workouts)
      parameters:
      - description: 'Entity type: movements, wods, user_workouts, users, workouts'
        in: path
        name: entity
        required: true
        type: string
      produces:
      - application/json
      responses:
        '200':
          description: Duplicate groups for entity
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Scan duplicates by entity
      tags:
      - admin-data-quality
  /admin/data-quality/full-scan:
    get:
      description: Run a comprehensive data quality scan including duplicates and data issues
      produces:
      - application/json
      responses:
        '200':
          description: Complete scan results
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Full data quality scan
      tags:
      - admin-data-quality
  /admin/data-quality/issues:
    get:
      description: 'Scan for data quality issues: orphaned FKs, empty required fields, future dates, invalid emails'
      produces:
      - application/json
      responses:
        '200':
          description: List of data quality issues
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Scan data quality issues
      tags:
      - admin-data-quality
  /admin/email-logs/:
    get:
      description: List email delivery logs
      produces:
      - application/json
      responses:
        '200':
          description: List of email logs
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: List email logs
      tags:
      - admin-email
  /admin/email-logs/cleanup:
    post:
      description: Delete old email logs based on retention period
      produces:
      - application/json
      responses:
        '200':
          description: Cleanup results
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Cleanup email logs
      tags:
      - admin-email
  /admin/email-logs/failures:
    get:
      description: Get recent email delivery failures
      produces:
      - application/json
      responses:
        '200':
          description: List of failed emails
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get recent email failures
      tags:
      - admin-email
  /admin/email-logs/stats:
    get:
      description: Get email delivery statistics (success/failure rates)
      produces:
      - application/json
      responses:
        '200':
          description: Email statistics
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get email statistics
      tags:
      - admin-email
  /admin/email-logs/{id}:
    get:
      description: Get details of a specific email log entry
      parameters:
      - description: Email log ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Email log details
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get email log details
      tags:
      - admin-email
  /admin/email/config:
    get:
      description: Get current email/SMTP configuration
      produces:
      - application/json
      responses:
        '200':
          description: Email configuration details
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get email configuration
      tags:
      - admin-email
  /admin/email/test:
    post:
      consumes:
      - application/json
      description: Send a test email to verify SMTP configuration
      produces:
      - application/json
      responses:
        '200':
          description: Test email sent
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Send test email
      tags:
      - admin-email
  /admin/gyms/{gym_id}/coaches:
    get:
      description: List coaches assigned to a gym
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of coaches
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: List gym coaches
      tags:
      - admin-scheduling
    post:
      consumes:
      - application/json
      description: Assign a coach to a gym
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '201':
          description: Coach assigned
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Assign coach to gym
      tags:
      - admin-scheduling
  /admin/gyms/{gym_id}/coaches/{id}:
    delete:
      description: Unassign a coach from a gym
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      - description: Coach assignment ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Coach unassigned
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Unassign coach from gym
      tags:
      - admin-scheduling
  /admin/gyms/{gym_id}/documents:
    post:
      consumes:
      - application/json
      description: Create a document type for a gym
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '201':
          description: Document created
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Create document
      tags:
      - admin-scheduling
  /admin/gyms/{gym_id}/documents/{id}:
    delete:
      description: Delete a document type
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      - description: Document ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Document deleted
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Delete document
      tags:
      - admin-scheduling
    put:
      consumes:
      - application/json
      description: Update a document type
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      - description: Document ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Document updated
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Update document
      tags:
      - admin-scheduling
  /admin/gyms/{gym_id}/locations:
    post:
      consumes:
      - application/json
      description: Create a new gym location
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '201':
          description: Location created
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Create gym location
      tags:
      - admin-scheduling
  /admin/gyms/{gym_id}/locations/{id}:
    delete:
      description: Delete a gym location
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      - description: Location ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Location deleted
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Delete gym location
      tags:
      - admin-scheduling
    put:
      consumes:
      - application/json
      description: Update a gym location
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      - description: Location ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Location updated
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Update gym location
      tags:
      - admin-scheduling
  /admin/gyms/{gym_id}/packages:
    post:
      consumes:
      - application/json
      description: Create a class package for a gym
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '201':
          description: Package created
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Create class package
      tags:
      - admin-scheduling
  /admin/gyms/{gym_id}/packages/{id}:
    delete:
      description: Delete a class package
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      - description: Package ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Package deleted
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Delete class package
      tags:
      - admin-scheduling
    put:
      consumes:
      - application/json
      description: Update a class package
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      - description: Package ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Package updated
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Update class package
      tags:
      - admin-scheduling
  /admin/gyms/{gym_id}/sessions:
    post:
      consumes:
      - application/json
      description: Create a class session manually
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '201':
          description: Session created
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Create session
      tags:
      - admin-scheduling
  /admin/gyms/{gym_id}/sessions/batch-workout:
    put:
      consumes:
      - application/json
      description: Batch update workout assignment for multiple sessions
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Sessions updated
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Batch update session workout
      tags:
      - admin-scheduling
  /admin/gyms/{gym_id}/sessions/{id}:
    put:
      consumes:
      - application/json
      description: Update a class session
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      - description: Session ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Session updated
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Update session
      tags:
      - admin-scheduling
  /admin/gyms/{gym_id}/sessions/{id}/cancel:
    post:
      consumes:
      - application/json
      description: Cancel a class session with optional reason
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      - description: Session ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Session cancelled
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Cancel session
      tags:
      - admin-scheduling
  /admin/gyms/{gym_id}/templates:
    post:
      consumes:
      - application/json
      description: Create a new class template
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '201':
          description: Template created
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Create class template
      tags:
      - admin-scheduling
  /admin/gyms/{gym_id}/user-documents/{id}/complete:
    post:
      description: Mark a user document as completed
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      - description: User document ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Document marked as completed
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Mark document completed
      tags:
      - admin-scheduling
  /admin/gyms/{gym_id}/users/{user_id}/credits:
    post:
      consumes:
      - application/json
      description: Purchase or add credits for a user at a gym
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      - description: User ID
        in: path
        name: user_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '201':
          description: Credits added
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Add credits for user
      tags:
      - admin-scheduling
  /admin/gyms/{gym_id}/users/{user_id}/documents/init:
    post:
      description: Initialize document records for a user at a gym
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      - description: User ID
        in: path
        name: user_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Documents initialized
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Initialize user documents
      tags:
      - admin-scheduling
  /admin/metrics:
    get:
      description: 'Get admin dashboard metrics: user counts, workout stats, system health'
      produces:
      - application/json
      responses:
        '200':
          description: Admin dashboard metrics
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get admin metrics
      tags:
      - admin
  /admin/notifications/announce:
    post:
      consumes:
      - application/json
      description: Send an announcement to all users, organization members, or specific users
      parameters:
      - description: Announcement details
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.CreateAnnouncementRequest'
      produces:
      - application/json
      responses:
        '201':
          description: Announcement created
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid request
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Admin access required
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Create announcement (Admin)
      tags:
      - admin
  /admin/organizations:
    get:
      consumes:
      - application/json
      description: Get a paginated list of all organizations
      parameters:
      - description: Max results (default 50)
        in: query
        name: limit
        type: integer
      - description: Skip N results (default 0)
        in: query
        name: offset
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Organizations list with total count
          schema:
            additionalProperties: true
            type: object
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List organizations (Admin)
      tags:
      - organizations
    post:
      consumes:
      - application/json
      description: Create a new organization (admin only)
      parameters:
      - description: Organization name and description
        in: body
        name: request
        required: true
        schema:
          type: object
      produces:
      - application/json
      responses:
        '201':
          description: Created organization
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid request
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '409':
          description: Organization name exists
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Create organization (Admin)
      tags:
      - organizations
  /admin/organizations/{id}:
    delete:
      consumes:
      - application/json
      description: Delete an organization (must have no assigned users)
      parameters:
      - description: Organization ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Success message
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid organization ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Organization not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '409':
          description: Organization has assigned users
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Delete organization (Admin)
      tags:
      - organizations
    get:
      consumes:
      - application/json
      description: Get details of a specific organization
      parameters:
      - description: Organization ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Organization details
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid organization ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Organization not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get organization (Admin)
      tags:
      - organizations
    put:
      consumes:
      - application/json
      description: Update an existing organization's details
      parameters:
      - description: Organization ID
        in: path
        name: id
        required: true
        type: integer
      - description: Updated organization details
        in: body
        name: request
        required: true
        schema:
          type: object
      produces:
      - application/json
      responses:
        '200':
          description: Updated organization
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid request
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Organization not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '409':
          description: Organization name exists
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Update organization (Admin)
      tags:
      - organizations
  /admin/organizations/{id}/users:
    get:
      consumes:
      - application/json
      description: Get all users belonging to an organization
      parameters:
      - description: Organization ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of users
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid organization ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Organization not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get organization users (Admin)
      tags:
      - organizations
  /admin/scheduling/templates/{id}:
    delete:
      description: 'Delete a class template. Supports mode parameter: template_only, with_future_sessions, with_all_sessions'
      parameters:
      - description: Template ID
        in: path
        name: id
        required: true
        type: integer
      - description: 'Delete mode: template_only, with_future_sessions, with_all_sessions'
        in: query
        name: mode
        required: false
        type: string
      produces:
      - application/json
      responses:
        '200':
          description: Template deleted with cascade results
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Delete class template
      tags:
      - admin-scheduling
    get:
      description: Get a class template by ID
      parameters:
      - description: Template ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Template details
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get class template
      tags:
      - admin-scheduling
    put:
      consumes:
      - application/json
      description: Update a class template
      parameters:
      - description: Template ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Template updated
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Update class template
      tags:
      - admin-scheduling
  /admin/scheduling/templates/{id}/coaches:
    get:
      description: Get default coaches assigned to a template
      parameters:
      - description: Template ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of template coaches
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get template coaches
      tags:
      - admin-scheduling
    post:
      consumes:
      - application/json
      description: Add a default coach to a template
      parameters:
      - description: Template ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '201':
          description: Coach added
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Add template coach
      tags:
      - admin-scheduling
  /admin/scheduling/templates/{id}/coaches/{user_id}:
    delete:
      description: Remove a default coach from a template
      parameters:
      - description: Template ID
        in: path
        name: id
        required: true
        type: integer
      - description: Coach user ID
        in: path
        name: user_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Coach removed
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Remove template coach
      tags:
      - admin-scheduling
  /admin/scheduling/templates/{id}/preview-schedule:
    get:
      description: Preview the schedule that would be generated for a template
      parameters:
      - description: Template ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Preview of scheduled sessions
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Preview template schedule
      tags:
      - admin-scheduling
  /admin/scheduling/templates/{id}/slots/:
    get:
      description: List schedule slots for a template
      parameters:
      - description: Template ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of schedule slots
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: List schedule slots
      tags:
      - admin-scheduling
    post:
      consumes:
      - application/json
      description: Create a schedule slot for a template
      parameters:
      - description: Template ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '201':
          description: Slot created
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Create schedule slot
      tags:
      - admin-scheduling
  /admin/scheduling/templates/{id}/slots/{slot_id}:
    delete:
      description: Delete a schedule slot
      parameters:
      - description: Template ID
        in: path
        name: id
        required: true
        type: integer
      - description: Slot ID
        in: path
        name: slot_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Slot deleted
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Delete schedule slot
      tags:
      - admin-scheduling
    put:
      consumes:
      - application/json
      description: Update a schedule slot
      parameters:
      - description: Template ID
        in: path
        name: id
        required: true
        type: integer
      - description: Slot ID
        in: path
        name: slot_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Slot updated
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Update schedule slot
      tags:
      - admin-scheduling
  /admin/sessions/{session_id}/check-in/{reservation_id}:
    post:
      description: Check in a reservation (admin)
      parameters:
      - description: Session ID
        in: path
        name: session_id
        required: true
        type: integer
      - description: Reservation ID
        in: path
        name: reservation_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Checked in
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Check in reservation (admin)
      tags:
      - admin-scheduling
  /admin/sessions/{session_id}/coaches:
    get:
      description: Get coaches assigned to a session
      parameters:
      - description: Session ID
        in: path
        name: session_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of session coaches
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get session coaches
      tags:
      - admin-scheduling
    post:
      consumes:
      - application/json
      description: Add a coach to a session
      parameters:
      - description: Session ID
        in: path
        name: session_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '201':
          description: Coach added to session
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Add session coach
      tags:
      - admin-scheduling
  /admin/sessions/{session_id}/coaches/{user_id}:
    delete:
      description: Remove a coach from a session
      parameters:
      - description: Session ID
        in: path
        name: session_id
        required: true
        type: integer
      - description: Coach user ID
        in: path
        name: user_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Coach removed from session
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Remove session coach
      tags:
      - admin-scheduling
  /admin/sessions/{session_id}/complete:
    post:
      description: Mark a session as completed (admin)
      parameters:
      - description: Session ID
        in: path
        name: session_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Session completed
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Complete session (admin)
      tags:
      - admin-scheduling
  /admin/sessions/{session_id}/no-show/{reservation_id}:
    post:
      description: Mark a reservation as no-show (admin)
      parameters:
      - description: Session ID
        in: path
        name: session_id
        required: true
        type: integer
      - description: Reservation ID
        in: path
        name: reservation_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Marked as no-show
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Mark no-show (admin)
      tags:
      - admin-scheduling
  /admin/sessions/{session_id}/roster:
    get:
      description: Get the roster of reservations for a session (admin)
      parameters:
      - description: Session ID
        in: path
        name: session_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Session roster
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get session roster (admin)
      tags:
      - admin-scheduling
  /admin/subscriptions/organizations:
    get:
      consumes:
      - application/json
      description: Get a list of all organization subscriptions in the system
      produces:
      - application/json
      responses:
        '200':
          description: Subscriptions list
          schema:
            additionalProperties: true
            type: object
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List all organization subscriptions (Admin)
      tags:
      - admin
    post:
      consumes:
      - application/json
      description: Create a new subscription for an organization (admin only)
      parameters:
      - description: Subscription details
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.CreateOrganizationSubscriptionRequest'
      produces:
      - application/json
      responses:
        '201':
          description: Created subscription
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid request
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '409':
          description: Active subscription exists
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Create organization subscription (Admin)
      tags:
      - admin
  /admin/subscriptions/organizations/expired:
    get:
      consumes:
      - application/json
      description: Get a list of expired or overdue organization subscriptions
      produces:
      - application/json
      responses:
        '200':
          description: Expired subscriptions list
          schema:
            additionalProperties: true
            type: object
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List expired organization subscriptions (Admin)
      tags:
      - admin
  /admin/subscriptions/organizations/expiring:
    get:
      consumes:
      - application/json
      description: Get a list of organization subscriptions expiring within the specified number of days
      parameters:
      - description: 'Number of days to look ahead (default: 30)'
        in: query
        name: days
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Expiring subscriptions list
          schema:
            additionalProperties: true
            type: object
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List expiring organization subscriptions (Admin)
      tags:
      - admin
  /admin/subscriptions/organizations/{id}/cancel:
    post:
      consumes:
      - application/json
      description: Cancel an organization subscription with a reason
      parameters:
      - description: Subscription ID
        in: path
        name: id
        required: true
        type: integer
      - description: Cancellation reason
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.CancelSubscriptionRequest'
      produces:
      - application/json
      responses:
        '200':
          description: Success message
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid request or missing reason
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Subscription not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Cancel organization subscription (Admin)
      tags:
      - admin
  /admin/subscriptions/organizations/{id}/paid:
    put:
      consumes:
      - application/json
      description: Mark an organization subscription as paid and extend the subscription period
      parameters:
      - description: Subscription ID
        in: path
        name: id
        required: true
        type: integer
      - description: Payment details
        in: body
        name: request
        schema:
          $ref: '#/definitions/internal_handler.MarkUserSubscriptionAsPaidRequest'
      produces:
      - application/json
      responses:
        '200':
          description: Success message
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Cannot mark free subscription as paid
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Subscription not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Mark organization subscription as paid (Admin)
      tags:
      - admin
  /admin/subscriptions/organizations/{id}/permanent:
    put:
      consumes:
      - application/json
      description: Set whether an organization subscription is permanently free
      parameters:
      - description: Subscription ID
        in: path
        name: id
        required: true
        type: integer
      - description: Permanent status
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.SetUserSubscriptionPermanentRequest'
      produces:
      - application/json
      responses:
        '200':
          description: Success message
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid request
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Subscription not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Set organization subscription permanent status (Admin)
      tags:
      - admin
  /admin/subscriptions/organizations/{org_id}:
    get:
      consumes:
      - application/json
      description: Get all subscriptions for a specific organization (admin only)
      parameters:
      - description: Organization ID
        in: path
        name: org_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Subscriptions list
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid organization ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get organization subscriptions (Admin)
      tags:
      - admin
  /admin/subscriptions/users:
    get:
      consumes:
      - application/json
      description: Get a list of all user subscriptions in the system
      produces:
      - application/json
      responses:
        '200':
          description: Subscriptions list
          schema:
            additionalProperties: true
            type: object
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List all user subscriptions (Admin)
      tags:
      - admin
    post:
      consumes:
      - application/json
      description: Create a new subscription for a user (admin only)
      parameters:
      - description: Subscription details
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.CreateUserSubscriptionRequest'
      produces:
      - application/json
      responses:
        '201':
          description: Created subscription
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid request
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Cannot modify own subscription
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '409':
          description: Active subscription exists
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Create user subscription (Admin)
      tags:
      - admin
  /admin/subscriptions/users/expired:
    get:
      consumes:
      - application/json
      description: Get a list of expired or overdue user subscriptions
      produces:
      - application/json
      responses:
        '200':
          description: Expired subscriptions list
          schema:
            additionalProperties: true
            type: object
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List expired user subscriptions (Admin)
      tags:
      - admin
  /admin/subscriptions/users/expiring:
    get:
      consumes:
      - application/json
      description: Get a list of user subscriptions expiring within the specified number of days
      parameters:
      - description: 'Number of days to look ahead (default: 30)'
        in: query
        name: days
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Expiring subscriptions list
          schema:
            additionalProperties: true
            type: object
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List expiring user subscriptions (Admin)
      tags:
      - admin
  /admin/subscriptions/users/{id}/cancel:
    post:
      consumes:
      - application/json
      description: Cancel a user subscription with a reason
      parameters:
      - description: Subscription ID
        in: path
        name: id
        required: true
        type: integer
      - description: Cancellation reason
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.CancelSubscriptionRequest'
      produces:
      - application/json
      responses:
        '200':
          description: Success message
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid request or missing reason
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Cannot modify own subscription
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Subscription not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Cancel user subscription (Admin)
      tags:
      - admin
  /admin/subscriptions/users/{id}/paid:
    put:
      consumes:
      - application/json
      description: Mark a user subscription as paid and extend the subscription period
      parameters:
      - description: Subscription ID
        in: path
        name: id
        required: true
        type: integer
      - description: Payment details
        in: body
        name: request
        schema:
          $ref: '#/definitions/internal_handler.MarkUserSubscriptionAsPaidRequest'
      produces:
      - application/json
      responses:
        '200':
          description: Success message
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Cannot mark free subscription as paid
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Cannot modify own subscription
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Subscription not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Mark user subscription as paid (Admin)
      tags:
      - admin
  /admin/subscriptions/users/{id}/permanent:
    put:
      consumes:
      - application/json
      description: Set whether a user subscription is permanently free
      parameters:
      - description: Subscription ID
        in: path
        name: id
        required: true
        type: integer
      - description: Permanent status
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.SetUserSubscriptionPermanentRequest'
      produces:
      - application/json
      responses:
        '200':
          description: Success message
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid request
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Cannot modify own subscription
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Subscription not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Set user subscription permanent status (Admin)
      tags:
      - admin
  /admin/subscriptions/users/{user_id}:
    get:
      consumes:
      - application/json
      description: Get all subscriptions for a specific user (admin only)
      parameters:
      - description: User ID
        in: path
        name: user_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Subscriptions list
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid user ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get user subscriptions (Admin)
      tags:
      - admin
  /admin/user-created/movements:
    get:
      consumes:
      - application/json
      description: Get all user-created movements with creator information
      parameters:
      - description: Max results (default 100)
        in: query
        name: limit
        type: integer
      - description: Skip N results (default 0)
        in: query
        name: offset
        type: integer
      - description: Search query
        in: query
        name: search
        type: string
      - description: Filter by movement type
        in: query
        name: type
        type: string
      - description: Filter by creator email
        in: query
        name: creator
        type: string
      produces:
      - application/json
      responses:
        '200':
          description: List of user-created movements
          schema:
            additionalProperties: true
            type: object
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List user-created movements (Admin)
      tags:
      - admin
  /admin/user-created/movements/{id}/copy-to-standard:
    post:
      consumes:
      - application/json
      description: Create a standard movement from a user-created movement
      parameters:
      - description: Movement ID
        in: path
        name: id
        required: true
        type: integer
      - description: New name for standard movement
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.CopyToStandardRequest'
      produces:
      - application/json
      responses:
        '201':
          description: Created standard movement
          schema:
            $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.Movement'
        '400':
          description: Invalid request
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Movement not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '409':
          description: Name already exists
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Copy movement to standard (Admin)
      tags:
      - admin
  /admin/user-created/wods:
    get:
      consumes:
      - application/json
      description: Get all user-created WODs with creator information
      parameters:
      - description: Max results (default 100)
        in: query
        name: limit
        type: integer
      - description: Skip N results (default 0)
        in: query
        name: offset
        type: integer
      - description: Search query
        in: query
        name: search
        type: string
      - description: Filter by score type
        in: query
        name: score_type
        type: string
      - description: Filter by creator email
        in: query
        name: creator
        type: string
      produces:
      - application/json
      responses:
        '200':
          description: List of user-created WODs
          schema:
            additionalProperties: true
            type: object
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List user-created WODs (Admin)
      tags:
      - admin
  /admin/user-created/wods/{id}/copy-to-standard:
    post:
      consumes:
      - application/json
      description: Create a standard WOD from a user-created WOD
      parameters:
      - description: WOD ID
        in: path
        name: id
        required: true
        type: integer
      - description: New name for standard WOD
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.CopyToStandardRequest'
      produces:
      - application/json
      responses:
        '201':
          description: Created standard WOD
          schema:
            $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.WOD'
        '400':
          description: Invalid request
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: WOD not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '409':
          description: Name already exists
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Copy WOD to standard (Admin)
      tags:
      - admin
  /admin/user-created/workouts:
    get:
      consumes:
      - application/json
      description: Get all user-created workout templates with creator information
      parameters:
      - description: Max results (default 100)
        in: query
        name: limit
        type: integer
      - description: Skip N results (default 0)
        in: query
        name: offset
        type: integer
      - description: Search query
        in: query
        name: search
        type: string
      - description: Filter by creator email
        in: query
        name: creator
        type: string
      produces:
      - application/json
      responses:
        '200':
          description: List of user-created workouts
          schema:
            additionalProperties: true
            type: object
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List user-created workouts (Admin)
      tags:
      - admin
  /admin/user-created/workouts/{id}/copy-to-standard:
    post:
      consumes:
      - application/json
      description: Create a standard workout template from a user-created workout
      parameters:
      - description: Workout ID
        in: path
        name: id
        required: true
        type: integer
      - description: New name for standard workout
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.CopyToStandardRequest'
      produces:
      - application/json
      responses:
        '201':
          description: Created standard workout
          schema:
            $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.Workout'
        '400':
          description: Invalid request
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Workout not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '409':
          description: Name already exists
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Copy workout to standard (Admin)
      tags:
      - admin
  /admin/user-management/batch-password-reset:
    post:
      consumes:
      - application/json
      description: Send password reset emails to selected users
      produces:
      - application/json
      responses:
        '200':
          description: Reset emails sent
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Batch password reset
      tags:
      - admin-user-management
  /admin/user-management/export:
    get:
      description: Export all users to CSV format
      produces:
      - text/csv
      responses:
        '200':
          description: CSV file download
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Export users to CSV
      tags:
      - admin-user-management
  /admin/user-management/filter:
    get:
      description: List users with search and date filters
      parameters:
      - description: Search by name or email
        in: query
        name: search
        required: false
        type: string
      - description: Filter by creation date (ISO 8601)
        in: query
        name: created_after
        required: false
        type: string
      - description: Filter by creation date (ISO 8601)
        in: query
        name: created_before
        required: false
        type: string
      produces:
      - application/json
      responses:
        '200':
          description: Filtered user list
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Filter users
      tags:
      - admin-user-management
  /admin/user-management/import/confirm:
    post:
      consumes:
      - application/json
      description: Confirm and execute user import
      produces:
      - application/json
      responses:
        '200':
          description: Import results
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Confirm user import
      tags:
      - admin-user-management
  /admin/user-management/import/preview:
    post:
      consumes:
      - multipart/form-data
      description: Preview user import from CSV file
      produces:
      - application/json
      responses:
        '200':
          description: Import preview with validation results
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Preview user import
      tags:
      - admin-user-management
  /admin/users:
    get:
      consumes:
      - application/json
      description: Get a paginated list of all users
      parameters:
      - description: Max results (default 50)
        in: query
        name: limit
        type: integer
      - description: Skip N results (default 0)
        in: query
        name: offset
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Users list with total count
          schema:
            additionalProperties: true
            type: object
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List users (Admin)
      tags:
      - admin
  /admin/users/{id}:
    delete:
      consumes:
      - application/json
      description: Permanently delete a user and all their data
      parameters:
      - description: User ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Success message
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid user ID or cannot delete
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Delete user (Admin)
      tags:
      - admin
    get:
      consumes:
      - application/json
      description: Get detailed information about a specific user
      parameters:
      - description: User ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: User details
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid user ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: User not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get user details (Admin)
      tags:
      - admin
  /admin/users/{id}/disable:
    post:
      consumes:
      - application/json
      description: Disable a user account with optional reason
      parameters:
      - description: User ID
        in: path
        name: id
        required: true
        type: integer
      - description: Optional disable reason
        in: body
        name: request
        schema:
          type: object
      produces:
      - application/json
      responses:
        '200':
          description: Success message
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid user ID or cannot disable
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Disable user account (Admin)
      tags:
      - admin
  /admin/users/{id}/enable:
    post:
      consumes:
      - application/json
      description: Re-enable a previously disabled user account
      parameters:
      - description: User ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Success message
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid user ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Enable user account (Admin)
      tags:
      - admin
  /admin/users/{id}/organization:
    post:
      consumes:
      - application/json
      description: Assign a user to an organization
      parameters:
      - description: User ID
        in: path
        name: id
        required: true
        type: integer
      - description: Organization ID to assign
        in: body
        name: request
        required: true
        schema:
          type: object
      produces:
      - application/json
      responses:
        '200':
          description: Success message
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid request
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: User or organization not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Assign user to organization (Admin)
      tags:
      - organizations
  /admin/users/{id}/organization/{org_id}:
    delete:
      consumes:
      - application/json
      description: Remove a user from an organization
      parameters:
      - description: User ID
        in: path
        name: id
        required: true
        type: integer
      - description: Organization ID
        in: path
        name: org_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Success message
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: User or organization not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Remove user from organization (Admin)
      tags:
      - organizations
  /admin/users/{id}/organizations:
    get:
      consumes:
      - application/json
      description: Get all organizations a user belongs to
      parameters:
      - description: User ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of organizations
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid user ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: User not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get user organizations (Admin)
      tags:
      - organizations
  /admin/users/{id}/role:
    put:
      consumes:
      - application/json
      description: Change a user's role to 'user' or 'admin'
      parameters:
      - description: User ID
        in: path
        name: id
        required: true
        type: integer
      - description: New role (user or admin)
        in: body
        name: request
        required: true
        schema:
          type: object
      produces:
      - application/json
      responses:
        '200':
          description: Success message
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid user ID or role
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Change user role (Admin)
      tags:
      - admin
  /admin/users/{id}/toggle-email-verification:
    post:
      consumes:
      - application/json
      description: Manually set a user's email verification status
      parameters:
      - description: User ID
        in: path
        name: id
        required: true
        type: integer
      - description: Verified status (true/false)
        in: body
        name: request
        required: true
        schema:
          type: object
      produces:
      - application/json
      responses:
        '200':
          description: Success message
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid user ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Toggle email verification (Admin)
      tags:
      - admin
  /admin/users/{id}/unlock:
    post:
      consumes:
      - application/json
      description: Unlock a user account that was locked due to failed login attempts
      parameters:
      - description: User ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Success message
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid user ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Unlock user account (Admin)
      tags:
      - admin
  /admin/wod-mismatches:
    get:
      consumes:
      - application/json
      description: Find WOD records where data doesn't match the expected score_type
      produces:
      - application/json
      responses:
        '200':
          description: List of mismatched records
          schema:
            additionalProperties: true
            type: object
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Detect WOD score type mismatches (Admin)
      tags:
      - admin
  /admin/wod-mismatches/fix:
    post:
      consumes:
      - application/json
      description: Delete WOD records that don't match their expected score_type
      produces:
      - application/json
      responses:
        '200':
          description: Count of deleted records
          schema:
            additionalProperties: true
            type: object
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Fix WOD score type mismatches (Admin)
      tags:
      - admin
  /admin/wod-records/{id}:
    put:
      consumes:
      - application/json
      description: Update a specific WOD performance record
      parameters:
      - description: WOD Record ID
        in: path
        name: id
        required: true
        type: integer
      - description: Updated record data
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.UpdateWODRecordRequest'
      produces:
      - application/json
      responses:
        '200':
          description: Success message
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid request or score type mismatch
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Record not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Update WOD record (Admin)
      tags:
      - admin
  /audit-logs:
    get:
      consumes:
      - application/json
      description: Get a paginated list of audit logs with optional filters
      parameters:
      - description: Filter by user ID
        in: query
        name: user_id
        type: integer
      - description: Filter by target user ID
        in: query
        name: target_user_id
        type: integer
      - description: Filter by event type
        in: query
        name: event_type
        type: string
      - description: Filter by IP address
        in: query
        name: ip_address
        type: string
      - description: Filter by start date (RFC3339)
        in: query
        name: start_date
        type: string
      - description: Filter by end date (RFC3339)
        in: query
        name: end_date
        type: string
      - description: Max results (default 50)
        in: query
        name: limit
        type: integer
      - description: Skip N results (default 0)
        in: query
        name: offset
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Audit logs list with total count
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid parameters
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Forbidden
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List audit logs (Admin)
      tags:
      - audit
  /audit-logs/{id}:
    get:
      consumes:
      - application/json
      description: Retrieve a specific audit log entry by ID
      parameters:
      - description: Audit Log ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Audit log entry
          schema:
            $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.AuditLog'
        '400':
          description: Invalid ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Forbidden
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Audit log not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get audit log entry (Admin)
      tags:
      - audit
  /auth/forgot-password:
    post:
      consumes:
      - application/json
      description: Send a password reset email to the user. Always returns success for security.
      parameters:
      - description: Email address
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.ForgotPasswordRequest'
      produces:
      - application/json
      responses:
        '200':
          description: Reset email sent if address exists
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid request body
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Failed to process request
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      summary: Request password reset
      tags:
      - auth
  /auth/login:
    post:
      consumes:
      - application/json
      description: Authenticate user with email and password. Set remember_me to true for refresh token.
      parameters:
      - description: Login credentials
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.LoginRequest'
      produces:
      - application/json
      responses:
        '200':
          description: Successfully authenticated
          schema:
            $ref: '#/definitions/internal_handler.AuthResponse'
        '400':
          description: Invalid request body
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Invalid email or password
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      summary: User login
      tags:
      - auth
  /auth/refresh-token:
    post:
      consumes:
      - application/json
      description: Get a new access token using a valid refresh token
      parameters:
      - description: Refresh token
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.RefreshTokenRequest'
      produces:
      - application/json
      responses:
        '200':
          description: New access token
          schema:
            $ref: '#/definitions/internal_handler.AuthResponse'
        '400':
          description: Invalid request body
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Invalid or expired refresh token
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Failed to refresh token
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      summary: Refresh access token
      tags:
      - auth
  /auth/register:
    post:
      consumes:
      - application/json
      description: Create a new user account with name, email, and password
      parameters:
      - description: Registration details
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.RegisterRequest'
      produces:
      - application/json
      responses:
        '201':
          description: Successfully registered
          schema:
            $ref: '#/definitions/internal_handler.AuthResponse'
        '400':
          description: Invalid request or validation error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Registration is closed
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '409':
          description: Email already exists
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      summary: Register a new user
      tags:
      - auth
  /auth/resend-verification:
    post:
      consumes:
      - application/json
      description: Resend email verification link. Always returns success for security.
      parameters:
      - description: Email address
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.ResendVerificationRequest'
      produces:
      - application/json
      responses:
        '200':
          description: Verification email sent if applicable
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid request or already verified
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Failed to resend verification email
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      summary: Resend verification email
      tags:
      - auth
  /auth/reset-password:
    post:
      consumes:
      - application/json
      description: Complete password reset using token from email
      parameters:
      - description: Reset token and new password
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.ResetPasswordRequest'
      produces:
      - application/json
      responses:
        '200':
          description: Password reset successfully
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid token, expired token, or weak password
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Failed to reset password
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      summary: Reset password
      tags:
      - auth
  /auth/revoke-token:
    post:
      consumes:
      - application/json
      description: Invalidate a refresh token to logout from a specific session
      parameters:
      - description: Refresh token to revoke
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.RevokeTokenRequest'
      produces:
      - application/json
      responses:
        '200':
          description: Token revoked successfully
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid request body
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Refresh token not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Failed to revoke token
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      summary: Revoke refresh token
      tags:
      - auth
  /auth/verify-email:
    get:
      consumes:
      - application/json
      description: Verify user's email using token from verification email
      parameters:
      - description: Verification token from email
        in: query
        name: token
        required: true
        type: string
      produces:
      - application/json
      responses:
        '200':
          description: Email verified successfully
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid or expired token, or already verified
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Failed to verify email
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      summary: Verify email address
      tags:
      - auth
  /benchmark:
    post:
      consumes:
      - application/json
      description: Execute the full benchmark suite to test database, serialization, and business logic performance
      parameters:
      - description: 'Include concurrent operation tests (default: false)'
        in: query
        name: concurrent
        type: boolean
      - description: 'Skip cleanup after run if set to false (default: true)'
        in: query
        name: cleanup
        type: boolean
      - description: 'Number of records to generate for benchmark testing (default: 1000, max: 500000)'
        in: query
        name: records
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Benchmark results
          schema:
            additionalProperties: true
            type: object
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Run benchmark suite
      tags:
      - benchmark
  /benchmark/status:
    get:
      consumes:
      - application/json
      description: Quick status check for the benchmark system
      produces:
      - application/json
      responses:
        '200':
          description: Benchmark status
          schema:
            additionalProperties: true
            type: object
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get benchmark status
      tags:
      - benchmark
  /coaches/me/sessions:
    get:
      description: Get upcoming sessions for the authenticated coach. Admins see all sessions across all gyms; coaches see
        only their assigned sessions.
      parameters:
      - description: Max sessions to return (default 20)
        in: query
        name: limit
        required: false
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of upcoming sessions with count
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get coach's upcoming sessions
      tags:
      - coaches
  /coaches/sessions/{session_id}/check-in/{reservation_id}:
    post:
      description: Check in an athlete's reservation. Coach must be assigned to the session's organization.
      parameters:
      - description: Session ID
        in: path
        name: session_id
        required: true
        type: integer
      - description: Reservation ID
        in: path
        name: reservation_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Reservation checked in
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Check in reservation
      tags:
      - coaches
  /coaches/sessions/{session_id}/complete:
    post:
      description: Mark a session as completed. Coach must be assigned to the session's organization.
      parameters:
      - description: Session ID
        in: path
        name: session_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Session marked as completed
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Complete session
      tags:
      - coaches
  /coaches/sessions/{session_id}/no-show/{reservation_id}:
    post:
      description: Mark a reservation as no-show. Coach must be assigned to the session's organization.
      parameters:
      - description: Session ID
        in: path
        name: session_id
        required: true
        type: integer
      - description: Reservation ID
        in: path
        name: reservation_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Reservation marked as no-show
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Mark reservation as no-show
      tags:
      - coaches
  /coaches/sessions/{session_id}/roster:
    get:
      description: Get the roster of reservations for a session. Coach must be assigned to the session's organization.
      parameters:
      - description: Session ID
        in: path
        name: session_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Session roster with reservations
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get session roster
      tags:
      - coaches
  /data-change-logs:
    get:
      consumes:
      - application/json
      description: Get a paginated list of data change logs with optional filters
      parameters:
      - description: Filter by entity type
        in: query
        name: entity_type
        type: string
      - description: Filter by entity ID
        in: query
        name: entity_id
        type: integer
      - description: Filter by operation (create, update, delete)
        in: query
        name: operation
        type: string
      - description: Filter by user ID
        in: query
        name: user_id
        type: integer
      - description: Filter by user email
        in: query
        name: user_email
        type: string
      - description: Filter by start date (RFC3339 or YYYY-MM-DD)
        in: query
        name: start_date
        type: string
      - description: Filter by end date (RFC3339 or YYYY-MM-DD)
        in: query
        name: end_date
        type: string
      - description: Max results (default 50)
        in: query
        name: limit
        type: integer
      - description: Skip N results (default 0)
        in: query
        name: offset
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Data change logs with total count
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid parameters
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Forbidden
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List data change logs (Admin)
      tags:
      - admin
  /data-change-logs/entity/{entity_type}/{entity_id}:
    get:
      consumes:
      - application/json
      description: Get the change history for a specific entity
      parameters:
      - description: Entity type (e.g., user, workout, wod)
        in: path
        name: entity_type
        required: true
        type: string
      - description: Entity ID
        in: path
        name: entity_id
        required: true
        type: integer
      - description: Max results (default 50)
        in: query
        name: limit
        type: integer
      - description: Skip N results (default 0)
        in: query
        name: offset
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Entity change history
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid entity_id
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Forbidden
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get entity history (Admin)
      tags:
      - admin
  /data-change-logs/{id}:
    get:
      consumes:
      - application/json
      description: Retrieve a specific data change log entry by ID
      parameters:
      - description: Data Change Log ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Data change log entry
          schema:
            $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.DataChangeLog'
        '400':
          description: Invalid ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Forbidden
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Log not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get data change log (Admin)
      tags:
      - admin
  /export/movements:
    get:
      consumes:
      - application/json
      description: Export movements to CSV or JSON format with optional filters
      parameters:
      - description: Include standard movements (default true)
        in: query
        name: include_standard
        type: boolean
      - description: Include custom movements (default true)
        in: query
        name: include_custom
        type: boolean
      - description: 'Export format: csv or json (default csv)'
        in: query
        name: format
        type: string
      produces:
      - text/csv
      - application/json
      responses:
        '200':
          description: Exported file (CSV or JSON)
          schema:
            type: file
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Export movements
      tags:
      - import-export
  /export/user-workouts:
    get:
      consumes:
      - application/json
      description: Export user's logged workouts to CSV or JSON format with optional date range
      parameters:
      - description: Start date (YYYY-MM-DD)
        in: query
        name: start_date
        type: string
      - description: End date (YYYY-MM-DD)
        in: query
        name: end_date
        type: string
      - description: 'Export format: csv or json (default json)'
        in: query
        name: format
        type: string
      produces:
      - text/csv
      - application/json
      responses:
        '200':
          description: Exported file (CSV or JSON)
          schema:
            type: file
        '400':
          description: Invalid date format
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Export user workouts
      tags:
      - import-export
  /export/wods:
    get:
      consumes:
      - application/json
      description: Export WODs to CSV or JSON format with optional filters
      parameters:
      - description: Include standard WODs (default true)
        in: query
        name: include_standard
        type: boolean
      - description: Include custom WODs (default true)
        in: query
        name: include_custom
        type: boolean
      - description: 'Export format: csv or json (default csv)'
        in: query
        name: format
        type: string
      produces:
      - text/csv
      - application/json
      responses:
        '200':
          description: Exported file (CSV or JSON)
          schema:
            type: file
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Export WODs
      tags:
      - import-export
  /gyms/{gym_id}/documents:
    get:
      description: List required documents for a gym (waivers, liability forms, etc.)
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of documents
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: List gym documents
      tags:
      - scheduling
  /gyms/{gym_id}/documents/{id}:
    get:
      description: Get details of a specific document
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      - description: Document ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Document details
        '401':
          description: Unauthorized
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get document details
      tags:
      - scheduling
  /gyms/{gym_id}/locations:
    get:
      description: List locations for a gym
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of locations
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: List gym locations
      tags:
      - scheduling
  /gyms/{gym_id}/locations/{id}:
    get:
      description: Get details of a specific gym location
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      - description: Location ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Location details
        '401':
          description: Unauthorized
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get location details
      tags:
      - scheduling
  /gyms/{gym_id}/packages:
    get:
      description: List class packages available at a gym
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of class packages
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: List class packages
      tags:
      - scheduling
  /gyms/{gym_id}/packages/{id}:
    get:
      description: Get details of a specific class package
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      - description: Package ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Package details
        '401':
          description: Unauthorized
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get class package details
      tags:
      - scheduling
  /gyms/{gym_id}/sessions:
    get:
      description: List upcoming class sessions for a gym
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of sessions
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: List gym sessions
      tags:
      - scheduling
  /gyms/{gym_id}/sessions/{id}:
    get:
      description: Get details of a specific class session
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      - description: Session ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Session details
        '401':
          description: Unauthorized
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get session details
      tags:
      - scheduling
  /gyms/{gym_id}/templates:
    get:
      description: List class templates for a gym
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of class templates
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: List class templates
      tags:
      - scheduling
  /gyms/{gym_id}/users/me/credits:
    get:
      description: Get the authenticated user's class credits for a gym
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: User credit records
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get user's credits
      tags:
      - scheduling
  /gyms/{gym_id}/users/me/credits/available:
    get:
      description: Get available (non-expired) credit count for the authenticated user at a gym
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Available credit count
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get user's available credits
      tags:
      - scheduling
  /gyms/{gym_id}/users/me/documents:
    get:
      description: Get the authenticated user's document completion status for a gym
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of user document statuses
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get user's gym documents
      tags:
      - scheduling
  /gyms/{gym_id}/users/me/documents/pending:
    get:
      description: Get the authenticated user's pending (incomplete) documents for a gym
      parameters:
      - description: Organization/Gym ID
        in: path
        name: gym_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of pending documents
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get user's pending documents
      tags:
      - scheduling
  /import/movements/confirm:
    post:
      consumes:
      - multipart/form-data
      description: Execute movement CSV import after preview
      parameters:
      - description: CSV file to import
        in: formData
        name: file
        required: true
        type: file
      - description: Skip duplicate entries
        in: formData
        name: skip_duplicates
        type: boolean
      - description: Update existing duplicates
        in: formData
        name: update_duplicates
        type: boolean
      produces:
      - application/json
      responses:
        '200':
          description: Import results with counts
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid file
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Import failed
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Confirm movement import
      tags:
      - import-export
  /import/movements/preview:
    post:
      consumes:
      - multipart/form-data
      description: Validate and preview movement CSV import before confirming
      parameters:
      - description: CSV file to import
        in: formData
        name: file
        required: true
        type: file
      produces:
      - application/json
      responses:
        '200':
          description: Import preview with validation results
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid file or validation failed
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Preview movement import
      tags:
      - import-export
  /import/user-workouts/confirm:
    post:
      consumes:
      - multipart/form-data
      description: Execute user workout JSON import after preview
      parameters:
      - description: JSON file to import
        in: formData
        name: file
        required: true
        type: file
      - description: Skip duplicate entries
        in: formData
        name: skip_duplicates
        type: boolean
      - description: Update existing duplicates
        in: formData
        name: update_duplicates
        type: boolean
      produces:
      - application/json
      responses:
        '200':
          description: Import results with counts
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid file
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Import failed
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Confirm user workout import
      tags:
      - import-export
  /import/user-workouts/preview:
    post:
      consumes:
      - multipart/form-data
      description: Validate and preview user workout JSON import before confirming
      parameters:
      - description: JSON file to import
        in: formData
        name: file
        required: true
        type: file
      produces:
      - application/json
      responses:
        '200':
          description: Import preview with validation results
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid file or validation failed
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Preview user workout import
      tags:
      - import-export
  /import/wodify/confirm:
    post:
      consumes:
      - multipart/form-data
      description: Execute Wodify performance data import after preview
      parameters:
      - description: Wodify export file
        in: formData
        name: file
        required: true
        type: file
      - description: Skip duplicate entries
        in: formData
        name: skip_duplicates
        type: boolean
      - description: Update existing duplicates
        in: formData
        name: update_duplicates
        type: boolean
      produces:
      - application/json
      responses:
        '200':
          description: Import results with counts
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid file
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Import failed
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Confirm Wodify import
      tags:
      - import-export
  /import/wodify/preview:
    post:
      consumes:
      - multipart/form-data
      description: Validate and preview Wodify performance data import before confirming
      parameters:
      - description: Wodify export file
        in: formData
        name: file
        required: true
        type: file
      produces:
      - application/json
      responses:
        '200':
          description: Import preview with validation results
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid file
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Preview failed
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Preview Wodify import
      tags:
      - import-export
  /import/wods/confirm:
    post:
      consumes:
      - multipart/form-data
      description: Execute WOD CSV import after preview
      parameters:
      - description: CSV file to import
        in: formData
        name: file
        required: true
        type: file
      - description: Skip duplicate entries
        in: formData
        name: skip_duplicates
        type: boolean
      - description: Update existing duplicates
        in: formData
        name: update_duplicates
        type: boolean
      produces:
      - application/json
      responses:
        '200':
          description: Import results with counts
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid file
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Import failed
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Confirm WOD import
      tags:
      - import-export
  /import/wods/preview:
    post:
      consumes:
      - multipart/form-data
      description: Validate and preview WOD CSV import before confirming
      parameters:
      - description: CSV file to import
        in: formData
        name: file
        required: true
        type: file
      produces:
      - application/json
      responses:
        '200':
          description: Import preview with validation results
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid file or validation failed
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Preview WOD import
      tags:
      - import-export
  /movements:
    get:
      consumes:
      - application/json
      description: Retrieve all movements including standard and custom
      produces:
      - application/json
      responses:
        '200':
          description: List of all movements
          schema:
            $ref: '#/definitions/internal_handler.MovementListResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      summary: List all movements
      tags:
      - movements
    post:
      consumes:
      - application/json
      description: Create a new custom movement (non-standard)
      parameters:
      - description: Movement details
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.CreateMovementRequest'
      produces:
      - application/json
      responses:
        '201':
          description: Created movement
          schema:
            $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.Movement'
        '400':
          description: Invalid request body
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Create a custom movement
      tags:
      - movements
  /movements/search:
    get:
      consumes:
      - application/json
      description: Search for movements by name
      parameters:
      - description: Search query
        in: query
        name: q
        required: true
        type: string
      - description: Max results (default 20)
        in: query
        name: limit
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Matching movements
          schema:
            $ref: '#/definitions/internal_handler.MovementListResponse'
        '400':
          description: Missing query parameter
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      summary: Search movements
      tags:
      - movements
  /movements/standard:
    get:
      consumes:
      - application/json
      description: Retrieve only standard (built-in) movements
      produces:
      - application/json
      responses:
        '200':
          description: List of standard movements
          schema:
            $ref: '#/definitions/internal_handler.MovementListResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      summary: List standard movements
      tags:
      - movements
  /movements/{id}:
    delete:
      consumes:
      - application/json
      description: Delete a custom movement (cannot delete standard movements)
      parameters:
      - description: Movement ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Movement deleted successfully
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid movement ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Cannot delete standard movement
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Delete a movement
      tags:
      - movements
    get:
      consumes:
      - application/json
      description: Retrieve a single movement by its ID
      parameters:
      - description: Movement ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Movement details
          schema:
            $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.Movement'
        '400':
          description: Invalid movement ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Movement not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      summary: Get movement by ID
      tags:
      - movements
    put:
      consumes:
      - application/json
      description: Update an existing movement (admin can update any, users only custom)
      parameters:
      - description: Movement ID
        in: path
        name: id
        required: true
        type: integer
      - description: Updated movement details
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.CreateMovementRequest'
      produces:
      - application/json
      responses:
        '200':
          description: Updated movement
          schema:
            $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.Movement'
        '400':
          description: Invalid request body
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Cannot modify standard movement
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Update a movement
      tags:
      - movements
  /notifications:
    get:
      consumes:
      - application/json
      description: Retrieve all notifications for the authenticated user
      parameters:
      - description: Max results (default 20, max 100)
        in: query
        name: limit
        type: integer
      - description: Skip N results (default 0)
        in: query
        name: offset
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of notifications
          schema:
            additionalProperties: true
            type: object
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List notifications
      tags:
      - notifications
  /notifications/count:
    get:
      consumes:
      - application/json
      description: Get the count of unread notifications (for badge display)
      produces:
      - application/json
      responses:
        '200':
          description: Unread count
          schema:
            additionalProperties: true
            type: object
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get unread notification count
      tags:
      - notifications
  /notifications/read-all:
    put:
      consumes:
      - application/json
      description: Mark all notifications for the user as read
      produces:
      - application/json
      responses:
        '200':
          description: All marked as read
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Mark all notifications as read
      tags:
      - notifications
  /notifications/unread:
    get:
      consumes:
      - application/json
      description: Retrieve only unread notifications for the authenticated user
      parameters:
      - description: Max results (default 20, max 100)
        in: query
        name: limit
        type: integer
      - description: Skip N results (default 0)
        in: query
        name: offset
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of unread notifications
          schema:
            additionalProperties: true
            type: object
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List unread notifications
      tags:
      - notifications
  /notifications/{id}:
    delete:
      consumes:
      - application/json
      description: Delete a specific notification
      parameters:
      - description: Notification ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Notification deleted
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid notification ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Delete notification
      tags:
      - notifications
  /notifications/{id}/like:
    delete:
      consumes:
      - application/json
      description: Remove like from a notification
      parameters:
      - description: Notification ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '204':
          description: Like removed
        '400':
          description: Invalid notification ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Unlike notification
      tags:
      - notifications
    post:
      consumes:
      - application/json
      description: Like a notification (e.g., PR announcement)
      parameters:
      - description: Notification ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '201':
          description: Notification liked
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid notification ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '409':
          description: Already liked
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Like notification
      tags:
      - notifications
  /notifications/{id}/likes:
    get:
      consumes:
      - application/json
      description: Get all likes for a notification
      parameters:
      - description: Notification ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Likes list with count
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid notification ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get notification likes
      tags:
      - notifications
  /notifications/{id}/read:
    put:
      consumes:
      - application/json
      description: Mark a specific notification as read
      parameters:
      - description: Notification ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Marked as read
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid notification ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Mark notification as read
      tags:
      - notifications
  /performance/movements/{id}:
    get:
      consumes:
      - application/json
      description: Retrieve all performance records for a movement with calculated 1RM values
      parameters:
      - description: Movement ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Performance history with best 1RM
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid movement ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get movement performance history
      tags:
      - performance
  /performance/search:
    get:
      consumes:
      - application/json
      description: Search across both movements and WODs in a single query
      parameters:
      - description: Search query
        in: query
        name: q
        required: true
        type: string
      - description: Max results per category (default 10)
        in: query
        name: limit
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Combined search results
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Missing search query
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Unified search for movements and WODs
      tags:
      - performance
  /performance/wods/{id}:
    get:
      consumes:
      - application/json
      description: Retrieve all performance records for a specific WOD
      parameters:
      - description: WOD ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: WOD performance history
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid WOD ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get WOD performance history
      tags:
      - performance
  /prs:
    get:
      consumes:
      - application/json
      description: Retrieve all personal records (PRs) for movements and WODs
      parameters:
      - description: Max results (default 50, max 200)
        in: query
        name: limit
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of personal records
          schema:
            additionalProperties: true
            type: object
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get all personal records
      tags:
      - prs
  /prs/movements:
    get:
      consumes:
      - application/json
      description: Retrieve movements that have personal records with summary stats
      parameters:
      - description: Max results (default 20, max 100)
        in: query
        name: limit
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Movement PR summaries
          schema:
            additionalProperties: true
            type: object
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get movements with PRs
      tags:
      - prs
  /prs/toggle:
    post:
      consumes:
      - application/json
      description: Toggle the personal record flag on a specific workout movement
      parameters:
      - description: Workout movement ID
        in: query
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: New PR state
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Missing or invalid movement ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Movement not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Toggle movement PR flag
      tags:
      - prs
  /sessions:
    get:
      consumes:
      - application/json
      description: Get all active sessions for the current user
      produces:
      - application/json
      responses:
        '200':
          description: List of active sessions
          schema:
            additionalProperties: true
            type: object
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List active sessions
      tags:
      - sessions
  /sessions/revoke-all:
    post:
      consumes:
      - application/json
      description: Revoke all sessions for the current user (log out everywhere)
      parameters:
      - description: Options (except_current_session)
        in: body
        name: request
        schema:
          type: object
      produces:
      - application/json
      responses:
        '200':
          description: All sessions revoked
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Revoke all sessions
      tags:
      - sessions
  /sessions/{id}:
    delete:
      consumes:
      - application/json
      description: Revoke a specific session (log out that device)
      parameters:
      - description: Session ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Session revoked
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid session ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Revoke session
      tags:
      - sessions
  /sessions/{session_id}/reserve:
    delete:
      description: Cancel a reservation for a class session
      parameters:
      - description: Session ID
        in: path
        name: session_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Reservation cancelled
        '401':
          description: Unauthorized
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Cancel reservation
      tags:
      - scheduling
    post:
      description: Reserve a spot in a class session
      parameters:
      - description: Session ID
        in: path
        name: session_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '201':
          description: Reservation created
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '402':
          description: Payment required
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Reserve session spot
      tags:
      - scheduling
  /sessions/{session_id}/waitlist:
    delete:
      description: Leave the waitlist for a class session
      parameters:
      - description: Session ID
        in: path
        name: session_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Removed from waitlist
        '401':
          description: Unauthorized
        '404':
          description: Not found
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Leave session waitlist
      tags:
      - scheduling
    get:
      description: Get the waitlist for a class session
      parameters:
      - description: Session ID
        in: path
        name: session_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of waitlist entries
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get session waitlist
      tags:
      - scheduling
    post:
      description: Join the waitlist for a full class session
      parameters:
      - description: Session ID
        in: path
        name: session_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '201':
          description: Added to waitlist
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '402':
          description: Payment required
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Join session waitlist
      tags:
      - scheduling
  /sessions/{session_id}/waitlist/position:
    get:
      description: Get the authenticated user's position on the session waitlist
      parameters:
      - description: Session ID
        in: path
        name: session_id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Waitlist position
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get waitlist position
      tags:
      - scheduling
  /settings:
    get:
      consumes:
      - application/json
      description: Retrieve the current user's settings
      produces:
      - application/json
      responses:
        '200':
          description: User settings
          schema:
            additionalProperties: true
            type: object
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get user settings
      tags:
      - users
    put:
      consumes:
      - application/json
      description: Update the current user's settings
      parameters:
      - description: Updated settings
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/github_com_johnzastrow_actalog_internal_domain.UserSettings'
      produces:
      - application/json
      responses:
        '200':
          description: Updated settings
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid request
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Update user settings
      tags:
      - users
  /stats/active-users-this-month:
    get:
      consumes:
      - application/json
      description: Retrieve stats about active users who have logged workouts this month
      produces:
      - application/json
      responses:
        '200':
          description: Active users stats
          schema:
            additionalProperties: true
            type: object
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get active users this month
      tags:
      - workouts
  /subscriptions/my-status:
    get:
      consumes:
      - application/json
      description: Get the current user's subscription status and plan details
      produces:
      - application/json
      responses:
        '200':
          description: Subscription status
          schema:
            additionalProperties: true
            type: object
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get my subscription status
      tags:
      - subscriptions
  /templates:
    get:
      consumes:
      - application/json
      description: Get all standard (system-provided) workout templates
      parameters:
      - description: Max results (default 100)
        in: query
        name: limit
        type: integer
      - description: Skip N results (default 0)
        in: query
        name: offset
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of standard templates
          schema:
            additionalProperties: true
            type: object
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List standard workout templates
      tags:
      - templates
    post:
      consumes:
      - application/json
      description: Create a new reusable workout template with movements and WODs
      parameters:
      - description: Template details with movements and WODs
        in: body
        name: request
        required: true
        schema:
          type: object
      produces:
      - application/json
      responses:
        '201':
          description: Created template
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid request
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Create workout template
      tags:
      - templates
  /templates/{id}:
    delete:
      consumes:
      - application/json
      description: Delete a workout template (owner only)
      parameters:
      - description: Template ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '204':
          description: Template deleted
        '400':
          description: Invalid template ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Not the template owner
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Delete workout template
      tags:
      - templates
    get:
      consumes:
      - application/json
      description: Retrieve a specific workout template by ID with full details
      parameters:
      - description: Template ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Template details
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid template ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Template not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get workout template
      tags:
      - templates
    put:
      consumes:
      - application/json
      description: Update an existing workout template (owner only)
      parameters:
      - description: Template ID
        in: path
        name: id
        required: true
        type: integer
      - description: Updated template details
        in: body
        name: request
        required: true
        schema:
          type: object
      produces:
      - application/json
      responses:
        '200':
          description: Updated template
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid request
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Update workout template
      tags:
      - templates
  /users/avatar:
    delete:
      consumes:
      - application/json
      description: Remove the authenticated user's avatar image
      produces:
      - application/json
      responses:
        '200':
          description: Avatar deleted successfully
          schema:
            $ref: '#/definitions/internal_handler.ProfileResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Failed to delete avatar
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Delete avatar image
      tags:
      - users
    post:
      consumes:
      - multipart/form-data
      description: Upload a new avatar image for the authenticated user (max 5MB)
      parameters:
      - description: Avatar image file
        in: formData
        name: avatar
        required: true
        type: file
      produces:
      - application/json
      responses:
        '200':
          description: Avatar uploaded successfully
          schema:
            $ref: '#/definitions/internal_handler.ProfileResponse'
        '400':
          description: No file provided, file too large, or invalid file type
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Failed to save avatar
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Upload avatar image
      tags:
      - users
  /users/change-password:
    post:
      consumes:
      - application/json
      description: Change the authenticated user's password
      parameters:
      - description: Current and new password
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.ChangePasswordRequest'
      produces:
      - application/json
      responses:
        '200':
          description: Password changed successfully
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid request or weak password
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized or incorrect current password
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Failed to change password
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Change password
      tags:
      - users
  /users/me/audit-logs:
    get:
      consumes:
      - application/json
      description: Get audit logs for the current user only
      parameters:
      - description: Max results (default 50)
        in: query
        name: limit
        type: integer
      - description: Skip N results (default 0)
        in: query
        name: offset
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: User's audit logs with total count
          schema:
            additionalProperties: true
            type: object
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get my audit logs
      tags:
      - audit
  /users/me/documents:
    get:
      description: Get the authenticated user's documents across all gyms
      produces:
      - application/json
      responses:
        '200':
          description: List of user documents
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get user's documents
      tags:
      - scheduling
  /users/me/notifications:
    get:
      description: Get the authenticated user's phase 4 notifications
      produces:
      - application/json
      responses:
        '200':
          description: List of notifications
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get user's class notifications
      tags:
      - scheduling
  /users/me/reservations/upcoming:
    get:
      description: Get the authenticated user's upcoming reservations across all gyms
      produces:
      - application/json
      responses:
        '200':
          description: List of upcoming reservations
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get upcoming reservations
      tags:
      - scheduling
  /users/me/waitlist:
    get:
      description: Get the authenticated user's waitlist entries across all gyms
      produces:
      - application/json
      responses:
        '200':
          description: List of waitlist entries
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      security:
      - BearerAuth: []
      summary: Get user's waitlist entries
      tags:
      - scheduling
  /users/profile:
    get:
      consumes:
      - application/json
      description: Retrieve the authenticated user's profile information
      produces:
      - application/json
      responses:
        '200':
          description: User profile
          schema:
            $ref: '#/definitions/internal_handler.ProfileResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: User not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get user profile
      tags:
      - users
    put:
      consumes:
      - application/json
      description: Update the authenticated user's profile information
      parameters:
      - description: Profile updates
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.UpdateProfileRequest'
      produces:
      - application/json
      responses:
        '200':
          description: Profile updated successfully
          schema:
            $ref: '#/definitions/internal_handler.ProfileResponse'
        '400':
          description: Invalid request body or birthday format
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: User not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '409':
          description: Email already in use
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Update user profile
      tags:
      - users
  /wods:
    get:
      consumes:
      - application/json
      description: Retrieve all WODs including standard and user's custom WODs
      parameters:
      - description: Max results (default 100)
        in: query
        name: limit
        type: integer
      - description: Skip N results (default 0)
        in: query
        name: offset
        type: integer
      - description: Return only standard WODs
        in: query
        name: standard
        type: boolean
      produces:
      - application/json
      responses:
        '200':
          description: List of WODs
          schema:
            $ref: '#/definitions/internal_handler.WODListResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List all WODs
      tags:
      - wods
    post:
      consumes:
      - application/json
      description: Create a new custom WOD (Workout of the Day)
      parameters:
      - description: WOD details
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.CreateWODRequest'
      produces:
      - application/json
      responses:
        '201':
          description: Created WOD
          schema:
            $ref: '#/definitions/internal_handler.WODResponse'
        '400':
          description: Invalid request body or missing name
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Create a custom WOD
      tags:
      - wods
  /wods/mine:
    get:
      consumes:
      - application/json
      description: Retrieve only the authenticated user's custom WODs
      parameters:
      - description: Max results (default 100)
        in: query
        name: limit
        type: integer
      - description: Skip N results (default 0)
        in: query
        name: offset
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of user's custom WODs
          schema:
            $ref: '#/definitions/internal_handler.WODListResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List my custom WODs
      tags:
      - wods
  /wods/search:
    get:
      consumes:
      - application/json
      description: Search for WODs by name
      parameters:
      - description: Search query
        in: query
        name: q
        required: true
        type: string
      produces:
      - application/json
      responses:
        '200':
          description: Matching WODs
          schema:
            $ref: '#/definitions/internal_handler.WODListResponse'
        '400':
          description: Missing search query
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      summary: Search WODs
      tags:
      - wods
  /wods/standard:
    get:
      consumes:
      - application/json
      description: Retrieve only standard (built-in) WODs
      parameters:
      - description: Max results (default 100)
        in: query
        name: limit
        type: integer
      - description: Skip N results (default 0)
        in: query
        name: offset
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of standard WODs
          schema:
            $ref: '#/definitions/internal_handler.WODListResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      summary: List standard WODs
      tags:
      - wods
  /wods/{id}:
    delete:
      consumes:
      - application/json
      description: Delete a custom WOD (cannot delete standard WODs)
      parameters:
      - description: WOD ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: WOD deleted successfully
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid WOD ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Forbidden - cannot delete this WOD
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Delete a WOD
      tags:
      - wods
    get:
      consumes:
      - application/json
      description: Retrieve a single WOD by its ID
      parameters:
      - description: WOD ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: WOD details
          schema:
            $ref: '#/definitions/internal_handler.WODResponse'
        '400':
          description: Invalid WOD ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      summary: Get WOD by ID
      tags:
      - wods
    put:
      consumes:
      - application/json
      description: Update an existing WOD (admin can update any, users only their own custom WODs)
      parameters:
      - description: WOD ID
        in: path
        name: id
        required: true
        type: integer
      - description: Updated WOD details
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.UpdateWODRequest'
      produces:
      - application/json
      responses:
        '200':
          description: Updated WOD
          schema:
            $ref: '#/definitions/internal_handler.WODResponse'
        '400':
          description: Invalid request body
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Forbidden - not your WOD
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Update a WOD
      tags:
      - wods
  /workouts:
    get:
      consumes:
      - application/json
      description: Retrieve all logged workouts for the user with pagination and optional date filtering
      parameters:
      - description: Max results (default 20)
        in: query
        name: limit
        type: integer
      - description: Skip N results (default 0)
        in: query
        name: offset
        type: integer
      - description: Filter start date (YYYY-MM-DD)
        in: query
        name: start_date
        type: string
      - description: Filter end date (YYYY-MM-DD)
        in: query
        name: end_date
        type: string
      produces:
      - application/json
      responses:
        '200':
          description: List of workouts with pagination
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid date format
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List logged workouts
      tags:
      - workouts
    post:
      consumes:
      - application/json
      description: Record a workout with performance data. Can be based on a template or ad-hoc.
      parameters:
      - description: Workout data with optional performance
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.LogWorkoutRequest'
      produces:
      - application/json
      responses:
        '201':
          description: Workout logged successfully
          schema:
            $ref: '#/definitions/internal_handler.UserWorkoutResponse'
        '400':
          description: Invalid request body or missing required fields
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Log a workout
      tags:
      - workouts
  /workouts/my-templates:
    get:
      consumes:
      - application/json
      description: Get all workout templates created by the current user
      parameters:
      - description: Max results (default 100)
        in: query
        name: limit
        type: integer
      - description: Skip N results (default 0)
        in: query
        name: offset
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: List of user's templates
          schema:
            additionalProperties: true
            type: object
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: List my workout templates
      tags:
      - templates
  /workouts/personal-records:
    get:
      consumes:
      - application/json
      description: Retrieve all personal records for movements and WODs
      parameters:
      - description: Max results per category (default 50)
        in: query
        name: limit
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: PR movements and PR WODs
          schema:
            additionalProperties: true
            type: object
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get personal records
      tags:
      - workouts
  /workouts/retroactive-prs:
    post:
      consumes:
      - application/json
      description: Analyze all existing workouts and flag personal records based on historical data
      produces:
      - application/json
      responses:
        '200':
          description: Count of flagged PRs
          schema:
            additionalProperties: true
            type: object
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Retroactively flag PRs
      tags:
      - workouts
  /workouts/stats/monthly:
    get:
      consumes:
      - application/json
      description: Retrieve the workout count for a specific month
      parameters:
      - description: Year (e.g., 2024)
        in: query
        name: year
        required: true
        type: integer
      - description: Month (1-12)
        in: query
        name: month
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Monthly stats with workout count
          schema:
            additionalProperties: true
            type: object
        '400':
          description: Invalid year or month
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get monthly workout stats
      tags:
      - workouts
  /workouts/{id}:
    delete:
      consumes:
      - application/json
      description: Delete a specific logged workout and all its performance data
      parameters:
      - description: Logged workout ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Workout deleted successfully
          schema:
            $ref: '#/definitions/internal_handler.MessageResponse'
        '400':
          description: Invalid workout ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Forbidden - not your workout
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Delete a logged workout
      tags:
      - workouts
    get:
      consumes:
      - application/json
      description: Retrieve a specific logged workout by ID with all performance data
      parameters:
      - description: Logged workout ID
        in: path
        name: id
        required: true
        type: integer
      produces:
      - application/json
      responses:
        '200':
          description: Logged workout details
          schema:
            $ref: '#/definitions/internal_handler.UserWorkoutResponse'
        '400':
          description: Invalid workout ID
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get a logged workout
      tags:
      - workouts
    put:
      consumes:
      - application/json
      description: Update an existing logged workout's details and performance data
      parameters:
      - description: Logged workout ID
        in: path
        name: id
        required: true
        type: integer
      - description: Updated workout data
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/internal_handler.UpdateLoggedWorkoutRequest'
      produces:
      - application/json
      responses:
        '200':
          description: Updated workout details
          schema:
            $ref: '#/definitions/internal_handler.UserWorkoutResponse'
        '400':
          description: Invalid request
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '401':
          description: Unauthorized
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '403':
          description: Forbidden - not your workout
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '404':
          description: Workout not found
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
        '500':
          description: Internal server error
          schema:
            $ref: '#/definitions/internal_handler.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Update a logged workout
      tags:
      - workouts
securityDefinitions:
  BearerAuth:
    description: 'JWT Bearer token. Format: "Bearer {token}"'
    in: header
    name: Authorization
    type: apiKey
swagger: '2.0'
tags:
- description: Coach portal - session roster and check-in
  name: coaches
- description: Class scheduling - sessions, reservations, waitlist
  name: scheduling
- description: Admin class scheduling management
  name: admin-scheduling
- description: Admin email configuration and logs
  name: admin-email
- description: Admin data quality and duplicate detection
  name: admin-data-quality
- description: Admin user import/export and batch operations
  name: admin-user-management