feat: payments module, notification templates, WA float, route fixes
- Add PaymentsModule: POST /payments/intent, POST /:id/confirm, GET /payments, GET /payments/package/:id, GET /payments/track/:trackingId
- Add Payment model to Prisma schema (PaymentStatus enum, Payment table)
- Add NotificationTemplate model + NotificationsController (GET/PUT /notification-templates, POST /notification-templates/seed)
- Update NotificationsService: DB-backed templates with variable interpolation {{trackingId}} {{firstName}} {{status}} {{suiteCode}}
- Fix /bodega/paquetes: replace 11 wrong status strings with correct §08 enum values
- Fix /admin/reportes: replace EN_CAMINO_A_ECUADOR with correct §08 statuses, rewrite report page with proper KPIs and bar charts
- Fix /portal/mis-paquetes: correct §08 statuses, add 'Pagar envío' button for VERIFICADO/DECLARACION_ADUANERA packages
- Add WhatsApp float component (_components/whatsapp-float.tsx, 2 contacts: NJ ops + Cuenca aduana)
- Add /casillero/calculadora and /casillero/registro redirects (§20)
- Add /portal/pago payment page with cost breakdown (§09/§14/§15)
- Add /admin/notificaciones page: view/edit/toggle templates per event×channel
- Admin nav: add Notificaciones link
- api.ts: add notificationTemplates.* and payments.* client methods
- schema.prisma v0.4: PaymentStatus enum, Payment model, NotificationTemplate model
- db push applied to remote DB (46.202.93.92)
- All builds pass (API nest build + Next.js build)
This commit is contained in:
@@ -11,6 +11,14 @@ datasource db {
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
enum PaymentStatus {
|
||||
PENDIENTE
|
||||
PROCESANDO
|
||||
COMPLETADO
|
||||
FALLIDO
|
||||
REEMBOLSADO
|
||||
}
|
||||
|
||||
// ─── Enums ───────────────────────────────────────────────────
|
||||
|
||||
enum UserRole {
|
||||
@@ -92,6 +100,8 @@ model Tenant {
|
||||
b2bRequests B2BRequest[]
|
||||
warehouses Warehouse[]
|
||||
integrations Integration[]
|
||||
notificationTemplates NotificationTemplate[]
|
||||
payments Payment[]
|
||||
}
|
||||
|
||||
// ─── Usuarios ────────────────────────────────────────────────
|
||||
@@ -196,6 +206,7 @@ model Package {
|
||||
statusHistory PackageStatusHistory[]
|
||||
preAlert PreAlert?
|
||||
notifications Notification[]
|
||||
payment Payment?
|
||||
|
||||
@@index([tenantId, status])
|
||||
@@index([userId])
|
||||
@@ -376,6 +387,55 @@ model Warehouse {
|
||||
@@index([tenantId])
|
||||
}
|
||||
|
||||
// ─── Pagos (§09 paso 8 / §14 paso 5) ─────────────────────────
|
||||
|
||||
/// Registro de pagos vinculados a un paquete.
|
||||
/// El `providerRef` es el PaymentIntent ID de Stripe (o equivalente).
|
||||
model Payment {
|
||||
id String @id @default(cuid())
|
||||
tenantId String
|
||||
packageId String @unique
|
||||
userId String
|
||||
amount Decimal @db.Decimal(10, 2)
|
||||
currency String @default("USD")
|
||||
/// "stripe" | "payphone" | "paypal"
|
||||
provider String @default("stripe")
|
||||
/// PaymentIntent ID de Stripe u equivalente
|
||||
providerRef String?
|
||||
status PaymentStatus @default(PENDIENTE)
|
||||
paidAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||||
package Package @relation(fields: [packageId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([tenantId, status])
|
||||
@@index([userId])
|
||||
}
|
||||
|
||||
// ─── Plantillas de notificación (§12) ────────────────────────
|
||||
|
||||
/// Plantillas de mensajes para cada evento del ciclo de vida del paquete.
|
||||
/// Soporta variables: {{trackingId}}, {{firstName}}, {{status}}, {{suiteCode}}
|
||||
model NotificationTemplate {
|
||||
id String @id @default(cuid())
|
||||
tenantId String
|
||||
/// Evento que dispara la notificación — coincide con PackageStatus
|
||||
event String // ej: "REGISTRADO", "ENTREGADO"
|
||||
channel NotificationChannel
|
||||
subject String? // Solo relevante para EMAIL
|
||||
body String
|
||||
isActive Boolean @default(true)
|
||||
updatedAt DateTime @updatedAt
|
||||
updatedBy String?
|
||||
|
||||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([tenantId, event, channel])
|
||||
@@index([tenantId, event])
|
||||
}
|
||||
|
||||
// ─── Integraciones (API keys por tenant) ─────────────────────
|
||||
|
||||
/// Configuración de integraciones externas (API keys, endpoints, webhooks).
|
||||
|
||||
Reference in New Issue
Block a user