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