feat(desarrollos): modulo de alta de desarrollos con inventario, reglas del cotizador por desarrollo y micrositio publico

Modulo nuevo (solo admin) para dar de alta desarrollos sin tocar codigo:
- CRUD de la ficha, modelos e inventario (alta manual y generador por rango)
- Reglas del cotizador por desarrollo, editables y persistidas en la BD
- El cotizador consume las reglas desde /desarrollos/reglas-cotizador y cae a
  las constantes con aviso cuando un desarrollo aun no tiene reglas guardadas
- Micrositio publico en /d/:clave (sin sesion) con ficha, modelos y
  disponibilidad; jamas expone datos de clientes ni cotizaciones

Integracion:
- La landing monta el modulo en el grid (clave 'desarrollos', solo admin) y el
  micrositio fuera del login; el rol manager NO accede (matriz y API con 403)
- La tabla de roles de Configuracion ahora lista todos los modulos
- Se alinea la FK de ReglaCotizadorDesarrollo con la BD viva (Desarrollo.id)

Verificado: 708 pruebas del API, 115 del cotizador y 89 de la landing en verde;
12/12 cotizaciones identicas antes y despues del cambio de reglas; prueba en
vivo del API con alta, modelos, inventario, reglas, micrositio y baja (30/30).
This commit is contained in:
2026-09-21 09:52:47 +00:00
parent 2fc80e7f9e
commit d6548999bf
68 changed files with 10016 additions and 66 deletions

View File

@@ -211,6 +211,7 @@ model Unidad {
modelo String @default("")
manzana String @default("")
lote String @default("")
nivel String @default("") // piso (desarrollos verticales); '' si no aplica
supConstruccion Float @default(0)
supExcedente Float @default(0)
supEstacionamiento Float @default(0)
@@ -530,3 +531,61 @@ model SolicitudSoporte {
@@index([usuarioId])
@@index([departamento])
}
// ── Módulo Desarrollos: catálogo de desarrollos nuevos ────────────────
// La BD es la fuente de verdad: la ficha del desarrollo, sus modelos y las
// reglas del cotizador (antes constantes fijas en el código de las apps).
model Desarrollo {
id String @id @default(uuid())
clave String @unique // SENDA, DIAGONAL… (forma los códigos de unidad)
nombre String // nombre comercial
estado String @default("ACTIVO") // ACTIVO | PREVENTA | CERRADO
tipo String @default("VERTICAL") // VERTICAL | HORIZONTAL
constructora String?
direccion String?
zona String?
descripcion String?
amenidades String? // texto libre o lista separada por comas
fechaInicioObra DateTime?
fechaEntregaProgramada DateTime?
fechaEntregaReprogramada DateTime?
activoEnCotizador Boolean @default(true) // aparece en el cotizador
activoEnAlta Boolean @default(true) // aparece en altas de lead/afluencia/cliente
prefijoUnidadPdf String? // p. ej. CASA (lo usa el PDF del cotizador)
imagenUrl String?
logoUrl String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
modelos ModeloDesarrollo[]
reglas ReglaCotizadorDesarrollo?
@@index([estado])
}
model ModeloDesarrollo {
id String @id @default(uuid())
desarrolloId String
desarrollo Desarrollo @relation(fields: [desarrolloId], references: [id], onDelete: Cascade)
nombre String
recamaras Int?
banos Float?
estacionamientos Int?
supConstruccion Float?
activo Boolean @default(true)
@@unique([desarrolloId, nombre])
@@index([desarrolloId])
}
model ReglaCotizadorDesarrollo {
// `desarrolloId` guarda el uuid de `Desarrollo.id` (es lo que escriben el seed
// y PUT /desarrollos/:id/reglas). El endpoint que consume el cotizador
// (`/desarrollos/reglas-cotizador`) traduce uuid → clave antes de responder.
desarrolloId String @id
desarrollo Desarrollo @relation(fields: [desarrolloId], references: [id], onDelete: Cascade)
parametrosJson String // JSON con la forma ParametrosDesarrollo
updatedAt DateTime @updatedAt
updatedPorId String?
}