feat: add Warehouses + Integrations modules, /admin/configuracion page
- Schema v0.3: Warehouse + Integration models (db push applied) - WarehousesModule: CRUD, set-default, multi-warehouse support - IntegrationsModule: 26 keys across 7 groups (payment, notifications, customs, courier, marketplace, compliance, warehouse) - AuthService: suite address pulled from default Warehouse in DB (env fallback) - AuthModule: imports WarehousesModule - Seed: creates default warehouse from WAREHOUSE_ADDRESS_* env vars - Web: /admin/configuracion page (3 tabs: Bodegas, Integraciones, Estado APIs) - Web: admin layout adds Configuracion nav link - api.ts: warehouses + integrations client methods
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// Moraworld Imports — Schema v0.2 (Fase 0–1)
|
||||
// Moraworld Imports — Schema v0.3 (Fase 2 — Bodegas + Integraciones)
|
||||
// Multi-tenant por tenant_id en todas las tablas de negocio
|
||||
// Sincronizado con documentacion.html v1.1
|
||||
|
||||
@@ -90,6 +90,8 @@ model Tenant {
|
||||
preAlerts PreAlert[]
|
||||
tariffs Tariff[]
|
||||
b2bRequests B2BRequest[]
|
||||
warehouses Warehouse[]
|
||||
integrations Integration[]
|
||||
}
|
||||
|
||||
// ─── Usuarios ────────────────────────────────────────────────
|
||||
@@ -344,3 +346,57 @@ model AuditLog {
|
||||
@@index([tenantId, createdAt])
|
||||
@@index([userId])
|
||||
}
|
||||
|
||||
// ─── Bodegas (multi-bodega, doc §07 + §12) ───────────────────
|
||||
|
||||
/// Bodega física. Cada tenant puede tener varias; una es la default.
|
||||
model Warehouse {
|
||||
id String @id @default(cuid())
|
||||
tenantId String
|
||||
name String // ej: "Bodega NJ — City of Orange"
|
||||
street String // ej: "150 N Day St"
|
||||
city String // ej: "City of Orange"
|
||||
state String // ej: "NJ"
|
||||
zip String // ej: "07050"
|
||||
country String @default("US")
|
||||
phone String?
|
||||
email String?
|
||||
contactName String?
|
||||
/// Horario de operación (texto libre)
|
||||
schedule String?
|
||||
/// Capacidad aproximada (m²)
|
||||
capacityM2 Decimal? @db.Decimal(10, 2)
|
||||
isDefault Boolean @default(false)
|
||||
isActive Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([tenantId])
|
||||
}
|
||||
|
||||
// ─── Integraciones (API keys por tenant) ─────────────────────
|
||||
|
||||
/// Configuración de integraciones externas (API keys, endpoints, webhooks).
|
||||
/// El valor se almacena en texto plano en dev; en prod debe cifrarse (AES-256).
|
||||
model Integration {
|
||||
id String @id @default(cuid())
|
||||
tenantId String
|
||||
/// Clave identificadora: ej. "whatsapp_token", "senae_endpoint", "stripe_secret"
|
||||
key String
|
||||
/// Valor (API key, URL, token — cifrar en prod)
|
||||
value String?
|
||||
/// Descripción legible del campo
|
||||
label String?
|
||||
/// Grupo de integración: "payment", "notifications", "customs", "courier", "warehouse"
|
||||
group String?
|
||||
isActive Boolean @default(false)
|
||||
updatedAt DateTime @updatedAt
|
||||
updatedBy String?
|
||||
|
||||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([tenantId, key])
|
||||
@@index([tenantId, group])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user