Skip to Content
📚 Bienvenido a la documentación técnica de Rial AI 👋
Database🗂️ Esquema de Base de Datos

🗂️ Esquema de Base de Datos

La base de datos de Rial AI está modelada de manera relacional en PostgreSQL y representa las relaciones entre compañías, marcas, usuarios, prendas, proyectos de generación, imágenes, modelos virtuales, publicaciones y control de créditos.

📊 Estructura General

Todos los modelos en nuestra base de datos siguen un patrón consistente que incluye:

  • id: Identificador incremental para uso interno del desarrollador
  • publicId: UUID (identificador único) que se puede compartir con el usuario y frontend de forma segura
  • createdAt: Timestamp de creación del registro
  • updatedAt: Timestamp de última actualización

¿Por qué dos IDs? El id interno es secuencial y optimizado para consultas de base de datos, mientras que el publicId es un UUID que no revela información sobre la cantidad de registros y es seguro para exponer públicamente.


🏢 Modelos de Organización

Company (Compañía)

Representa a una empresa que puede tener múltiples marcas. Las empresas pueden operar con o sin sistema de créditos.

model Company { id Int @id @default(autoincrement()) publicId String @unique @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt name String @unique logo String credits Int @default(0) brands Brand[] users User[] folders ProjectFolder[] models Model[] }

Campos Clave

  • name: Nombre único de la compañía
  • logo: URL del logo corporativo
  • credits: Saldo actual de créditos (default: 0)
    • Nota: Por ahora no manejamos activamente el sistema de créditos

Relaciones

  • brands[]: Una compañía puede tener múltiples marcas
  • users[]: Una compañía puede tener múltiples usuarios
  • folders[]: Carpetas de proyectos de la compañía
  • models[]: Modelos virtuales asociados a la compañía

Brand (Marca)

Cada marca pertenece a una compañía y contiene sus propias prendas, proyectos, usuarios y modelos virtuales. El par (name, companyId) es único.

model Brand { id Int @id @default(autoincrement()) publicId String @unique @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt name String logo String companyId Int company Company @relation(fields: [companyId], references: [id]) garments Garment[] projects Project[] users User[] // N:M con User models Model[] // N:M con Model } // Índice único: (name, companyId)

Campos Clave

  • name: Nombre de la marca (único por compañía)
  • logo: URL del logo de la marca
  • companyId: Referencia a la compañía propietaria

Relaciones

  • company: Pertenece a una compañía
  • users[]: Usuarios asignados a la marca
  • garments[]: Prendas de la marca
  • projects[]: Proyectos de generación
  • models[]: Modelos virtuales personalizados

User (Usuario)

Representa a un miembro de la plataforma con diferentes niveles de acceso, permisos granulares y asociación a marcas mediante relación N:M.

model User { id Int @id @default(autoincrement()) publicId String @unique @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt nickname String @default("") email String @unique phoneNumber String? notificationsEnabled NotificationTemplateType[] role UserRole @default(COMPANY_ADMIN) companyId Int? sessionId String @unique transactions CreditTransaction[] company Company? @relation(fields: [companyId], references: [id]) approvals GeneratedImage[] apiKey ApiKey? brands Brand[] permissions RolePermission[] allowedModelSexes Gender[] } enum UserRole { ADMIN COMPANY_ADMIN BRAND_ADMIN } enum RolePermission { // Permisos del usuario PROJECT_CREATOR // Puede crear proyectos REVIEWER // Puede revisar imágenes DOWNLOADER // Puede descargar imágenes PERMISSION_ADMIN // Puede manejar permisos de otros usuarios VIEWER // Puede ver el detalle de las imágenes }

Campos Clave

  • email: Email único del usuario (usado para autenticación)
  • nickname: Nombre para mostrar (Actualmente usado cuando se envían notificaciones)
  • phoneNumber: Teléfono (opcional, usado para el envío de notificaciones)
  • notificationsEnabled: Tipos de notificación que el usuario tiene habilitados
  • role: Nivel de acceso del usuario
    • ADMIN: Acceso completo a toda la plataforma
    • COMPANY_ADMIN: Administrador de una compañía específica
    • BRAND_ADMIN: Administrador de marcas en específico
  • permissions: Permisos granulares
  • allowedModelSexes: Géneros de modelo permitidos para este usuario
  • sessionId: Identificador único de sesión (relacionado con autenticación Supabase)
  • companyId: Referencia a compañía (para usuarios de tipo COMPANY_ADMIN y BRAND_ADMIN)

Relaciones

  • company: Compañía asociada (para usuarios de tipo BRAND_ADMIN o COMPANY_ADMIN)
  • brands[]: Marcas a las que tiene acceso (para usuarios de tipo BRAND_ADMIN)
  • apiKey: API key asociada si existe (opcional)
  • transactions[]: Transacciones de créditos del usuario
  • approvals[]: Imágenes generadas que revisó este usuario

ApiKey (Clave de API)

Almacena claves de API para autenticación de integraciones. Cada usuario puede tener como máximo una API key.

model ApiKey { id Int @id @default(autoincrement()) publicId String @unique name String prefix String @unique // Primeros caracteres visibles para identificación hash String // Hash de la clave (nunca se almacena en claro) ownerId Int @unique owner User @relation(fields: [ownerId], references: [id]) isDisabled Boolean @default(false) lastUsedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }

Campos Clave

  • name: Nombre descriptivo de la clave (ej. “Integración Excel”)
  • prefix: Prefijo visible de la clave para que el usuario identifique cuál es
  • hash: Hash de la clave secreta (no se almacena el valor en claro)
  • ownerId: Usuario propietario (relación 1:1)
  • isDisabled: Si está deshabilitada no se puede usar para autenticación
  • lastUsedAt: Última vez que se usó la clave (auditoría)

Relaciones

  • owner: Usuario propietario de la API key

👕 Gestión de Prendas

Garment (Prenda)

Representa las prendas subidas por las marcas para ser utilizadas en los proyectos de generación.

model Garment { id Int @id @default(autoincrement()) publicId String @unique @default(uuid()) name String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt season String? type GarmentType brandId Int? brand Brand? @relation(fields: [brandId], references: [id]) images GarmentImage[] projects ProjectImage[] // N:M: prendas usadas en una entrada de proyecto result GeneratedImage[] // N:M: imágenes generadas que incluyen esta prenda } enum GarmentType { FOOTWEAR // Zapatos, botas, sandalias UPPER_TRUNK // Camisetas, blusas, chaquetas LOWER_TRUNK // Pantalones, faldas, shorts FULL_BODY // Conjuntos completos FACESWAP // Imágenes para proyectos de tipo faceswap }

Campos Clave

  • name: Nombre descriptivo de la prenda
  • type: Categoría de la prenda
    • FOOTWEAR: Zapatos, botas, sandalias, etc.
    • UPPER_TRUNK: Camisetas, blusas, chaquetas, etc.
    • LOWER_TRUNK: Pantalones, faldas, shorts, etc.
    • FULL_BODY: Conjuntos completos
    • FACESWAP: Imágenes para proyectos de tipo faceswap
  • season: Temporada asociada (opcional) - ej: “Verano 2024”, “Otoño/Invierno 2024”
  • brandId: Referencia opcional a la marca propietaria

Relaciones

  • brand: Marca propietaria de la prenda (opcional)
  • images[]: Imágenes asociadas a la prenda
  • projects[]: Entradas de proyecto (ProjectImage) donde se utiliza la prenda (N:M)
  • result[]: Imágenes generadas que incluyen esta prenda (N:M)

GarmentImage (Imagen de Prenda)

Almacena las imágenes originales de las prendas subidas por las marcas.

model GarmentImage { id Int @id @default(autoincrement()) publicId String @unique @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt url String garmentId Int garment Garment @relation(fields: [garmentId], references: [id]) }

Campos Clave

  • url: URL de la imagen almacenada en Google Cloud Storage
  • garmentId: Referencia a la prenda asociada

Relaciones

  • garment: Prenda a la que pertenece la imagen

🎯 Sistema de Proyectos

ProjectFolder (Carpeta de Proyectos)

Agrupa proyectos bajo un nombre, tipo, temporada y descripción. La compañía organiza su trabajo en carpetas; cada carpeta tiene estados visibles para admin y para cliente.

model ProjectFolder { id Int @id @default(autoincrement()) publicId String @unique @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt name String projectType ProjectType season String? description String? adminStatus AdminStatus @default(CREATING) clientStatus ClientStatus @default(CREATING) companyId Int company Company @relation(fields: [companyId], references: [id]) projects Project[] notifications Notification[] } // Índice único: (companyId, name) enum ProjectType { LIFESTYLE BATCH LOOKBOOK FACESWAP } enum AdminStatus { CREATING IN_PROGRESS WAITING_APPROVAL REJECTED COMPLETED CANCELLED } enum ClientStatus { CREATING IN_PROGRESS PENDING_APPROVAL IN_REVIEW PENDING_DOWNLOAD COMPLETED CANCELLED }

Campos Clave

  • name: Nombre de la carpeta (único por compañía)
  • projectType: Tipo de caso/proyecto
    • LIFESTYLE: Generación contextualizada con escenarios personalizados
    • BATCH: Generación masiva de prendas individuales
    • LOOKBOOK: Generación de conjuntos completos
    • FACESWAP: Reemplazo de rostros
  • season: Temporada asociada (opcional)
  • description: Descripción de la carpeta
  • adminStatus: Estado visible para administradores (flujo interno)
  • clientStatus: Estado visible para el cliente (flujo de aprobación/descarga)

Relaciones

  • company: Compañía propietaria de la carpeta
  • projects[]: Proyectos contenidos en la carpeta
  • notifications[]: Notificaciones asociadas a esta carpeta

Project (Proyecto)

Un proyecto define una generación concreta dentro de una carpeta: opciones en JSON, marca y carpeta. No tiene nombre propio; el nombre, temporada y descripción están en la carpeta.

model Project { id Int @id @default(autoincrement()) publicId String @unique @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt adminStatus AdminStatus @default(CREATING) clientStatus ClientStatus @default(CREATING) statusRank Int @default(99) // Orden para vistas por estado statusRankAdmin Int @default(99) brandId Int options Json folderId Int brand Brand @relation(fields: [brandId], references: [id]) folder ProjectFolder @relation(fields: [folderId], references: [id]) images GeneratedImage[] uploads ProjectImage[] } // Índice único: (options, brandId, folderId)

Campos Clave

  • adminStatus / clientStatus: Estados del proyecto (mismos enums que ProjectFolder)
  • statusRank / statusRankAdmin: Orden para mostrar proyectos por estado (cliente y admin)
  • options: Configuración en JSON con parámetros específicos del tipo de proyecto
  • brandId: Marca propietaria del proyecto
  • folderId: Carpeta a la que pertenece el proyecto

Relaciones

  • brand: Marca propietaria del proyecto
  • folder: Carpeta que agrupa este proyecto
  • uploads[]: Imágenes de entrada (ProjectImage)
  • images[]: Imágenes generadas en el proyecto

ProjectImage (Imagen de Proyecto)

Representa una entrada de generación dentro de un proyecto, es decir, un SKU. Tiene estados separados para vista admin y cliente.

model ProjectImage { id Int @id @default(autoincrement()) publicId String @unique @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt settings Json projectId Int project Project @relation(fields: [projectId], references: [id]) images GeneratedImage[] garments Garment[] // N:M: prendas usadas en esta entrada SKU String adminStatus AdminStatus @default(IN_PROGRESS) clientStatus ClientStatus @default(IN_PROGRESS) }

Campos Clave

  • settings: Configuración específica en JSON (pose, fondo, modelo, etc.)
  • SKU: Código de identificación del producto
  • adminStatus: Estado para administradores (mismo enum AdminStatus)
  • clientStatus: Estado para el cliente (mismo enum ClientStatus)
  • projectId: Referencia al proyecto

Relaciones

  • project: Proyecto al que pertenece
  • garments[]: Prendas utilizadas en esta generación (N:M)
  • images[]: Imágenes generadas para esta entrada

🖼️ Gestión de Imágenes

GeneratedImage (Imagen Generada)

Almacena las imágenes generadas por IA con sistema de versionado, aprobación y relación N:M con prendas.

model GeneratedImage { id Int @id @default(autoincrement()) publicId String @unique @default(uuid()) name String url String status ImageStatus @default(INCOMPLETE) reason String? uploadId Int projectId Int project Project @relation(fields: [projectId], references: [id]) upload ProjectImage @relation(fields: [uploadId], references: [id]) previous GeneratedImage? @relation("PreviousImages", fields: [previousId], references: [id]) previousId Int? @unique next GeneratedImage? @relation("PreviousImages") isFinal Boolean @default(true) version Int @default(1) garments Garment[] // N:M: prendas que aparecen en esta imagen approvedBy User? @relation(fields: [approvedById], references: [id]) approvedById Int? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } enum ImageStatus { PENDING INCOMPLETE PENDING_APPROVAL APPROVED REJECTED }

Campos Clave

  • name: Nombre del archivo o imagen
  • url: URL de la imagen generada (a bucket en GCP)
  • status: Estado en el flujo de aprobación (incluye INCOMPLETE mientras no esté completo el SKU)
  • reason: Razón de rechazo (si estado es REJECTED)
  • isFinal: Indica si es la versión final
  • version: Número de versión (para versionado)
  • previousId: Referencia a imagen anterior (cadena de versiones)
  • approvedById: Usuario que revisó la imagen

Sistema de Versionado

Las imágenes pueden tener múltiples versiones. Cuando se solicita una mejora o corrección:

  1. Se crea una nueva GeneratedImage
  2. Se establece previousId apuntando a la versión anterior
  3. Solo la imagen final puede tener isFinal = true. El campo version ayuda a ordenar y mostrar la versión actual.

Relaciones

  • project: Proyecto al que pertenece
  • upload: SKU al cual se relaciona (ProjectImage)
  • previous / next: Cadena de versiones
  • garments[]: Prendas que aparecen en esta imagen (N:M)
  • approvedBy: Usuario que aprobó la imagen

👤 Modelos

Model (Modelo)

Representa los modelos del catálogo Rial. Pertenecen a una compañía y se asocian a marcas mediante relación N:M (un modelo puede usarse en varias marcas).

model Model { id Int @id @default(autoincrement()) publicId String @unique @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt name String gender Gender age Int image String companyId Int? company Company? @relation(fields: [companyId], references: [id]) brands Brand[] // N:M con Brand } enum Gender { MALE FEMALE OTHER }

Campos Clave

  • name: Nombre del modelo
  • gender: Género del modelo
  • age: Edad aproximada del modelo
  • image: URL de la imagen de referencia del modelo
  • companyId: Referencia a la compañía (opcional; si es null, el modelo puede ser público)

Tipos de Modelos

  • Los modelos se asocian a marcas mediante la relación N:M (brands[]). Una compañía tiene sus modelos y cada modelo puede estar en una o más marcas.

Relaciones

  • company: Compañía a la que pertenece el modelo (opcional)
  • brands[]: Marcas en las que está disponible este modelo (N:M)

🔔 Notificaciones

Notification (Notificación)

Registra notificaciones enviadas a usuarios (email, WhatsApp, etc.), asociadas a una carpeta de proyectos y generadas a partir de una plantilla.

model Notification { id Int @id @default(autoincrement()) publicId String @unique @default(uuid()) title String description String link String folderId Int? folder ProjectFolder? @relation(fields: [folderId], references: [id]) isRead Boolean @default(false) templateId Int template NotificationTemplate @relation(fields: [templateId], references: [id]) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }

Campos Clave

  • title: Título de la notificación
  • description: Cuerpo o descripción del mensaje
  • link: Enlace asociado de rial-ai.com
  • folderId: Al caso que se relaciona la notificación (si es que aplica)
  • isRead: Si el usuario ya leyó la notificación
  • templateId: Plantilla con la que se generó el mensaje

Relaciones

  • folder: Carpeta de proyectos asociada (opcional)
  • template: Plantilla de notificación usada

NotificationTemplate (Plantilla de Notificación)

Define plantillas reutilizables para notificaciones (email, WhatsApp). El publicId identifica el tipo de evento (enum).

model NotificationTemplate { id Int @id @default(autoincrement()) publicId NotificationTemplateType @unique title String body String variables String[] twilioTemplateSid String role UserRole createdAt DateTime @default(now()) updatedAt DateTime @updatedAt notifications Notification[] } enum NotificationTemplateType { ADMIN_PROJECT_CREATED // Notificación para administrador cuando se crea un proyecto/caso nuevo ADMIN_NEW_REJECTIONS // Notificación para administrador cuando se rechazan imágenes COMPANY_PROJECT_CREATED // Notificación para cliente cuando se termina de crear un proyecto nuevo COMPANY_PROJECT_PENDING_APPROVAL // Notificación para cliente cuando se generan nuevas imágenes COMPANY_PROJECT_READY_FOR_DOWNLOAD // Notificación para cliente cuando se completa/aprueba un caso/proyecto }

Campos Clave

  • publicId: Tipo de notificación (enum); identifica el evento que dispara esta plantilla
  • title / body: Texto de la plantilla
  • variables: Lista de nombres de variables que se reemplazan al enviar (ej. nombre de carpeta, link)
  • twilioTemplateSid: ID de la plantilla en Twilio para mensajes WhatsApp
  • role: Rol del usuario al que va dirigida (ADMIN, COMPANY_ADMIN, BRAND_ADMIN)

Relaciones

  • notifications[]: Notificaciones generadas con esta plantilla

💳 Sistema de Créditos

Nota: Este sistema está definido en la base de datos pero aún no está implementado en la aplicación.

CreditTransaction (Transacción de Créditos)

Registra todas las compras y usos de créditos en el sistema.

model CreditTransaction { id Int @id @default(autoincrement()) publicId String @unique @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt amount Int transactionType TransactionType userId Int user User @relation(fields: [userId], references: [id]) } enum TransactionType { PURCHASE USAGE }

Campos Clave

  • amount: Cantidad de créditos
  • transactionType: Tipo de transacción
    • PURCHASE: Compra de créditos
    • USAGE: Uso de créditos para generación
  • userId: Usuario que realizó la transacción

Relaciones

  • user: Usuario asociado a la transacción

📰 Gestión de Contenido

Post (Publicación)

Sistema de publicaciones y contenido de prensa para el sitio web y blog.

model Post { id Int @id @default(autoincrement()) publicId String @unique @default(uuid()) title String description String publicationDate DateTime? image String file String tags String[] type PostType isPublished Boolean @default(false) authorName String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } enum PostType { PUBLICATION PRESS }

Campos Clave

  • title: Título de la publicación
  • description: Contenido o descripción del post
  • publicationDate: Fecha de publicación programada
  • image: URL de imagen destacada
  • file: URL del archivo asociado
  • tags: Array de etiquetas para categorización
  • type: Tipo de publicación
    • PUBLICATION: Artículos del blog
    • PRESS: Notas de prensa
  • isPublished: Estado de publicación
  • authorName: Nombre del autor

🔗 Diagrama de Relaciones

El diagrama de relaciones se encuentra en el siguiente enlace: Diagrama de Relaciones .

Diagrama de Relaciones de la Base de Datos
Last updated on