// Package docs Code generated by swaggo/swag. DO NOT EDIT package docs import "github.com/swaggo/swag" const docTemplate = `{ "schemes": {{ marshal .Schemes }}, "swagger": "2.0", "info": { "description": "{{escape .Description}}", "title": "{{.Title}}", "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": "{{.Version}}" }, "host": "{{.Host}}", "basePath": "{{.BasePath}}", "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" } } } } } }, "definitions": { "github_com_johnzastrow_actalog_internal_domain.AuditLog": { "type": "object", "properties": { "created_at": { "type": "string" }, "details": { "description": "JSON string", "type": "string" }, "event_type": { "type": "string" }, "id": { "type": "integer" }, "ip_address": { "type": "string" }, "target_user_email": { "description": "Email of affected user", "type": "string" }, "target_user_id": { "description": "User affected by the action", "type": "integer" }, "user_agent": { "type": "string" }, "user_email": { "description": "These fields are populated via JOIN queries and are not in the audit_logs table", "type": "string" }, "user_id": { "description": "User who performed the action (NULL for system)", "type": "integer" } } }, "github_com_johnzastrow_actalog_internal_domain.BackupMetadata": { "type": "object", "properties": { "created_at": { "type": "string" }, "created_by_email": { "type": "string" }, "database_driver": { "type": "string" }, "database_name": { "type": "string" }, "file_size": { "description": "Size in bytes", "type": "integer" }, "filename": { "type": "string" }, "total_movements": { "type": "integer" }, "total_users": { "type": "integer" }, "total_wods": { "type": "integer" }, "total_workouts": { "type": "integer" }, "version": { "type": "string" } } }, "github_com_johnzastrow_actalog_internal_domain.DataChangeLog": { "type": "object", "properties": { "after_values": { "description": "JSON of record after change (NULL for deletes)", "type": "string" }, "before_values": { "description": "JSON of record before change", "type": "string" }, "created_at": { "type": "string" }, "entity_id": { "description": "ID of the record that was changed", "type": "integer" }, "entity_name": { "description": "Human-readable name (e.g., WOD name, movement name)", "type": "string" }, "entity_type": { "description": "wod, movement, workout, user_workout, etc.", "type": "string" }, "id": { "type": "integer" }, "ip_address": { "type": "string" }, "operation": { "description": "update, delete", "type": "string" }, "user_agent": { "type": "string" }, "user_email": { "description": "Email for display (denormalized)", "type": "string" }, "user_id": { "description": "User who made the change", "type": "integer" } } }, "github_com_johnzastrow_actalog_internal_domain.Movement": { "type": "object", "properties": { "created_at": { "type": "string" }, "created_by": { "description": "User ID if custom", "type": "integer" }, "description": { "type": "string" }, "id": { "type": "integer" }, "is_standard": { "description": "True for predefined movements", "type": "boolean" }, "name": { "type": "string" }, "type": { "$ref": "#/definitions/github_com_johnzastrow_actalog_internal_domain.MovementType" }, "updated_at": { "type": "string" } } }, "github_com_johnzastrow_actalog_internal_domain.MovementType": { "type": "string", "enum": [ "weightlifting", "bodyweight", "cardio", "gymnastics" ], "x-enum-varnames": [ "MovementTypeWeightlifting", "MovementTypeBodyweight", "MovementTypeCardio", "MovementTypeGymnastics" ] }, "github_com_johnzastrow_actalog_internal_domain.UserSettings": { "type": "object", "properties": { "admin_user_event_notifications": { "description": "Admins: receive user event emails", "type": "boolean" }, "created_at": { "type": "string" }, "data_export_format": { "description": "JSON, CSV", "type": "string" }, "distance_unit": { "description": "miles, km", "type": "string" }, "font_family": { "description": "system, inter, roboto, lato, firasans, lexend, opendyslexic, atkinson, sourceserif, jetbrainsmono", "type": "string" }, "id": { "type": "integer" }, "notification_preferences": { "description": "JSON format", "type": "string" }, "theme": { "description": "light, dark", "type": "string" }, "timezone": { "description": "IANA timezone identifier", "type": "string" }, "updated_at": { "type": "string" }, "user_id": { "type": "integer" }, "weight_unit": { "description": "lbs, kg", "type": "string" } } }, "github_com_johnzastrow_actalog_internal_domain.UserWorkoutMovement": { "type": "object", "properties": { "created_at": { "type": "string" }, "distance": { "description": "in meters or miles", "type": "number" }, "id": { "type": "integer" }, "is_pr": { "description": "Personal record flag", "type": "boolean" }, "movement": { "description": "Related data (loaded via joins)", "allOf": [ { "$ref": "#/definitions/github_com_johnzastrow_actalog_internal_domain.Movement" } ] }, "movement_id": { "description": "References movements table", "type": "integer" }, "movement_name": { "description": "Flattened for convenience", "type": "string" }, "movement_type": { "description": "Flattened for convenience", "type": "string" }, "notes": { "type": "string" }, "order_index": { "description": "Order in the workout", "type": "integer" }, "reps": { "type": "integer" }, "sets": { "type": "integer" }, "time_seconds": { "description": "in seconds", "type": "integer" }, "updated_at": { "type": "string" }, "user_workout_id": { "description": "References user_workouts (logged workout instance)", "type": "integer" }, "weight": { "description": "in lbs or kg", "type": "number" }, "workout_date": { "description": "From user_workouts.workout_date", "type": "string" } } }, "github_com_johnzastrow_actalog_internal_domain.UserWorkoutWOD": { "type": "object", "properties": { "created_at": { "type": "string" }, "id": { "type": "integer" }, "is_pr": { "description": "Personal record flag", "type": "boolean" }, "notes": { "type": "string" }, "order_index": { "description": "Order in the workout", "type": "integer" }, "reps": { "description": "Remaining reps in AMRAP", "type": "integer" }, "rounds": { "description": "For AMRAP WODs", "type": "integer" }, "score_type": { "description": "Time (HH:MM:SS), Rounds+Reps, Max Weight", "type": "string" }, "score_value": { "description": "Formatted score (e.g., \"12:34\", \"10+15\", \"225.5\")", "type": "string" }, "time_seconds": { "description": "For Time-based WODs", "type": "integer" }, "updated_at": { "type": "string" }, "user_workout_id": { "description": "References user_workouts (logged workout instance)", "type": "integer" }, "weight": { "description": "For Max Weight WODs", "type": "number" }, "wod": { "description": "Related data (loaded via joins)", "allOf": [ { "$ref": "#/definitions/github_com_johnzastrow_actalog_internal_domain.WOD" } ] }, "wod_id": { "description": "References wods table", "type": "integer" }, "wod_name": { "description": "Flattened for convenience", "type": "string" }, "wod_score_type": { "description": "WOD's defined score_type from wods table", "type": "string" }, "wod_type": { "description": "Flattened for convenience (Benchmark, Hero, Girl, etc.)", "type": "string" }, "workout_date": { "description": "From user_workouts.workout_date", "type": "string" } } }, "github_com_johnzastrow_actalog_internal_domain.WOD": { "type": "object", "properties": { "created_at": { "type": "string" }, "created_by": { "description": "User ID if custom WOD (NULL for standard)", "type": "integer" }, "description": { "description": "Full WOD description/instructions", "type": "string" }, "id": { "type": "integer" }, "is_standard": { "description": "TRUE for pre-seeded WODs, FALSE for user-created", "type": "boolean" }, "name": { "type": "string" }, "notes": { "description": "Additional notes", "type": "string" }, "regime": { "description": "EMOM, AMRAP, Fastest Time, Slowest Round, Get Stronger, Skills", "type": "string" }, "score_type": { "description": "Time (HH:MM:SS), Rounds+Reps, Max Weight", "type": "string" }, "source": { "description": "CrossFit, Other Coach, Self-recorded", "type": "string" }, "type": { "description": "Benchmark, Hero, Girl, Notables, Games, Endurance, Self-created", "type": "string" }, "updated_at": { "type": "string" }, "url": { "description": "Optional video or reference URL", "type": "string" } } }, "github_com_johnzastrow_actalog_internal_domain.Workout": { "type": "object", "properties": { "created_at": { "type": "string" }, "created_by": { "description": "User who created (NULL for standard templates)", "type": "integer" }, "id": { "type": "integer" }, "movements": { "description": "Related data (not stored directly in workout table, loaded via joins)", "type": "array", "items": { "$ref": "#/definitions/github_com_johnzastrow_actalog_internal_domain.WorkoutMovement" } }, "name": { "description": "Template name (e.g., \"Monday Strength\", \"Hero WOD\")", "type": "string" }, "notes": { "description": "General template notes/description", "type": "string" }, "updated_at": { "type": "string" }, "wods": { "description": "WODs in this template", "type": "array", "items": { "$ref": "#/definitions/github_com_johnzastrow_actalog_internal_domain.WorkoutWODWithDetails" } } } }, "github_com_johnzastrow_actalog_internal_domain.WorkoutMovement": { "type": "object", "properties": { "created_at": { "type": "string" }, "distance": { "description": "in meters or miles", "type": "number" }, "id": { "type": "integer" }, "is_pr": { "description": "Personal record flag", "type": "boolean" }, "is_rx": { "description": "Prescribed weight/standard", "type": "boolean" }, "movement": { "description": "Related data", "allOf": [ { "$ref": "#/definitions/github_com_johnzastrow_actalog_internal_domain.Movement" } ] }, "movement_id": { "description": "References movements table", "type": "integer" }, "notes": { "type": "string" }, "order_index": { "description": "Order in the workout", "type": "integer" }, "reps": { "type": "integer" }, "sets": { "type": "integer" }, "time": { "description": "in seconds", "type": "integer" }, "updated_at": { "type": "string" }, "weight": { "description": "in lbs or kg", "type": "number" }, "workout_id": { "description": "References workout template", "type": "integer" } } }, "github_com_johnzastrow_actalog_internal_domain.WorkoutWODWithDetails": { "type": "object", "properties": { "created_at": { "type": "string" }, "division": { "description": "rx, scaled, beginner", "type": "string" }, "id": { "type": "integer" }, "is_pr": { "description": "Personal record flag", "type": "boolean" }, "order_index": { "description": "Order in workout sequence", "type": "integer" }, "score_value": { "description": "Actual score when logged (time, rounds+reps, weight)", "type": "string" }, "updated_at": { "type": "string" }, "wod_description": { "type": "string" }, "wod_id": { "description": "References WOD", "type": "integer" }, "wod_name": { "type": "string" }, "wod_regime": { "type": "string" }, "wod_score_type": { "type": "string" }, "wod_type": { "type": "string" }, "workout_id": { "description": "References workout template", "type": "integer" } } }, "internal_handler.AuthResponse": { "description": "Authentication response containing JWT token and user info", "type": "object", "properties": { "refresh_token": { "type": "string", "example": "550e8400-e29b-41d4-a716-446655440000" }, "token": { "type": "string", "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." }, "user": {} } }, "internal_handler.CancelSubscriptionRequest": { "description": "Request to cancel a subscription", "type": "object", "properties": { "reason": { "type": "string", "example": "User requested cancellation" } } }, "internal_handler.ChangePasswordRequest": { "description": "Password change request", "type": "object", "properties": { "new_password": { "type": "string", "example": "newSecurePassword456" }, "old_password": { "type": "string", "example": "currentPassword123" } } }, "internal_handler.CopyToStandardRequest": { "type": "object", "properties": { "new_name": { "type": "string" } } }, "internal_handler.CreateAnnouncementRequest": { "description": "Admin announcement request", "type": "object", "properties": { "message": { "type": "string", "example": "Scheduled maintenance tonight" }, "organization_id": { "type": "integer" }, "target_ids": { "description": "org IDs or user IDs", "type": "array", "items": { "type": "integer" } }, "target_type": { "description": "\"all\", \"organization\", or \"users\"", "type": "string", "example": "all" }, "title": { "type": "string", "example": "System Update" } } }, "internal_handler.CreateMovementRequest": { "description": "Request to create a new custom movement", "type": "object", "properties": { "description": { "type": "string", "example": "A hip hinge movement using a kettlebell" }, "name": { "type": "string", "example": "Kettlebell Swing" }, "type": { "type": "string", "example": "strength" } } }, "internal_handler.CreateOrganizationSubscriptionRequest": { "description": "Request to create an organization subscription (admin only)", "type": "object", "properties": { "is_permanent_free": { "type": "boolean", "example": false }, "notes": { "type": "string", "example": "Enterprise plan" }, "organization_id": { "type": "integer", "example": 1 }, "subscription_type": { "type": "string", "example": "annual" } } }, "internal_handler.CreateUserSubscriptionRequest": { "description": "Request to create a user subscription (admin only)", "type": "object", "properties": { "is_permanent_free": { "type": "boolean", "example": false }, "notes": { "type": "string", "example": "Customer referral discount" }, "subscription_type": { "description": "\"free\", \"monthly\", \"annual\"", "type": "string", "example": "monthly" }, "user_id": { "type": "integer", "example": 1 } } }, "internal_handler.CreateWODRequest": { "description": "Request to create a new WOD", "type": "object", "properties": { "description": { "type": "string", "example": "15 min AMRAP of 10 KB swings, 15 box jumps" }, "name": { "type": "string", "example": "My Custom WOD" }, "notes": { "type": "string" }, "regime": { "type": "string", "example": "15 min" }, "score_type": { "type": "string", "example": "rounds+reps" }, "source": { "type": "string", "example": "custom" }, "type": { "type": "string", "example": "AMRAP" }, "url": { "type": "string" } } }, "internal_handler.ErrorResponse": { "description": "Error response returned when a request fails", "type": "object", "properties": { "error": { "type": "string", "example": "additional error details" }, "message": { "type": "string", "example": "Invalid credentials" } } }, "internal_handler.ForgotPasswordRequest": { "description": "Request to initiate password reset", "type": "object", "properties": { "email": { "type": "string", "example": "john@example.com" } } }, "internal_handler.LogWorkoutRequest": { "description": "Request to log a workout (either from template or ad-hoc)", "type": "object", "properties": { "movements": { "description": "Performance data", "type": "array", "items": { "$ref": "#/definitions/internal_handler.MovementPerformance" } }, "notes": { "type": "string", "example": "Felt strong today" }, "total_time": { "description": "Duration in seconds", "type": "integer", "example": 1200 }, "wods": { "type": "array", "items": { "$ref": "#/definitions/internal_handler.WODPerformance" } }, "workout_date": { "description": "YYYY-MM-DD format", "type": "string", "example": "2024-01-15" }, "workout_id": { "description": "Template ID (optional for ad-hoc workouts)", "type": "integer", "example": 1 }, "workout_name": { "description": "Name for ad-hoc workouts (required if workout_id is null)", "type": "string", "example": "Fran" }, "workout_type": { "type": "string", "example": "AMRAP" } } }, "internal_handler.LoginRequest": { "description": "User login request body", "type": "object", "properties": { "email": { "type": "string", "example": "john@example.com" }, "password": { "type": "string", "example": "securePassword123" }, "remember_me": { "type": "boolean", "example": true } } }, "internal_handler.MarkUserSubscriptionAsPaidRequest": { "description": "Request to mark a subscription as paid", "type": "object", "properties": { "duration_days": { "description": "Optional: custom duration in days", "type": "integer", "example": 30 }, "payment_date": { "description": "Optional: defaults to now", "type": "string", "example": "2024-01-15" } } }, "internal_handler.MessageResponse": { "description": "Generic message response", "type": "object", "properties": { "message": { "type": "string", "example": "Operation completed successfully" } } }, "internal_handler.MovementListResponse": { "description": "List of movements", "type": "object", "properties": { "movements": { "type": "array", "items": { "$ref": "#/definitions/github_com_johnzastrow_actalog_internal_domain.Movement" } } } }, "internal_handler.MovementPerformance": { "description": "Performance data recorded for a movement in a workout", "type": "object", "properties": { "distance": { "type": "number", "example": 1000 }, "movement_id": { "type": "integer", "example": 1 }, "notes": { "type": "string", "example": "Used belt" }, "order_index": { "type": "integer", "example": 0 }, "reps": { "type": "integer", "example": 10 }, "sets": { "type": "integer", "example": 5 }, "time": { "description": "in seconds", "type": "integer", "example": 300 }, "weight": { "type": "number", "example": 135.5 } } }, "internal_handler.ProfileResponse": { "description": "User profile data", "type": "object", "properties": { "user": {} } }, "internal_handler.RefreshTokenRequest": { "description": "Request to refresh access token", "type": "object", "properties": { "refresh_token": { "type": "string", "example": "550e8400-e29b-41d4-a716-446655440000" } } }, "internal_handler.RegisterRequest": { "description": "User registration request body", "type": "object", "properties": { "email": { "type": "string", "example": "john@example.com" }, "name": { "type": "string", "example": "John Doe" }, "password": { "type": "string", "example": "securePassword123" } } }, "internal_handler.ResendVerificationRequest": { "description": "Request to resend verification email", "type": "object", "properties": { "email": { "type": "string", "example": "john@example.com" } } }, "internal_handler.ResetPasswordRequest": { "description": "Request to complete password reset with token", "type": "object", "properties": { "new_password": { "type": "string", "example": "newSecurePassword123" }, "token": { "type": "string", "example": "abc123def456" } } }, "internal_handler.RevokeTokenRequest": { "description": "Request to revoke a refresh token (logout)", "type": "object", "properties": { "refresh_token": { "type": "string", "example": "550e8400-e29b-41d4-a716-446655440000" } } }, "internal_handler.SetUserSubscriptionPermanentRequest": { "description": "Request to set subscription permanent status", "type": "object", "properties": { "is_permanent": { "type": "boolean", "example": true } } }, "internal_handler.UpdateLoggedWorkoutRequest": { "description": "Request to update an existing logged workout", "type": "object", "properties": { "movements": { "type": "array", "items": { "$ref": "#/definitions/internal_handler.MovementPerformance" } }, "notes": { "type": "string", "example": "Updated notes" }, "total_time": { "type": "integer", "example": 900 }, "wods": { "type": "array", "items": { "$ref": "#/definitions/internal_handler.WODPerformance" } }, "workout_name": { "description": "For ad-hoc workouts", "type": "string", "example": "Custom WOD" }, "workout_type": { "type": "string", "example": "EMOM" } } }, "internal_handler.UpdateProfileRequest": { "description": "User profile update request", "type": "object", "properties": { "birthday": { "description": "Format: \"YYYY-MM-DD\" or empty", "type": "string", "example": "1990-05-15" }, "email": { "type": "string", "example": "john@example.com" }, "name": { "type": "string", "example": "John Doe" } } }, "internal_handler.UpdateWODRecordRequest": { "type": "object", "properties": { "notes": { "type": "string" }, "reps": { "type": "integer" }, "rounds": { "type": "integer" }, "time_seconds": { "type": "integer" }, "weight": { "type": "number" } } }, "internal_handler.UpdateWODRequest": { "description": "Request to update an existing WOD", "type": "object", "properties": { "description": { "type": "string", "example": "21-15-9 thrusters and pull-ups" }, "name": { "type": "string", "example": "Updated WOD Name" }, "notes": { "type": "string" }, "regime": { "type": "string", "example": "21-15-9" }, "score_type": { "type": "string", "example": "time" }, "source": { "type": "string", "example": "custom" }, "type": { "type": "string", "example": "For Time" }, "url": { "type": "string" } } }, "internal_handler.UserWorkoutResponse": { "description": "Complete logged workout with performance data", "type": "object", "properties": { "created_at": { "type": "string", "example": "2024-01-15T10:30:00Z" }, "id": { "type": "integer", "example": 1 }, "movements": { "description": "Template movements", "type": "array", "items": { "$ref": "#/definitions/github_com_johnzastrow_actalog_internal_domain.WorkoutMovement" } }, "notes": { "type": "string", "example": "Felt great" }, "performance_movements": { "description": "Actual performance", "type": "array", "items": { "$ref": "#/definitions/github_com_johnzastrow_actalog_internal_domain.UserWorkoutMovement" } }, "performance_wods": { "description": "Actual performance", "type": "array", "items": { "$ref": "#/definitions/github_com_johnzastrow_actalog_internal_domain.UserWorkoutWOD" } }, "total_time": { "type": "integer", "example": 1200 }, "updated_at": { "type": "string", "example": "2024-01-15T10:30:00Z" }, "user_id": { "type": "integer", "example": 1 }, "wods": { "description": "Template WODs", "type": "array", "items": { "$ref": "#/definitions/github_com_johnzastrow_actalog_internal_domain.WorkoutWODWithDetails" } }, "workout_date": { "type": "string", "example": "2024-01-15" }, "workout_id": { "description": "Nullable for ad-hoc workouts", "type": "integer", "example": 1 }, "workout_name": { "type": "string", "example": "Fran" }, "workout_notes": { "type": "string", "example": "Template notes" }, "workout_type": { "type": "string", "example": "For Time" } } }, "internal_handler.WODListResponse": { "description": "List of WODs", "type": "object", "properties": { "wods": { "type": "array", "items": { "$ref": "#/definitions/internal_handler.WODResponse" } } } }, "internal_handler.WODPerformance": { "description": "Performance data recorded for a WOD in a workout", "type": "object", "properties": { "notes": { "type": "string", "example": "PR attempt" }, "order_index": { "type": "integer", "example": 0 }, "reps": { "description": "Remaining reps in AMRAP", "type": "integer", "example": 12 }, "rounds": { "description": "For AMRAP", "type": "integer", "example": 5 }, "score_type": { "description": "Time, Rounds+Reps, Max Weight", "type": "string", "example": "Time" }, "score_value": { "description": "Formatted score", "type": "string", "example": "12:30" }, "time_seconds": { "description": "For time-based WODs", "type": "integer", "example": 750 }, "weight": { "description": "For max weight WODs", "type": "number", "example": 225 }, "wod_id": { "type": "integer", "example": 1 } } }, "internal_handler.WODResponse": { "description": "WOD details response", "type": "object", "properties": { "created_at": { "type": "string", "example": "2024-01-15T10:30:00Z" }, "created_by": { "type": "integer" }, "description": { "type": "string", "example": "21-15-9 thrusters and pull-ups" }, "id": { "type": "integer", "example": 1 }, "is_standard": { "type": "boolean", "example": true }, "name": { "type": "string", "example": "Fran" }, "notes": { "type": "string" }, "regime": { "type": "string", "example": "21-15-9" }, "score_type": { "type": "string", "example": "time" }, "source": { "type": "string", "example": "CrossFit" }, "type": { "type": "string", "example": "For Time" }, "updated_at": { "type": "string", "example": "2024-01-15T10:30:00Z" }, "url": { "type": "string" } } } }, "securityDefinitions": { "BearerAuth": { "description": "JWT Bearer token. Format: \"Bearer {token}\"", "type": "apiKey", "name": "Authorization", "in": "header" } } }` // SwaggerInfo holds exported Swagger Info so clients can modify it var SwaggerInfo = &swag.Spec{ Version: "0.22.0", Host: "localhost:8080", BasePath: "/api", Schemes: []string{}, Title: "ActaLog API", 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.", InfoInstanceName: "swagger", SwaggerTemplate: docTemplate, LeftDelim: "{{", RightDelim: "}}", } func init() { swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) }