Skip to content

Posts

Endpoints para crear y gestionar posts sociales, likes y comentarios.

Los siguientes modelos de Prisma pertenecen al schema social:

model Post {
id String @id @default(cuid())
userProfileId String @map("user_profile_id")
title String?
content String
imageUrl String? @map("image_url")
videoUrl String? @map("video_url")
isPublic Boolean @default(true) @map("is_public")
userProfile UserProfile @relation(fields: [userProfileId], references: [id], onDelete: Cascade)
likes Like[]
comments Comment[]
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("posts")
@@schema("social")
}
model Like {
id String @id @default(cuid())
userProfileId String @map("user_profile_id")
postId String @map("post_id")
userProfile UserProfile @relation(fields: [userProfileId], references: [id], onDelete: Cascade)
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now()) @map("created_at")
@@unique([userProfileId, postId])
@@map("likes")
@@schema("social")
}
model Comment {
id String @id @default(cuid())
userProfileId String @map("user_profile_id")
postId String @map("post_id")
content String
userProfile UserProfile @relation(fields: [userProfileId], references: [id], onDelete: Cascade)
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("comments")
@@schema("social")
}

Obtener posts públicos con filtrado.

  • URL: /api/v1/social/posts
  • Método: GET
  • Autenticación Requerida:

Este endpoint obtiene posts públicos:

  1. Filtro base: Solo posts con isPublic: true

  2. Filtros opcionales:

    • userId: Posts de un usuario específico
    • following: Si es true y se proporciona userId, obtiene posts de usuarios seguidos
  3. Lógica de following:

    • Obtiene lista de followingIds del usuario
    • Filtra posts donde userProfileId está en esa lista
  4. Incluye:

    • userProfile (id, name)
    • Contadores de likes y comments
  5. Ordenado por createdAt descendente

  • limit: Número de posts por página
  • offset: Offset para paginación
  • userId: Filtrar por usuario
  • following: Obtener posts solo de usuarios seguidos
{
"data": [
{
"id": "...",
"title": "My first post",
"content": "Just finished a great workout!",
"isPublic": true,
"createdAt": "2023-10-27T10:00:00Z",
"userProfile": {
"id": "...",
"name": "John Doe"
},
"_count": {
"likes": 5,
"comments": 3
}
}
],
"pagination": {...}
}
import { hcWithType } from '@vitality-gym/api/client'
const client = hcWithType('http://localhost:3000')
const res = await client.api.v1.social.posts.$get({
query: {
limit: '10'
}
})

Crear un nuevo post social.

  • URL: /api/v1/social/posts
  • Método: POST
  • Autenticación Requerida:

Este endpoint crea un nuevo post:

  1. Obtiene userProfileId del token de autenticación

  2. Crea el post con:

    • title, content (proporcionados)
    • imageUrl (opcional)
    • isPublic (default: true)
    • userProfileId
  3. Incluye en respuesta:

    • userProfile (id, name)
    • Contadores iniciales (0 likes, 0 comments)
{
"title": "Workout Complete",
"content": "Just finished a great workout!",
"imageUrl": "https://...",
"isPublic": true
}
import { hcWithType } from '@vitality-gym/api/client'
const client = hcWithType('http://localhost:3000')
const res = await client.api.v1.social.posts.$post({
json: {
content: 'Just finished a great workout!'
}
})

Obtener detalles de un post específico incluyendo likes y comentarios.

  • URL: /api/v1/social/posts/:id
  • Método: GET
  • Autenticación Requerida:

Este endpoint obtiene un post con todo su contenido:

  1. Busca post por ID usando findUniqueOrThrow
  2. Incluye:
    • userProfile (id, userId, name)
    • likes con userProfile de cada like
    • comments con userProfile, ordenados por fecha descendente
    • Contadores de likes y comments

Actualizar un post existente.

  • URL: /api/v1/social/posts/:id
  • Método: PUT
  • Autenticación Requerida:

Eliminar un post.

  • URL: /api/v1/social/posts/:id
  • Método: DELETE
  • Autenticación Requerida:

Dar o quitar like a un post.

  • URL: /api/v1/social/posts/:id/like
  • Método: POST
  • Autenticación Requerida:

Este endpoint alterna el like en un post:

  1. Busca like existente con compound key (userProfileId + postId)

  2. Si no existe: Crea nuevo like

  3. Si existe: Elimina el like

  4. Retorna el like creado o eliminado con userProfile

  • Primera llamada: Añade like
  • Segunda llamada: Quita like
  • Tercera llamada: Añade like (etc.)
import { hcWithType } from '@vitality-gym/api/client'
const client = hcWithType('http://localhost:3000')
const res = await client.api.v1.social.posts[':id'].like.$post({
param: { id: 'post_id' }
})

Añadir un comentario a un post.

  • URL: /api/v1/social/posts/:id/comments
  • Método: POST
  • Autenticación Requerida:

Este endpoint añade un comentario:

  1. Obtiene postId de params y userProfileId del token
  2. Crea el comentario con content proporcionado
  3. Incluye userProfile en respuesta
{
"content": "Great job!"
}
import { hcWithType } from '@vitality-gym/api/client'
const client = hcWithType('http://localhost:3000')
const res = await client.api.v1.social.posts[':id'].comments.$post({
param: { id: 'post_id' },
json: {
content: 'Great job!'
}
})

Eliminar un comentario.

  • URL: /api/v1/social/comments/:commentId
  • Método: DELETE
  • Autenticación Requerida:

Este endpoint elimina un comentario:

  1. Verifica propiedad: Compara userProfileId del comentario con el del token
  2. Si no coincide: Lanza error “No tienes permisos para eliminar este comentario”
  3. Si coincide: Elimina el comentario

Nota: Solo el autor del comentario puede eliminarlo.