// FRASA API Gateway — persistencia local // Desarrollo: SQLite. Producción: Postgres 16 (cambiar provider y DATABASE_URL). generator client { provider = "prisma-client-js" } datasource db { provider = "sqlite" // prod: "postgresql" url = env("DATABASE_URL") } model Cotizacion { id String @id @default(uuid()) unidadCodigo String clienteNombre String clienteEmail String? clienteTelefono String? tipoPropuesta String // BANCARIO | INFONAVIT | CONTADO | SEMI_CONTADO acabados Boolean apartado Float // TODO prod: Decimal en Postgres descuento Float // fracción (0.02 = 2%) precioLista Float // TODO prod: Decimal en Postgres precioFinal Float enganche Float numMensualidades Int mensualidad Float? // null => N/A (Contado) pagoFinal Float mondayItemId String? createdAt DateTime @default(now()) @@index([unidadCodigo]) } model Cliente { id String @id @default(uuid()) nombreCompleto String curp String rfc String email String? celular String? proyecto String unidadCodigo String? // Payload completo del alta como JSON serializado (SQLite no tiene Json nativo; // en Postgres puede migrarse a la columna Json sin cambiar el contrato). payloadJson String firmaPng String? // base64 opcional mondayContactoId String? mondayApartadoId String? createdAt DateTime @default(now()) documentos Documento[] @@index([curp]) } model Documento { id String @id @default(uuid()) clienteId String cliente Cliente @relation(fields: [clienteId], references: [id], onDelete: Cascade) tipo String // INE | CONSTANCIA_RFC | CURP | COMPROBANTE_DOMICILIO | ACTA_NACIMIENTO | OTRO nombreArchivo String ruta String mime String tamano Int createdAt DateTime @default(now()) @@index([clienteId]) } model PlanPago { id String @id @default(uuid()) ventaRef String? clienteNombre String clienteTelefono String? unidadCodigo String proyecto String fechaInicio DateTime // se normaliza a medianoche local engancheTotal Float // TODO prod: Decimal en Postgres numPagos Int mensualidad Float tasaMoraMensual Float @default(0) status String @default("ACTIVO") // ACTIVO | CANCELADO (LIQUIDADO se deriva) createdAt DateTime @default(now()) notas NotaPlan[] pagos Pago[] @@index([unidadCodigo]) } model Pago { id String @id @default(uuid()) planId String plan PlanPago @relation(fields: [planId], references: [id], onDelete: Cascade) numPago Int fechaVencimiento DateTime monto Float montoPagado Float @default(0) aplicaciones AplicacionPago[] @@index([planId]) @@index([fechaVencimiento]) } model AplicacionPago { id String @id @default(uuid()) pagoId String pago Pago @relation(fields: [pagoId], references: [id], onDelete: Cascade) fechaPago DateTime monto Float referencia String @@index([pagoId]) } // Estado persistente de las automatizaciones de Monday (round-robin, recordatorios). // Clave-valor genérico: 'rr:indice', 'rr:vendedores', 'recordatorio::', etc. model AutomatizacionState { clave String @id valor String updatedAt DateTime @updatedAt } model NotaPlan { id String @id @default(uuid()) planId String plan PlanPago @relation(fields: [planId], references: [id], onDelete: Cascade) fecha DateTime @default(now()) texto String @@index([planId]) } // ---------- Agente IA interno (RAG) ---------- // Documento de la base de conocimiento; `hash` (sha256 del contenido) permite // re-indexar solo cuando cambió. model AIDocumento { id String @id @default(uuid()) titulo String @unique contenido String hash String createdAt DateTime @default(now()) chunks AIChunk[] } model AIChunk { id String @id @default(uuid()) documentoId String documento AIDocumento @relation(fields: [documentoId], references: [id], onDelete: Cascade) texto String embedding String // JSON array de floats (SQLite no tiene vector nativo) orden Int @@index([documentoId]) } model AIConversacion { id String @id @default(uuid()) createdAt DateTime @default(now()) mensajes AIMensaje[] } model AIMensaje { id String @id @default(uuid()) conversacionId String conversacion AIConversacion @relation(fields: [conversacionId], references: [id], onDelete: Cascade) rol String // user | assistant contenido String fuentes String? // JSON [{titulo, score}] solo en mensajes del asistente createdAt DateTime @default(now()) @@index([conversacionId]) }