docs/swagger.json
Rama main · réplica de lectura del repositorio original.
{
"swagger": "2.0",
"info": {
"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.",
"title": "ActaLog API",
"termsOfService": "https://actalog.com/terms/",
"contact": {
"name": "ActaLog Support",
"url": "https://github.com/johnzastrow/actalog/issues",
"email": "support@actalog.com"
},
"license": {
"name": "MIT",
"url": "https://opensource.org/licenses/MIT"
},
"version": "1.1.0-beta"
},
"host": "localhost:8080",
"basePath": "/api",
"paths": {
"/admin/audit-logs/cleanup": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Delete audit logs older than specified retention period",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"audit"
],
"summary": "Cleanup old audit logs (Admin)",
"parameters": [
{
"description": "Retention days (must be positive)",
"name": "request",
"in": "body",
"required": true,
"schema": {
"type": "object"
}
}
],
"responses": {
"200": {
"description": "Deleted count and success message",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/admin/backups": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get a list of all available backup files",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"backups"
],
"summary": "List backups (Admin)",
"responses": {
"200": {
"description": "List of backups with count",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Create a new database backup",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"backups"
],
"summary": "Create backup (Admin)",
"responses": {
"201": {
"description": "Backup created with filename and metadata",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/admin/backups/upload": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Upload a backup ZIP file from another system",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"backups"
],
"summary": "Upload backup (Admin)",
"parameters": [
{
"type": "file",
"description": "Backup ZIP file",
"name": "file",
"in": "formData",
"required": true
}
],
"responses": {
"201": {
"description": "Upload success with filename and metadata",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/admin/backups/{filename}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Download a backup file",
"consumes": [
"application/json"
],
"produces": [
"application/zip"
],
"tags": [
"backups"
],
"summary": "Download backup (Admin)",
"parameters": [
{
"type": "string",
"description": "Backup filename",
"name": "filename",
"in": "path",
"required": true
}
],
"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"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Delete a backup file",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"backups"
],
"summary": "Delete backup (Admin)",
"parameters": [
{
"type": "string",
"description": "Backup filename",
"name": "filename",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Success message with filename",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/admin/backups/{filename}/metadata": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get metadata information for a specific backup file",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"backups"
],
"summary": "Get backup metadata (Admin)",
"parameters": [
{
"type": "string",
"description": "Backup filename",
"name": "filename",
"in": "path",
"required": true
}
],
"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"
}
}
}
}
},
"/admin/backups/{filename}/restore": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Restore database from a backup file (requires confirmation)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"backups"
],
"summary": "Restore backup (Admin)",
"parameters": [
{
"type": "string",
"description": "Backup filename",
"name": "filename",
"in": "path",
"required": true
},
{
"description": "Restore options (confirm, mode)",
"name": "request",
"in": "body",
"required": true,
"schema": {
"type": "object"
}
}
],
"responses": {
"200": {
"description": "Restore result",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/admin/benchmark/data": {
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Delete all benchmark data from the database",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"benchmark"
],
"summary": "Cleanup all benchmark data (Admin)",
"responses": {
"200": {
"description": "Cleanup result",
"schema": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
"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"
}
}
}
}
},
"/admin/data-change-logs/cleanup": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Delete data change logs older than specified retention period",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Cleanup old data change logs (Admin)",
"parameters": [
{
"description": "Retention days (must be positive)",
"name": "request",
"in": "body",
"required": true,
"schema": {
"type": "object"
}
}
],
"responses": {
"200": {
"description": "Deleted count and success message",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/admin/notifications/announce": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Send an announcement to all users, organization members, or specific users",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Create announcement (Admin)",
"parameters": [
{
"description": "Announcement details",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.CreateAnnouncementRequest"
}
}
],
"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"
}
}
}
}
},
"/admin/organizations": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get a paginated list of all organizations",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"organizations"
],
"summary": "List organizations (Admin)",
"parameters": [
{
"type": "integer",
"description": "Max results (default 50)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Skip N results (default 0)",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "Organizations list with total count",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Create a new organization (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"organizations"
],
"summary": "Create organization (Admin)",
"parameters": [
{
"description": "Organization name and description",
"name": "request",
"in": "body",
"required": true,
"schema": {
"type": "object"
}
}
],
"responses": {
"201": {
"description": "Created organization",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/admin/organizations/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get details of a specific organization",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"organizations"
],
"summary": "Get organization (Admin)",
"parameters": [
{
"type": "integer",
"description": "Organization ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Organization details",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
},
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Update an existing organization's details",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"organizations"
],
"summary": "Update organization (Admin)",
"parameters": [
{
"type": "integer",
"description": "Organization ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Updated organization details",
"name": "request",
"in": "body",
"required": true,
"schema": {
"type": "object"
}
}
],
"responses": {
"200": {
"description": "Updated organization",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Delete an organization (must have no assigned users)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"organizations"
],
"summary": "Delete organization (Admin)",
"parameters": [
{
"type": "integer",
"description": "Organization ID",
"name": "id",
"in": "path",
"required": true
}
],
"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"
}
}
}
}
},
"/admin/organizations/{id}/users": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get all users belonging to an organization",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"organizations"
],
"summary": "Get organization users (Admin)",
"parameters": [
{
"type": "integer",
"description": "Organization ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "List of users",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/admin/subscriptions/organizations": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get a list of all organization subscriptions in the system",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "List all organization subscriptions (Admin)",
"responses": {
"200": {
"description": "Subscriptions list",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Create a new subscription for an organization (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Create organization subscription (Admin)",
"parameters": [
{
"description": "Subscription details",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.CreateOrganizationSubscriptionRequest"
}
}
],
"responses": {
"201": {
"description": "Created subscription",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/admin/subscriptions/organizations/expired": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get a list of expired or overdue organization subscriptions",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "List expired organization subscriptions (Admin)",
"responses": {
"200": {
"description": "Expired subscriptions list",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/admin/subscriptions/organizations/expiring": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get a list of organization subscriptions expiring within the specified number of days",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "List expiring organization subscriptions (Admin)",
"parameters": [
{
"type": "integer",
"description": "Number of days to look ahead (default: 30)",
"name": "days",
"in": "query"
}
],
"responses": {
"200": {
"description": "Expiring subscriptions list",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/admin/subscriptions/organizations/{id}/cancel": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Cancel an organization subscription with a reason",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Cancel organization subscription (Admin)",
"parameters": [
{
"type": "integer",
"description": "Subscription ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Cancellation reason",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.CancelSubscriptionRequest"
}
}
],
"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"
}
}
}
}
},
"/admin/subscriptions/organizations/{id}/paid": {
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Mark an organization subscription as paid and extend the subscription period",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Mark organization subscription as paid (Admin)",
"parameters": [
{
"type": "integer",
"description": "Subscription ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Payment details",
"name": "request",
"in": "body",
"schema": {
"$ref": "#/definitions/internal_handler.MarkUserSubscriptionAsPaidRequest"
}
}
],
"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"
}
}
}
}
},
"/admin/subscriptions/organizations/{id}/permanent": {
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Set whether an organization subscription is permanently free",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Set organization subscription permanent status (Admin)",
"parameters": [
{
"type": "integer",
"description": "Subscription ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Permanent status",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.SetUserSubscriptionPermanentRequest"
}
}
],
"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"
}
}
}
}
},
"/admin/subscriptions/organizations/{org_id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get all subscriptions for a specific organization (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Get organization subscriptions (Admin)",
"parameters": [
{
"type": "integer",
"description": "Organization ID",
"name": "org_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Subscriptions list",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Invalid organization ID",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/admin/subscriptions/users": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get a list of all user subscriptions in the system",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "List all user subscriptions (Admin)",
"responses": {
"200": {
"description": "Subscriptions list",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Create a new subscription for a user (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Create user subscription (Admin)",
"parameters": [
{
"description": "Subscription details",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.CreateUserSubscriptionRequest"
}
}
],
"responses": {
"201": {
"description": "Created subscription",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/admin/subscriptions/users/expired": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get a list of expired or overdue user subscriptions",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "List expired user subscriptions (Admin)",
"responses": {
"200": {
"description": "Expired subscriptions list",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/admin/subscriptions/users/expiring": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get a list of user subscriptions expiring within the specified number of days",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "List expiring user subscriptions (Admin)",
"parameters": [
{
"type": "integer",
"description": "Number of days to look ahead (default: 30)",
"name": "days",
"in": "query"
}
],
"responses": {
"200": {
"description": "Expiring subscriptions list",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/admin/subscriptions/users/{id}/cancel": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Cancel a user subscription with a reason",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Cancel user subscription (Admin)",
"parameters": [
{
"type": "integer",
"description": "Subscription ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Cancellation reason",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.CancelSubscriptionRequest"
}
}
],
"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"
}
}
}
}
},
"/admin/subscriptions/users/{id}/paid": {
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Mark a user subscription as paid and extend the subscription period",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Mark user subscription as paid (Admin)",
"parameters": [
{
"type": "integer",
"description": "Subscription ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Payment details",
"name": "request",
"in": "body",
"schema": {
"$ref": "#/definitions/internal_handler.MarkUserSubscriptionAsPaidRequest"
}
}
],
"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"
}
}
}
}
},
"/admin/subscriptions/users/{id}/permanent": {
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Set whether a user subscription is permanently free",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Set user subscription permanent status (Admin)",
"parameters": [
{
"type": "integer",
"description": "Subscription ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Permanent status",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.SetUserSubscriptionPermanentRequest"
}
}
],
"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"
}
}
}
}
},
"/admin/subscriptions/users/{user_id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get all subscriptions for a specific user (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Get user subscriptions (Admin)",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "user_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Subscriptions list",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Invalid user ID",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/admin/user-created/movements": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get all user-created movements with creator information",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "List user-created movements (Admin)",
"parameters": [
{
"type": "integer",
"description": "Max results (default 100)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Skip N results (default 0)",
"name": "offset",
"in": "query"
},
{
"type": "string",
"description": "Search query",
"name": "search",
"in": "query"
},
{
"type": "string",
"description": "Filter by movement type",
"name": "type",
"in": "query"
},
{
"type": "string",
"description": "Filter by creator email",
"name": "creator",
"in": "query"
}
],
"responses": {
"200": {
"description": "List of user-created movements",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/admin/user-created/movements/{id}/copy-to-standard": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Create a standard movement from a user-created movement",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Copy movement to standard (Admin)",
"parameters": [
{
"type": "integer",
"description": "Movement ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "New name for standard movement",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.CopyToStandardRequest"
}
}
],
"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"
}
}
}
}
},
"/admin/user-created/wods": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get all user-created WODs with creator information",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "List user-created WODs (Admin)",
"parameters": [
{
"type": "integer",
"description": "Max results (default 100)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Skip N results (default 0)",
"name": "offset",
"in": "query"
},
{
"type": "string",
"description": "Search query",
"name": "search",
"in": "query"
},
{
"type": "string",
"description": "Filter by score type",
"name": "score_type",
"in": "query"
},
{
"type": "string",
"description": "Filter by creator email",
"name": "creator",
"in": "query"
}
],
"responses": {
"200": {
"description": "List of user-created WODs",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/admin/user-created/wods/{id}/copy-to-standard": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Create a standard WOD from a user-created WOD",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Copy WOD to standard (Admin)",
"parameters": [
{
"type": "integer",
"description": "WOD ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "New name for standard WOD",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.CopyToStandardRequest"
}
}
],
"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"
}
}
}
}
},
"/admin/user-created/workouts": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get all user-created workout templates with creator information",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "List user-created workouts (Admin)",
"parameters": [
{
"type": "integer",
"description": "Max results (default 100)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Skip N results (default 0)",
"name": "offset",
"in": "query"
},
{
"type": "string",
"description": "Search query",
"name": "search",
"in": "query"
},
{
"type": "string",
"description": "Filter by creator email",
"name": "creator",
"in": "query"
}
],
"responses": {
"200": {
"description": "List of user-created workouts",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/admin/user-created/workouts/{id}/copy-to-standard": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Create a standard workout template from a user-created workout",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Copy workout to standard (Admin)",
"parameters": [
{
"type": "integer",
"description": "Workout ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "New name for standard workout",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.CopyToStandardRequest"
}
}
],
"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"
}
}
}
}
},
"/admin/users": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get a paginated list of all users",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "List users (Admin)",
"parameters": [
{
"type": "integer",
"description": "Max results (default 50)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Skip N results (default 0)",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "Users list with total count",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/admin/users/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get detailed information about a specific user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Get user details (Admin)",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "User details",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Invalid user ID",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"404": {
"description": "User not found",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Permanently delete a user and all their data",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Delete user (Admin)",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
}
],
"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"
}
}
}
}
},
"/admin/users/{id}/disable": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Disable a user account with optional reason",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Disable user account (Admin)",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Optional disable reason",
"name": "request",
"in": "body",
"schema": {
"type": "object"
}
}
],
"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"
}
}
}
}
},
"/admin/users/{id}/enable": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Re-enable a previously disabled user account",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Enable user account (Admin)",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
}
],
"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"
}
}
}
}
},
"/admin/users/{id}/organization": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Assign a user to an organization",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"organizations"
],
"summary": "Assign user to organization (Admin)",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Organization ID to assign",
"name": "request",
"in": "body",
"required": true,
"schema": {
"type": "object"
}
}
],
"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"
}
}
}
}
},
"/admin/users/{id}/organization/{org_id}": {
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Remove a user from an organization",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"organizations"
],
"summary": "Remove user from organization (Admin)",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "Organization ID",
"name": "org_id",
"in": "path",
"required": true
}
],
"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"
}
}
}
}
},
"/admin/users/{id}/organizations": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get all organizations a user belongs to",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"organizations"
],
"summary": "Get user organizations (Admin)",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "List of organizations",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/admin/users/{id}/role": {
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Change a user's role to 'user' or 'admin'",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Change user role (Admin)",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "New role (user or admin)",
"name": "request",
"in": "body",
"required": true,
"schema": {
"type": "object"
}
}
],
"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"
}
}
}
}
},
"/admin/users/{id}/toggle-email-verification": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Manually set a user's email verification status",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Toggle email verification (Admin)",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Verified status (true/false)",
"name": "request",
"in": "body",
"required": true,
"schema": {
"type": "object"
}
}
],
"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"
}
}
}
}
},
"/admin/users/{id}/unlock": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Unlock a user account that was locked due to failed login attempts",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Unlock user account (Admin)",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
}
],
"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"
}
}
}
}
},
"/admin/wod-mismatches": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Find WOD records where data doesn't match the expected score_type",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Detect WOD score type mismatches (Admin)",
"responses": {
"200": {
"description": "List of mismatched records",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/admin/wod-mismatches/fix": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Delete WOD records that don't match their expected score_type",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Fix WOD score type mismatches (Admin)",
"responses": {
"200": {
"description": "Count of deleted records",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/admin/wod-records/{id}": {
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Update a specific WOD performance record",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Update WOD record (Admin)",
"parameters": [
{
"type": "integer",
"description": "WOD Record ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Updated record data",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.UpdateWODRecordRequest"
}
}
],
"responses": {
"200": {
"description": "Success message",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/audit-logs": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get a paginated list of audit logs with optional filters",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"audit"
],
"summary": "List audit logs (Admin)",
"parameters": [
{
"type": "integer",
"description": "Filter by user ID",
"name": "user_id",
"in": "query"
},
{
"type": "integer",
"description": "Filter by target user ID",
"name": "target_user_id",
"in": "query"
},
{
"type": "string",
"description": "Filter by event type",
"name": "event_type",
"in": "query"
},
{
"type": "string",
"description": "Filter by IP address",
"name": "ip_address",
"in": "query"
},
{
"type": "string",
"description": "Filter by start date (RFC3339)",
"name": "start_date",
"in": "query"
},
{
"type": "string",
"description": "Filter by end date (RFC3339)",
"name": "end_date",
"in": "query"
},
{
"type": "integer",
"description": "Max results (default 50)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Skip N results (default 0)",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "Audit logs list with total count",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/audit-logs/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve a specific audit log entry by ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"audit"
],
"summary": "Get audit log entry (Admin)",
"parameters": [
{
"type": "integer",
"description": "Audit Log ID",
"name": "id",
"in": "path",
"required": true
}
],
"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"
}
}
}
}
},
"/auth/forgot-password": {
"post": {
"description": "Send a password reset email to the user. Always returns success for security.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "Request password reset",
"parameters": [
{
"description": "Email address",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.ForgotPasswordRequest"
}
}
],
"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"
}
}
}
}
},
"/auth/login": {
"post": {
"description": "Authenticate user with email and password. Set remember_me to true for refresh token.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "User login",
"parameters": [
{
"description": "Login credentials",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.LoginRequest"
}
}
],
"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"
}
}
}
}
},
"/auth/refresh-token": {
"post": {
"description": "Get a new access token using a valid refresh token",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "Refresh access token",
"parameters": [
{
"description": "Refresh token",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.RefreshTokenRequest"
}
}
],
"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"
}
}
}
}
},
"/auth/register": {
"post": {
"description": "Create a new user account with name, email, and password",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "Register a new user",
"parameters": [
{
"description": "Registration details",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.RegisterRequest"
}
}
],
"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"
}
}
}
}
},
"/auth/resend-verification": {
"post": {
"description": "Resend email verification link. Always returns success for security.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "Resend verification email",
"parameters": [
{
"description": "Email address",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.ResendVerificationRequest"
}
}
],
"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"
}
}
}
}
},
"/auth/reset-password": {
"post": {
"description": "Complete password reset using token from email",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "Reset password",
"parameters": [
{
"description": "Reset token and new password",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.ResetPasswordRequest"
}
}
],
"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"
}
}
}
}
},
"/auth/revoke-token": {
"post": {
"description": "Invalidate a refresh token to logout from a specific session",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "Revoke refresh token",
"parameters": [
{
"description": "Refresh token to revoke",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.RevokeTokenRequest"
}
}
],
"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"
}
}
}
}
},
"/auth/verify-email": {
"get": {
"description": "Verify user's email using token from verification email",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "Verify email address",
"parameters": [
{
"type": "string",
"description": "Verification token from email",
"name": "token",
"in": "query",
"required": true
}
],
"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"
}
}
}
}
},
"/benchmark": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Execute the full benchmark suite to test database, serialization, and business logic performance",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"benchmark"
],
"summary": "Run benchmark suite",
"parameters": [
{
"type": "boolean",
"description": "Include concurrent operation tests (default: false)",
"name": "concurrent",
"in": "query"
},
{
"type": "boolean",
"description": "Skip cleanup after run if set to false (default: true)",
"name": "cleanup",
"in": "query"
},
{
"type": "integer",
"description": "Number of records to generate for benchmark testing (default: 1000, max: 500000)",
"name": "records",
"in": "query"
}
],
"responses": {
"200": {
"description": "Benchmark results",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/benchmark/status": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Quick status check for the benchmark system",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"benchmark"
],
"summary": "Get benchmark status",
"responses": {
"200": {
"description": "Benchmark status",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/data-change-logs": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get a paginated list of data change logs with optional filters",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "List data change logs (Admin)",
"parameters": [
{
"type": "string",
"description": "Filter by entity type",
"name": "entity_type",
"in": "query"
},
{
"type": "integer",
"description": "Filter by entity ID",
"name": "entity_id",
"in": "query"
},
{
"type": "string",
"description": "Filter by operation (create, update, delete)",
"name": "operation",
"in": "query"
},
{
"type": "integer",
"description": "Filter by user ID",
"name": "user_id",
"in": "query"
},
{
"type": "string",
"description": "Filter by user email",
"name": "user_email",
"in": "query"
},
{
"type": "string",
"description": "Filter by start date (RFC3339 or YYYY-MM-DD)",
"name": "start_date",
"in": "query"
},
{
"type": "string",
"description": "Filter by end date (RFC3339 or YYYY-MM-DD)",
"name": "end_date",
"in": "query"
},
{
"type": "integer",
"description": "Max results (default 50)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Skip N results (default 0)",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "Data change logs with total count",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/data-change-logs/entity/{entity_type}/{entity_id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get the change history for a specific entity",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Get entity history (Admin)",
"parameters": [
{
"type": "string",
"description": "Entity type (e.g., user, workout, wod)",
"name": "entity_type",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "Entity ID",
"name": "entity_id",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "Max results (default 50)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Skip N results (default 0)",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "Entity change history",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/data-change-logs/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve a specific data change log entry by ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Get data change log (Admin)",
"parameters": [
{
"type": "integer",
"description": "Data Change Log ID",
"name": "id",
"in": "path",
"required": true
}
],
"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"
}
}
}
}
},
"/export/movements": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Export movements to CSV or JSON format with optional filters",
"consumes": [
"application/json"
],
"produces": [
"text/csv",
"application/json"
],
"tags": [
"import-export"
],
"summary": "Export movements",
"parameters": [
{
"type": "boolean",
"description": "Include standard movements (default true)",
"name": "include_standard",
"in": "query"
},
{
"type": "boolean",
"description": "Include custom movements (default true)",
"name": "include_custom",
"in": "query"
},
{
"type": "string",
"description": "Export format: csv or json (default csv)",
"name": "format",
"in": "query"
}
],
"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"
}
}
}
}
},
"/export/user-workouts": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Export user's logged workouts to CSV or JSON format with optional date range",
"consumes": [
"application/json"
],
"produces": [
"text/csv",
"application/json"
],
"tags": [
"import-export"
],
"summary": "Export user workouts",
"parameters": [
{
"type": "string",
"description": "Start date (YYYY-MM-DD)",
"name": "start_date",
"in": "query"
},
{
"type": "string",
"description": "End date (YYYY-MM-DD)",
"name": "end_date",
"in": "query"
},
{
"type": "string",
"description": "Export format: csv or json (default json)",
"name": "format",
"in": "query"
}
],
"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"
}
}
}
}
},
"/export/wods": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Export WODs to CSV or JSON format with optional filters",
"consumes": [
"application/json"
],
"produces": [
"text/csv",
"application/json"
],
"tags": [
"import-export"
],
"summary": "Export WODs",
"parameters": [
{
"type": "boolean",
"description": "Include standard WODs (default true)",
"name": "include_standard",
"in": "query"
},
{
"type": "boolean",
"description": "Include custom WODs (default true)",
"name": "include_custom",
"in": "query"
},
{
"type": "string",
"description": "Export format: csv or json (default csv)",
"name": "format",
"in": "query"
}
],
"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"
}
}
}
}
},
"/import/movements/confirm": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Execute movement CSV import after preview",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"import-export"
],
"summary": "Confirm movement import",
"parameters": [
{
"type": "file",
"description": "CSV file to import",
"name": "file",
"in": "formData",
"required": true
},
{
"type": "boolean",
"description": "Skip duplicate entries",
"name": "skip_duplicates",
"in": "formData"
},
{
"type": "boolean",
"description": "Update existing duplicates",
"name": "update_duplicates",
"in": "formData"
}
],
"responses": {
"200": {
"description": "Import results with counts",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/import/movements/preview": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Validate and preview movement CSV import before confirming",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"import-export"
],
"summary": "Preview movement import",
"parameters": [
{
"type": "file",
"description": "CSV file to import",
"name": "file",
"in": "formData",
"required": true
}
],
"responses": {
"200": {
"description": "Import preview with validation results",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Invalid file or validation failed",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/import/user-workouts/confirm": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Execute user workout JSON import after preview",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"import-export"
],
"summary": "Confirm user workout import",
"parameters": [
{
"type": "file",
"description": "JSON file to import",
"name": "file",
"in": "formData",
"required": true
},
{
"type": "boolean",
"description": "Skip duplicate entries",
"name": "skip_duplicates",
"in": "formData"
},
{
"type": "boolean",
"description": "Update existing duplicates",
"name": "update_duplicates",
"in": "formData"
}
],
"responses": {
"200": {
"description": "Import results with counts",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/import/user-workouts/preview": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Validate and preview user workout JSON import before confirming",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"import-export"
],
"summary": "Preview user workout import",
"parameters": [
{
"type": "file",
"description": "JSON file to import",
"name": "file",
"in": "formData",
"required": true
}
],
"responses": {
"200": {
"description": "Import preview with validation results",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Invalid file or validation failed",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/import/wodify/confirm": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Execute Wodify performance data import after preview",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"import-export"
],
"summary": "Confirm Wodify import",
"parameters": [
{
"type": "file",
"description": "Wodify export file",
"name": "file",
"in": "formData",
"required": true
},
{
"type": "boolean",
"description": "Skip duplicate entries",
"name": "skip_duplicates",
"in": "formData"
},
{
"type": "boolean",
"description": "Update existing duplicates",
"name": "update_duplicates",
"in": "formData"
}
],
"responses": {
"200": {
"description": "Import results with counts",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/import/wodify/preview": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Validate and preview Wodify performance data import before confirming",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"import-export"
],
"summary": "Preview Wodify import",
"parameters": [
{
"type": "file",
"description": "Wodify export file",
"name": "file",
"in": "formData",
"required": true
}
],
"responses": {
"200": {
"description": "Import preview with validation results",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/import/wods/confirm": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Execute WOD CSV import after preview",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"import-export"
],
"summary": "Confirm WOD import",
"parameters": [
{
"type": "file",
"description": "CSV file to import",
"name": "file",
"in": "formData",
"required": true
},
{
"type": "boolean",
"description": "Skip duplicate entries",
"name": "skip_duplicates",
"in": "formData"
},
{
"type": "boolean",
"description": "Update existing duplicates",
"name": "update_duplicates",
"in": "formData"
}
],
"responses": {
"200": {
"description": "Import results with counts",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/import/wods/preview": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Validate and preview WOD CSV import before confirming",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"import-export"
],
"summary": "Preview WOD import",
"parameters": [
{
"type": "file",
"description": "CSV file to import",
"name": "file",
"in": "formData",
"required": true
}
],
"responses": {
"200": {
"description": "Import preview with validation results",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Invalid file or validation failed",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/movements": {
"get": {
"description": "Retrieve all movements including standard and custom",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"movements"
],
"summary": "List all movements",
"responses": {
"200": {
"description": "List of all movements",
"schema": {
"$ref": "#/definitions/internal_handler.MovementListResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Create a new custom movement (non-standard)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"movements"
],
"summary": "Create a custom movement",
"parameters": [
{
"description": "Movement details",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.CreateMovementRequest"
}
}
],
"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"
}
}
}
}
},
"/movements/search": {
"get": {
"description": "Search for movements by name",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"movements"
],
"summary": "Search movements",
"parameters": [
{
"type": "string",
"description": "Search query",
"name": "q",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Max results (default 20)",
"name": "limit",
"in": "query"
}
],
"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"
}
}
}
}
},
"/movements/standard": {
"get": {
"description": "Retrieve only standard (built-in) movements",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"movements"
],
"summary": "List standard movements",
"responses": {
"200": {
"description": "List of standard movements",
"schema": {
"$ref": "#/definitions/internal_handler.MovementListResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/movements/{id}": {
"get": {
"description": "Retrieve a single movement by its ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"movements"
],
"summary": "Get movement by ID",
"parameters": [
{
"type": "integer",
"description": "Movement ID",
"name": "id",
"in": "path",
"required": true
}
],
"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"
}
}
}
},
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Update an existing movement (admin can update any, users only custom)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"movements"
],
"summary": "Update a movement",
"parameters": [
{
"type": "integer",
"description": "Movement ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Updated movement details",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.CreateMovementRequest"
}
}
],
"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"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Delete a custom movement (cannot delete standard movements)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"movements"
],
"summary": "Delete a movement",
"parameters": [
{
"type": "integer",
"description": "Movement ID",
"name": "id",
"in": "path",
"required": true
}
],
"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"
}
}
}
}
},
"/notifications": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve all notifications for the authenticated user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"notifications"
],
"summary": "List notifications",
"parameters": [
{
"type": "integer",
"description": "Max results (default 20, max 100)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Skip N results (default 0)",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "List of notifications",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/notifications/count": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get the count of unread notifications (for badge display)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"notifications"
],
"summary": "Get unread notification count",
"responses": {
"200": {
"description": "Unread count",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/notifications/read-all": {
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Mark all notifications for the user as read",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"notifications"
],
"summary": "Mark all notifications as read",
"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"
}
}
}
}
},
"/notifications/unread": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve only unread notifications for the authenticated user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"notifications"
],
"summary": "List unread notifications",
"parameters": [
{
"type": "integer",
"description": "Max results (default 20, max 100)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Skip N results (default 0)",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "List of unread notifications",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/notifications/{id}": {
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Delete a specific notification",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"notifications"
],
"summary": "Delete notification",
"parameters": [
{
"type": "integer",
"description": "Notification ID",
"name": "id",
"in": "path",
"required": true
}
],
"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"
}
}
}
}
},
"/notifications/{id}/like": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Like a notification (e.g., PR announcement)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"notifications"
],
"summary": "Like notification",
"parameters": [
{
"type": "integer",
"description": "Notification ID",
"name": "id",
"in": "path",
"required": true
}
],
"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"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Remove like from a notification",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"notifications"
],
"summary": "Unlike notification",
"parameters": [
{
"type": "integer",
"description": "Notification ID",
"name": "id",
"in": "path",
"required": true
}
],
"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"
}
}
}
}
},
"/notifications/{id}/likes": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get all likes for a notification",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"notifications"
],
"summary": "Get notification likes",
"parameters": [
{
"type": "integer",
"description": "Notification ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Likes list with count",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Invalid notification ID",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/notifications/{id}/read": {
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Mark a specific notification as read",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"notifications"
],
"summary": "Mark notification as read",
"parameters": [
{
"type": "integer",
"description": "Notification ID",
"name": "id",
"in": "path",
"required": true
}
],
"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"
}
}
}
}
},
"/performance/movements/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve all performance records for a movement with calculated 1RM values",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"performance"
],
"summary": "Get movement performance history",
"parameters": [
{
"type": "integer",
"description": "Movement ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Performance history with best 1RM",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/performance/search": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Search across both movements and WODs in a single query",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"performance"
],
"summary": "Unified search for movements and WODs",
"parameters": [
{
"type": "string",
"description": "Search query",
"name": "q",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Max results per category (default 10)",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "Combined search results",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/performance/wods/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve all performance records for a specific WOD",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"performance"
],
"summary": "Get WOD performance history",
"parameters": [
{
"type": "integer",
"description": "WOD ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "WOD performance history",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/prs": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve all personal records (PRs) for movements and WODs",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"prs"
],
"summary": "Get all personal records",
"parameters": [
{
"type": "integer",
"description": "Max results (default 50, max 200)",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "List of personal records",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/prs/movements": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve movements that have personal records with summary stats",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"prs"
],
"summary": "Get movements with PRs",
"parameters": [
{
"type": "integer",
"description": "Max results (default 20, max 100)",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "Movement PR summaries",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/prs/toggle": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Toggle the personal record flag on a specific workout movement",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"prs"
],
"summary": "Toggle movement PR flag",
"parameters": [
{
"type": "integer",
"description": "Workout movement ID",
"name": "id",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "New PR state",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/sessions": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get all active sessions for the current user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"sessions"
],
"summary": "List active sessions",
"responses": {
"200": {
"description": "List of active sessions",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/sessions/revoke-all": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Revoke all sessions for the current user (log out everywhere)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"sessions"
],
"summary": "Revoke all sessions",
"parameters": [
{
"description": "Options (except_current_session)",
"name": "request",
"in": "body",
"schema": {
"type": "object"
}
}
],
"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"
}
}
}
}
},
"/sessions/{id}": {
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Revoke a specific session (log out that device)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"sessions"
],
"summary": "Revoke session",
"parameters": [
{
"type": "integer",
"description": "Session ID",
"name": "id",
"in": "path",
"required": true
}
],
"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"
}
}
}
}
},
"/settings": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve the current user's settings",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"users"
],
"summary": "Get user settings",
"responses": {
"200": {
"description": "User settings",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
},
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Update the current user's settings",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"users"
],
"summary": "Update user settings",
"parameters": [
{
"description": "Updated settings",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/github_com_johnzastrow_actalog_internal_domain.UserSettings"
}
}
],
"responses": {
"200": {
"description": "Updated settings",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/stats/active-users-this-month": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve stats about active users who have logged workouts this month",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"workouts"
],
"summary": "Get active users this month",
"responses": {
"200": {
"description": "Active users stats",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/subscriptions/my-status": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get the current user's subscription status and plan details",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"subscriptions"
],
"summary": "Get my subscription status",
"responses": {
"200": {
"description": "Subscription status",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/templates": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get all standard (system-provided) workout templates",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"templates"
],
"summary": "List standard workout templates",
"parameters": [
{
"type": "integer",
"description": "Max results (default 100)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Skip N results (default 0)",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "List of standard templates",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Create a new reusable workout template with movements and WODs",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"templates"
],
"summary": "Create workout template",
"parameters": [
{
"description": "Template details with movements and WODs",
"name": "request",
"in": "body",
"required": true,
"schema": {
"type": "object"
}
}
],
"responses": {
"201": {
"description": "Created template",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/templates/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve a specific workout template by ID with full details",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"templates"
],
"summary": "Get workout template",
"parameters": [
{
"type": "integer",
"description": "Template ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Template details",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Invalid template ID",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"404": {
"description": "Template not found",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
},
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Update an existing workout template (owner only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"templates"
],
"summary": "Update workout template",
"parameters": [
{
"type": "integer",
"description": "Template ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Updated template details",
"name": "request",
"in": "body",
"required": true,
"schema": {
"type": "object"
}
}
],
"responses": {
"200": {
"description": "Updated template",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Delete a workout template (owner only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"templates"
],
"summary": "Delete workout template",
"parameters": [
{
"type": "integer",
"description": "Template ID",
"name": "id",
"in": "path",
"required": true
}
],
"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"
}
}
}
}
},
"/users/avatar": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Upload a new avatar image for the authenticated user (max 5MB)",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"users"
],
"summary": "Upload avatar image",
"parameters": [
{
"type": "file",
"description": "Avatar image file",
"name": "avatar",
"in": "formData",
"required": true
}
],
"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"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Remove the authenticated user's avatar image",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"users"
],
"summary": "Delete avatar image",
"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"
}
}
}
}
},
"/users/change-password": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Change the authenticated user's password",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"users"
],
"summary": "Change password",
"parameters": [
{
"description": "Current and new password",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.ChangePasswordRequest"
}
}
],
"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"
}
}
}
}
},
"/users/me/audit-logs": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get audit logs for the current user only",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"audit"
],
"summary": "Get my audit logs",
"parameters": [
{
"type": "integer",
"description": "Max results (default 50)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Skip N results (default 0)",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "User's audit logs with total count",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/users/profile": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve the authenticated user's profile information",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"users"
],
"summary": "Get user profile",
"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"
}
}
}
},
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Update the authenticated user's profile information",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"users"
],
"summary": "Update user profile",
"parameters": [
{
"description": "Profile updates",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.UpdateProfileRequest"
}
}
],
"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"
}
}
}
}
},
"/wods": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve all WODs including standard and user's custom WODs",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"wods"
],
"summary": "List all WODs",
"parameters": [
{
"type": "integer",
"description": "Max results (default 100)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Skip N results (default 0)",
"name": "offset",
"in": "query"
},
{
"type": "boolean",
"description": "Return only standard WODs",
"name": "standard",
"in": "query"
}
],
"responses": {
"200": {
"description": "List of WODs",
"schema": {
"$ref": "#/definitions/internal_handler.WODListResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Create a new custom WOD (Workout of the Day)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"wods"
],
"summary": "Create a custom WOD",
"parameters": [
{
"description": "WOD details",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.CreateWODRequest"
}
}
],
"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"
}
}
}
}
},
"/wods/mine": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve only the authenticated user's custom WODs",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"wods"
],
"summary": "List my custom WODs",
"parameters": [
{
"type": "integer",
"description": "Max results (default 100)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Skip N results (default 0)",
"name": "offset",
"in": "query"
}
],
"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"
}
}
}
}
},
"/wods/search": {
"get": {
"description": "Search for WODs by name",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"wods"
],
"summary": "Search WODs",
"parameters": [
{
"type": "string",
"description": "Search query",
"name": "q",
"in": "query",
"required": true
}
],
"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"
}
}
}
}
},
"/wods/standard": {
"get": {
"description": "Retrieve only standard (built-in) WODs",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"wods"
],
"summary": "List standard WODs",
"parameters": [
{
"type": "integer",
"description": "Max results (default 100)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Skip N results (default 0)",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "List of standard WODs",
"schema": {
"$ref": "#/definitions/internal_handler.WODListResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/wods/{id}": {
"get": {
"description": "Retrieve a single WOD by its ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"wods"
],
"summary": "Get WOD by ID",
"parameters": [
{
"type": "integer",
"description": "WOD ID",
"name": "id",
"in": "path",
"required": true
}
],
"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"
}
}
}
},
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Update an existing WOD (admin can update any, users only their own custom WODs)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"wods"
],
"summary": "Update a WOD",
"parameters": [
{
"type": "integer",
"description": "WOD ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Updated WOD details",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.UpdateWODRequest"
}
}
],
"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"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Delete a custom WOD (cannot delete standard WODs)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"wods"
],
"summary": "Delete a WOD",
"parameters": [
{
"type": "integer",
"description": "WOD ID",
"name": "id",
"in": "path",
"required": true
}
],
"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"
}
}
}
}
},
"/workouts": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve all logged workouts for the user with pagination and optional date filtering",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"workouts"
],
"summary": "List logged workouts",
"parameters": [
{
"type": "integer",
"description": "Max results (default 20)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Skip N results (default 0)",
"name": "offset",
"in": "query"
},
{
"type": "string",
"description": "Filter start date (YYYY-MM-DD)",
"name": "start_date",
"in": "query"
},
{
"type": "string",
"description": "Filter end date (YYYY-MM-DD)",
"name": "end_date",
"in": "query"
}
],
"responses": {
"200": {
"description": "List of workouts with pagination",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Record a workout with performance data. Can be based on a template or ad-hoc.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"workouts"
],
"summary": "Log a workout",
"parameters": [
{
"description": "Workout data with optional performance",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.LogWorkoutRequest"
}
}
],
"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"
}
}
}
}
},
"/workouts/my-templates": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get all workout templates created by the current user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"templates"
],
"summary": "List my workout templates",
"parameters": [
{
"type": "integer",
"description": "Max results (default 100)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Skip N results (default 0)",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "List of user's templates",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/workouts/personal-records": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve all personal records for movements and WODs",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"workouts"
],
"summary": "Get personal records",
"parameters": [
{
"type": "integer",
"description": "Max results per category (default 50)",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "PR movements and PR WODs",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/workouts/retroactive-prs": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Analyze all existing workouts and flag personal records based on historical data",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"workouts"
],
"summary": "Retroactively flag PRs",
"responses": {
"200": {
"description": "Count of flagged PRs",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handler.ErrorResponse"
}
}
}
}
},
"/workouts/stats/monthly": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve the workout count for a specific month",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"workouts"
],
"summary": "Get monthly workout stats",
"parameters": [
{
"type": "integer",
"description": "Year (e.g., 2024)",
"name": "year",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Month (1-12)",
"name": "month",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "Monthly stats with workout count",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"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"
}
}
}
}
},
"/workouts/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve a specific logged workout by ID with all performance data",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"workouts"
],
"summary": "Get a logged workout",
"parameters": [
{
"type": "integer",
"description": "Logged workout ID",
"name": "id",
"in": "path",
"required": true
}
],
"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"
}
}
}
},
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Update an existing logged workout's details and performance data",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"workouts"
],
"summary": "Update a logged workout",
"parameters": [
{
"type": "integer",
"description": "Logged workout ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Updated workout data",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handler.UpdateLoggedWorkoutRequest"
}
}
],
"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"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Delete a specific logged workout and all its performance data",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"workouts"
],
"summary": "Delete a logged workout",
"parameters": [
{
"type": "integer",
"description": "Logged workout ID",
"name": "id",
"in": "path",
"required": true
}
],
"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"
}
}
}
}
},
"/coaches/me/sessions": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get upcoming sessions for the authenticated coach. Admins see all sessions across all gyms; coaches see only their assigned sessions.",
"produces": [
"application/json"
],
"tags": [
"coaches"
],
"summary": "Get coach's upcoming sessions",
"parameters": [
{
"name": "limit",
"in": "query",
"type": "integer",
"description": "Max sessions to return (default 20)",
"required": false
}
],
"responses": {
"200": {
"description": "List of upcoming sessions with count"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/coaches/sessions/{session_id}/roster": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get the roster of reservations for a session. Coach must be assigned to the session's organization.",
"produces": [
"application/json"
],
"tags": [
"coaches"
],
"summary": "Get session roster",
"parameters": [
{
"name": "session_id",
"in": "path",
"type": "integer",
"description": "Session ID",
"required": true
}
],
"responses": {
"200": {
"description": "Session roster with reservations"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal server error"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not found"
}
}
}
},
"/coaches/sessions/{session_id}/check-in/{reservation_id}": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Check in an athlete's reservation. Coach must be assigned to the session's organization.",
"produces": [
"application/json"
],
"tags": [
"coaches"
],
"summary": "Check in reservation",
"parameters": [
{
"name": "session_id",
"in": "path",
"type": "integer",
"description": "Session ID",
"required": true
},
{
"name": "reservation_id",
"in": "path",
"type": "integer",
"description": "Reservation ID",
"required": true
}
],
"responses": {
"200": {
"description": "Reservation checked in"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal server error"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not found"
}
}
}
},
"/coaches/sessions/{session_id}/no-show/{reservation_id}": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Mark a reservation as no-show. Coach must be assigned to the session's organization.",
"produces": [
"application/json"
],
"tags": [
"coaches"
],
"summary": "Mark reservation as no-show",
"parameters": [
{
"name": "session_id",
"in": "path",
"type": "integer",
"description": "Session ID",
"required": true
},
{
"name": "reservation_id",
"in": "path",
"type": "integer",
"description": "Reservation ID",
"required": true
}
],
"responses": {
"200": {
"description": "Reservation marked as no-show"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal server error"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not found"
}
}
}
},
"/coaches/sessions/{session_id}/complete": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Mark a session as completed. Coach must be assigned to the session's organization.",
"produces": [
"application/json"
],
"tags": [
"coaches"
],
"summary": "Complete session",
"parameters": [
{
"name": "session_id",
"in": "path",
"type": "integer",
"description": "Session ID",
"required": true
}
],
"responses": {
"200": {
"description": "Session marked as completed"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal server error"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not found"
}
}
}
},
"/gyms/{gym_id}/sessions": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "List upcoming class sessions for a gym",
"produces": [
"application/json"
],
"tags": [
"scheduling"
],
"summary": "List gym sessions",
"parameters": [
{
"name": "gym_id",
"in": "path",
"type": "integer",
"description": "Organization/Gym ID",
"required": true
}
],
"responses": {
"200": {
"description": "List of sessions"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/gyms/{gym_id}/sessions/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get details of a specific class session",
"produces": [
"application/json"
],
"tags": [
"scheduling"
],
"summary": "Get session details",
"parameters": [
{
"name": "gym_id",
"in": "path",
"type": "integer",
"description": "Organization/Gym ID",
"required": true
},
{
"name": "id",
"in": "path",
"type": "integer",
"description": "Session ID",
"required": true
}
],
"responses": {
"200": {
"description": "Session details"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal server error"
},
"404": {
"description": "Not found"
}
}
}
},
"/gyms/{gym_id}/locations": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "List locations for a gym",
"produces": [
"application/json"
],
"tags": [
"scheduling"
],
"summary": "List gym locations",
"parameters": [
{
"name": "gym_id",
"in": "path",
"type": "integer",
"description": "Organization/Gym ID",
"required": true
}
],
"responses": {
"200": {
"description": "List of locations"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/gyms/{gym_id}/locations/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get details of a specific gym location",
"produces": [
"application/json"
],
"tags": [
"scheduling"
],
"summary": "Get location details",
"parameters": [
{
"name": "gym_id",
"in": "path",
"type": "integer",
"description": "Organization/Gym ID",
"required": true
},
{
"name": "id",
"in": "path",
"type": "integer",
"description": "Location ID",
"required": true
}
],
"responses": {
"200": {
"description": "Location details"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal server error"
},
"404": {
"description": "Not found"
}
}
}
},
"/gyms/{gym_id}/templates": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "List class templates for a gym",
"produces": [
"application/json"
],
"tags": [
"scheduling"
],
"summary": "List class templates",
"parameters": [
{
"name": "gym_id",
"in": "path",
"type": "integer",
"description": "Organization/Gym ID",
"required": true
}
],
"responses": {
"200": {
"description": "List of class templates"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/gyms/{gym_id}/documents": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "List required documents for a gym (waivers, liability forms, etc.)",
"produces": [
"application/json"
],
"tags": [
"scheduling"
],
"summary": "List gym documents",
"parameters": [
{
"name": "gym_id",
"in": "path",
"type": "integer",
"description": "Organization/Gym ID",
"required": true
}
],
"responses": {
"200": {
"description": "List of documents"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/gyms/{gym_id}/documents/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get details of a specific document",
"produces": [
"application/json"
],
"tags": [
"scheduling"
],
"summary": "Get document details",
"parameters": [
{
"name": "gym_id",
"in": "path",
"type": "integer",
"description": "Organization/Gym ID",
"required": true
},
{
"name": "id",
"in": "path",
"type": "integer",
"description": "Document ID",
"required": true
}
],
"responses": {
"200": {
"description": "Document details"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal server error"
},
"404": {
"description": "Not found"
}
}
}
},
"/gyms/{gym_id}/packages": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "List class packages available at a gym",
"produces": [
"application/json"
],
"tags": [
"scheduling"
],
"summary": "List class packages",
"parameters": [
{
"name": "gym_id",
"in": "path",
"type": "integer",
"description": "Organization/Gym ID",
"required": true
}
],
"responses": {
"200": {
"description": "List of class packages"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/gyms/{gym_id}/packages/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get details of a specific class package",
"produces": [
"application/json"
],
"tags": [
"scheduling"
],
"summary": "Get class package details",
"parameters": [
{
"name": "gym_id",
"in": "path",
"type": "integer",
"description": "Organization/Gym ID",
"required": true
},
{
"name": "id",
"in": "path",
"type": "integer",
"description": "Package ID",
"required": true
}
],
"responses": {
"200": {
"description": "Package details"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal server error"
},
"404": {
"description": "Not found"
}
}
}
},
"/gyms/{gym_id}/users/me/documents": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get the authenticated user's document completion status for a gym",
"produces": [
"application/json"
],
"tags": [
"scheduling"
],
"summary": "Get user's gym documents",
"parameters": [
{
"name": "gym_id",
"in": "path",
"type": "integer",
"description": "Organization/Gym ID",
"required": true
}
],
"responses": {
"200": {
"description": "List of user document statuses"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/gyms/{gym_id}/users/me/documents/pending": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get the authenticated user's pending (incomplete) documents for a gym",
"produces": [
"application/json"
],
"tags": [
"scheduling"
],
"summary": "Get user's pending documents",
"parameters": [
{
"name": "gym_id",
"in": "path",
"type": "integer",
"description": "Organization/Gym ID",
"required": true
}
],
"responses": {
"200": {
"description": "List of pending documents"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/gyms/{gym_id}/users/me/credits": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get the authenticated user's class credits for a gym",
"produces": [
"application/json"
],
"tags": [
"scheduling"
],
"summary": "Get user's credits",
"parameters": [
{
"name": "gym_id",
"in": "path",
"type": "integer",
"description": "Organization/Gym ID",
"required": true
}
],
"responses": {
"200": {
"description": "User credit records"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/gyms/{gym_id}/users/me/credits/available": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get available (non-expired) credit count for the authenticated user at a gym",
"produces": [
"application/json"
],
"tags": [
"scheduling"
],
"summary": "Get user's available credits",
"parameters": [
{
"name": "gym_id",
"in": "path",
"type": "integer",
"description": "Organization/Gym ID",
"required": true
}
],
"responses": {
"200": {
"description": "Available credit count"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/users/me/reservations/upcoming": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get the authenticated user's upcoming rese