{"openapi":"3.1.0","info":{"title":"Cristian Fitness API","version":"1.0.0","description":"API REST multiusuario para entrenamientos y métricas corporales. La identidad autenticada determina el conjunto de datos; no se acepta un userId del cliente."},"servers":[{"url":"/","description":"Servidor actual"}],"tags":[{"name":"Auth"},{"name":"Fitness"},{"name":"Tokens"},{"name":"Admin"},{"name":"Export"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"Personal access token (fit_...)"},"cookieAuth":{"type":"apiKey","in":"cookie","name":"fitness_session"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"}}}}},"WorkoutInput":{"type":"object","required":["date","exercise","reps"],"properties":{"date":{"type":"string","format":"date"},"session":{"type":"string"},"exercise":{"type":"string"},"weightKg":{"type":["number","null"]},"reps":{"type":"array","minItems":1,"items":{"type":"integer","minimum":0}},"durationMin":{"type":["number","null"]},"distanceKm":{"type":["number","null"]},"rpe":{"type":["number","null"],"minimum":1,"maximum":10},"notes":{"type":"string"}}},"WorkoutPatch":{"type":"object","properties":{"date":{"type":"string","format":"date"},"session":{"type":"string"},"exercise":{"type":"string"},"set":{"type":"integer","minimum":1},"weightKg":{"type":["number","null"]},"reps":{"type":["integer","null"],"minimum":0},"durationMin":{"type":["number","null"]},"distanceKm":{"type":["number","null"]},"rpe":{"type":["number","null"],"minimum":1,"maximum":10},"notes":{"type":"string"}}},"WorkoutRow":{"type":"object","properties":{"id":{"type":"string"},"date":{"type":"string","format":"date"},"exercise":{"type":"string"},"set":{"type":"integer"},"weightKg":{"type":["number","null"]},"reps":{"type":["integer","null"]},"rpe":{"type":["number","null"]},"notes":{"type":"string"}}},"DailyInput":{"type":"object","properties":{"weightKg":{"type":["number","null"]},"waistCm":{"type":["number","null"]},"calories":{"type":["number","null"]},"proteinG":{"type":["number","null"]},"carbsG":{"type":["number","null"]},"fatG":{"type":["number","null"]},"steps":{"type":["integer","null"]},"sleepHours":{"type":["number","null"]},"energy":{"type":["integer","null"],"minimum":1,"maximum":5},"hunger":{"type":["integer","null"],"minimum":1,"maximum":5},"notes":{"type":"string"}}},"Dashboard":{"type":"object","properties":{"workouts":{"type":"array","items":{"$ref":"#/components/schemas/WorkoutRow"}},"daily":{"type":"array","items":{"type":"object"}},"exerciseProgress":{"type":"object","additionalProperties":{"type":"array","items":{"type":"object"}}}}},"TokenIssued":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"token":{"type":"string","description":"Se devuelve una sola vez"},"createdAt":{"type":"string","format":"date-time"}}}}},"paths":{"/api/v1/auth/login":{"post":{"tags":["Auth"],"summary":"Iniciar sesión web","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["username","password"],"properties":{"username":{"type":"string"},"password":{"type":"string","format":"password"}}}}}},"responses":{"200":{"description":"Sesión iniciada","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Credenciales incorrectas","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/auth/session":{"get":{"tags":["Auth"],"summary":"Consultar sesión web","responses":{"200":{"description":"Estado de sesión","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/auth/logout":{"post":{"tags":["Auth"],"summary":"Cerrar sesión web","security":[{"cookieAuth":[]}],"responses":{"200":{"description":"Sesión cerrada","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/me":{"get":{"tags":["Auth"],"summary":"Usuario autenticado","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"Usuario","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"No autorizado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/dashboard":{"get":{"tags":["Fitness"],"summary":"Todos los datos y agregados del usuario","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"Panel","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Dashboard"}}}}}}},"/api/v1/workouts":{"post":{"tags":["Fitness"],"summary":"Registrar un ejercicio con una fila por serie","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutInput"}}}},"responses":{"201":{"description":"Registrado","content":{"application/json":{"schema":{"type":"object"}}}},"422":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workouts/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^w-[0-9]+$"}}],"patch":{"tags":["Fitness"],"summary":"Editar una serie","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkoutPatch"}}}},"responses":{"200":{"description":"Actualizada","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"No encontrada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Fitness"],"summary":"Eliminar una serie","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"Eliminada","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"No encontrada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/daily/{date}":{"put":{"tags":["Fitness"],"summary":"Crear o actualizar métricas del día","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"parameters":[{"name":"date","in":"path","required":true,"schema":{"type":"string","format":"date"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DailyInput"}}}},"responses":{"200":{"description":"Guardado","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/exercises/{exercise}/progress":{"get":{"tags":["Fitness"],"summary":"Evolución de un ejercicio","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"parameters":[{"name":"exercise","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Evolución","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/tokens":{"get":{"tags":["Tokens"],"summary":"Listar tokens activos","description":"Solo sesión web.","security":[{"cookieAuth":[]}],"responses":{"200":{"description":"Tokens","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"tags":["Tokens"],"summary":"Crear token personal","description":"Solo sesión web y CSRF. El secreto se devuelve una vez.","security":[{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}}}}}},"responses":{"201":{"description":"Token creado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenIssued"}}}}}}},"/api/v1/tokens/{id}":{"delete":{"tags":["Tokens"],"summary":"Revocar token","security":[{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Revocado","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/admin/users":{"get":{"tags":["Admin"],"summary":"Listar usuarios","description":"Solo administradores mediante sesión web.","security":[{"cookieAuth":[]}],"responses":{"200":{"description":"Usuarios","content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"Prohibido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Admin"],"summary":"Crear usuario y almacenamiento aislado","description":"Solo administradores mediante sesión web.","security":[{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["username","password"],"properties":{"username":{"type":"string"},"password":{"type":"string","minLength":12},"role":{"type":"string","enum":["user","admin"]}}}}}},"responses":{"201":{"description":"Usuario creado","content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"Prohibido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/export/fitness.xlsx":{"get":{"tags":["Export"],"summary":"Descargar Excel completo del usuario","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"Libro Excel","content":{"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"type":"string","contentEncoding":"binary"}}}}}}}}}