Skip to content

Logros

Endpoints para gestionar y ver logros.

Los siguientes modelos de Prisma pertenecen al schema gamification:

model Achievement {
id String @id @default(cuid())
name String @unique
title String
description String
type AchievementType
iconUrl String? @map("icon_url")
badgeColor String? @map("badge_color")
xpReward Int @default(0) @map("xp_reward")
requirement Json
rarity String?
category String?
isActive Boolean @default(true) @map("is_active")
userAchievements UserAchievement[]
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("achievements")
@@schema("gamification")
}
model UserAchievement {
id String @id @default(cuid())
userProfileId String @map("user_profile_id")
achievementId String @map("achievement_id")
earnedAt DateTime @default(now()) @map("earned_at")
progress Json?
isDisplayed Boolean @default(true) @map("is_displayed")
userProfile UserProfile @relation(fields: [userProfileId], references: [id], onDelete: Cascade)
achievement Achievement @relation(fields: [achievementId], references: [id], onDelete: Cascade)
@@unique([userProfileId, achievementId])
@@map("user_achievements")
@@schema("gamification")
}
enum AchievementType {
STREAK_MILESTONE
WORKOUT_COUNT
WEIGHT_MILESTONE
ATTENDANCE
SOCIAL
SPECIAL
@@schema("gamification")
}

Los achievements se desbloquean automáticamente cuando:

  • Se sube de nivel (verifica achievements tipo ‘level’)
  • Se alcanza cierta racha (verifica achievements tipo ‘streak’)
  • Se completan objetivos específicos

Obtener todos los logros disponibles en el sistema.

  • URL: /api/v1/gamification/achievements
  • Método: GET
  • Autenticación Requerida:

Este endpoint obtiene todos los logros disponibles:

  1. Filtros disponibles:

    • type: WORKOUT_COUNT, STREAK_MILESTONE, etc.
    • category: FITNESS, NUTRITION, SOCIAL, etc.
    • rarity: COMMON, UNCOMMON, RARE, EPIC, LEGENDARY
    • isActive: Solo logros activos
  2. Incluye contador de userAchievements (cuántos usuarios lo tienen)

  3. Ordenado por fecha de creación

  • type: Tipo de achievement
  • category: Categoría del achievement
  • rarity: Rareza del achievement
  • isActive: Solo logros activos
  • page: Número de página
  • limit: Resultados por página
{
"data": [
{
"id": "...",
"name": "first_workout",
"title": "First Steps",
"description": "Complete your first workout",
"type": "WORKOUT_COUNT",
"iconUrl": "https://...",
"badgeColor": "#FFD700",
"xpReward": 50,
"requirement": { "workout_count": 1 },
"rarity": "COMMON",
"category": "FITNESS",
"isActive": true,
"_count": {
"userAchievements": 1250
}
}
],
"pagination": {...}
}

Obtener un logro específico.

  • URL: /api/v1/gamification/achievements/:id
  • Método: GET
  • Autenticación Requerida:

Obtener logros del usuario.

  • URL: /api/v1/gamification/user-achievements/me
  • Método: GET
  • Autenticación Requerida:

Este endpoint obtiene los logros desbloqueados del usuario:

  1. Filtros disponibles:

    • achievementId: Filtrar por logro específico
    • isDisplayed: Solo logros mostrados en perfil
  2. Incluye:

    • achievement: Datos completos del logro
    • userProfile: id y name
  3. Ordenado por earnedAt descendente

{
"data": [
{
"id": "...",
"earnedAt": "2023-10-15T10:00:00Z",
"isDisplayed": true,
"achievement": {
"id": "...",
"name": "First Steps",
"description": "Complete your first workout",
"icon": "🏃",
"xpReward": 50,
"rarity": "COMMON"
}
}
]
}
import { hcWithType } from '@vitality-gym/api/client'
const client = hcWithType('http://localhost:3000')
const res = await client.api.v1.gamification['user-achievements'].me.$get()

Alternar si un logro se muestra en el perfil del usuario.

  • URL: /api/v1/gamification/user-achievements/:id/display
  • Método: PUT
  • Autenticación Requerida:
{
"isDisplayed": true
}

Obtener progreso hacia logros bloqueados.

  • URL: /api/v1/gamification/achievements/progress
  • Método: GET
  • Autenticación Requerida:
{
"data": [
{
"achievement": {
"id": "...",
"name": "30 Day Streak",
"requirement": { "streak_days": 30 }
},
"currentProgress": 15,
"targetProgress": 30,
"progressPercentage": 50
}
]
}

Crear un nuevo logro.

  • URL: /api/v1/gamification/achievements
  • Método: POST
  • Autenticación Requerida: Sí (Admin)
{
"name": "marathon_runner",
"title": "Marathon Runner",
"description": "Complete 100 workouts",
"type": "WORKOUT_COUNT",
"iconUrl": "https://...",
"badgeColor": "#FFD700",
"xpReward": 500,
"requirement": { "workout_count": 100 },
"rarity": "EPIC",
"category": "FITNESS"
}
TipoDescripción
STREAK_MILESTONELogros por rachas (7 días, 30 días, etc.)
WORKOUT_COUNTLogros por cantidad de entrenamientos
WEIGHT_MILESTONELogros por pérdida/ganancia de peso
ATTENDANCELogros por asistencia
SOCIALLogros sociales (likes, comentarios)
SPECIALLogros especiales/eventos
RarezaDescripción
COMMONFácil de obtener
UNCOMMONRequiere algo de esfuerzo
RAREDifícil de obtener
EPICMuy difícil de obtener
LEGENDARYExtremadamente raro