Files
Horux360/docs/architecture/database-schema.prisma
Consultoria AS e0c97cb3b6 Initial commit: Horux360 SaaS design documentation
- Complete design document with architecture, data models, and API specs
- Database schema (Prisma) for multi-tenant PostgreSQL
- README with project overview and plans
- Support for 4 visual themes (Light, Vibrant, Corporate, Dark)
- Comprehensive module specifications:
  - Dashboard with KPIs
  - CFDI management
  - IVA/ISR tax control
  - Bank reconciliation
  - Fiscal calendar
  - User management with roles

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 01:28:58 +00:00

278 lines
7.5 KiB
Plaintext

// Horux360 - Database Schema
// PostgreSQL with Multi-tenant (schema per tenant)
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// ============================================
// PUBLIC SCHEMA - Shared across all tenants
// ============================================
model Tenant {
id String @id @default(uuid())
nombre String
rfc String @unique
plan Plan @default(starter)
schemaName String @unique @map("schema_name")
cfdiLimit Int @map("cfdi_limit")
usersLimit Int @map("users_limit")
active Boolean @default(true)
createdAt DateTime @default(now()) @map("created_at")
expiresAt DateTime? @map("expires_at")
users User[]
@@map("tenants")
}
model User {
id String @id @default(uuid())
tenantId String @map("tenant_id")
email String @unique
passwordHash String @map("password_hash")
nombre String
role Role @default(visor)
active Boolean @default(true)
lastLogin DateTime? @map("last_login")
createdAt DateTime @default(now()) @map("created_at")
tenant Tenant @relation(fields: [tenantId], references: [id])
@@map("users")
}
enum Plan {
starter
business
professional
enterprise
}
enum Role {
admin
contador
visor
}
// ============================================
// TENANT SCHEMA - Isolated per tenant
// These models exist in each tenant's schema
// ============================================
// Note: The following models are defined for documentation
// They will be created dynamically in each tenant schema
model Cuenta {
id Int @id @default(autoincrement())
codigo String
nombre String
tipo TipoCuenta
padreId Int? @map("padre_id")
active Boolean @default(true)
padre Cuenta? @relation("CuentaHijos", fields: [padreId], references: [id])
hijos Cuenta[] @relation("CuentaHijos")
@@map("cuentas")
}
enum TipoCuenta {
activo
pasivo
capital
ingreso
egreso
}
model Cfdi {
id String @id @default(uuid())
uuidFiscal String @unique @map("uuid_fiscal")
tipo TipoCfdi
serie String?
folio String?
fechaEmision DateTime @map("fecha_emision")
fechaTimbrado DateTime @map("fecha_timbrado")
rfcEmisor String @map("rfc_emisor")
nombreEmisor String @map("nombre_emisor")
rfcReceptor String @map("rfc_receptor")
nombreReceptor String @map("nombre_receptor")
subtotal Decimal @db.Decimal(18, 2)
descuento Decimal @default(0) @db.Decimal(18, 2)
iva Decimal @default(0) @db.Decimal(18, 2)
isrRetenido Decimal @default(0) @map("isr_retenido") @db.Decimal(18, 2)
ivaRetenido Decimal @default(0) @map("iva_retenido") @db.Decimal(18, 2)
total Decimal @db.Decimal(18, 2)
moneda String @default("MXN")
tipoCambio Decimal @default(1) @map("tipo_cambio") @db.Decimal(10, 4)
metodoPago String? @map("metodo_pago")
formaPago String? @map("forma_pago")
usoCfdi String? @map("uso_cfdi")
estado EstadoCfdi @default(vigente)
xmlUrl String? @map("xml_url")
pdfUrl String? @map("pdf_url")
createdAt DateTime @default(now()) @map("created_at")
conceptos CfdiConcepto[]
movimientos MovimientoBancario[]
@@map("cfdis")
}
enum TipoCfdi {
ingreso
egreso
traslado
pago
nomina
}
enum EstadoCfdi {
vigente
cancelado
}
model CfdiConcepto {
id Int @id @default(autoincrement())
cfdiId String @map("cfdi_id")
claveProducto String @map("clave_producto")
descripcion String
cantidad Decimal @db.Decimal(10, 2)
unidad String
valorUnitario Decimal @map("valor_unitario") @db.Decimal(18, 2)
importe Decimal @db.Decimal(18, 2)
descuento Decimal @default(0) @db.Decimal(18, 2)
objetoImpuesto String? @map("objeto_impuesto")
cfdi Cfdi @relation(fields: [cfdiId], references: [id])
@@map("cfdi_conceptos")
}
model IvaMensual {
id Int @id @default(autoincrement())
año Int
mes Int
ivaTrasladado Decimal @map("iva_trasladado") @db.Decimal(18, 2)
ivaAcreditable Decimal @map("iva_acreditable") @db.Decimal(18, 2)
ivaRetenido Decimal @default(0) @map("iva_retenido") @db.Decimal(18, 2)
resultado Decimal @db.Decimal(18, 2)
acumulado Decimal @db.Decimal(18, 2)
estado EstadoDeclaracion @default(pendiente)
fechaDeclaracion DateTime? @map("fecha_declaracion")
@@unique([año, mes])
@@map("iva_mensual")
}
model IsrMensual {
id Int @id @default(autoincrement())
año Int
mes Int
ingresosAcumulados Decimal @map("ingresos_acumulados") @db.Decimal(18, 2)
deducciones Decimal @db.Decimal(18, 2)
baseGravable Decimal @map("base_gravable") @db.Decimal(18, 2)
isrCausado Decimal @map("isr_causado") @db.Decimal(18, 2)
isrRetenido Decimal @map("isr_retenido") @db.Decimal(18, 2)
isrAPagar Decimal @map("isr_a_pagar") @db.Decimal(18, 2)
estado EstadoDeclaracion @default(pendiente)
fechaDeclaracion DateTime? @map("fecha_declaracion")
@@unique([año, mes])
@@map("isr_mensual")
}
enum EstadoDeclaracion {
pendiente
declarado
acreditado
}
model MovimientoBancario {
id Int @id @default(autoincrement())
banco String
cuenta String
fecha DateTime
referencia String?
descripcion String
tipo TipoMovimiento
monto Decimal @db.Decimal(18, 2)
saldo Decimal @db.Decimal(18, 2)
cfdiId String? @map("cfdi_id")
estadoConciliacion EstadoConciliacion @default(pendiente) @map("estado_conciliacion")
notas String?
cfdi Cfdi? @relation(fields: [cfdiId], references: [id])
@@map("movimientos_bancarios")
}
enum TipoMovimiento {
cargo
abono
}
enum EstadoConciliacion {
pendiente
conciliado
error
}
model Alerta {
id Int @id @default(autoincrement())
tipo TipoAlerta
titulo String
mensaje String
prioridad Prioridad @default(media)
fechaVencimiento DateTime? @map("fecha_vencimiento")
leida Boolean @default(false)
resuelta Boolean @default(false)
createdAt DateTime @default(now()) @map("created_at")
@@map("alertas")
}
enum TipoAlerta {
vencimiento
discrepancia
iva_favor
declaracion
}
enum Prioridad {
alta
media
baja
}
model CalendarioFiscal {
id Int @id @default(autoincrement())
titulo String
descripcion String?
tipo TipoObligacion
fechaLimite DateTime @map("fecha_limite")
recurrencia Recurrencia @default(unica)
completado Boolean @default(false)
notas String?
@@map("calendario_fiscal")
}
enum TipoObligacion {
declaracion
pago
obligacion
}
enum Recurrencia {
mensual
bimestral
anual
unica
}