Documento histórico
Este documento se conserva solo para trazabilidad. Consulte el índice maestro para la fuente vigente.
Documento histórico — no usar como fuente de decisiones actuales
Reemplazado por la versión canónica del 2026-07-11. Conservar solo como trazabilidad histórica.
Diagrama de clases¶
Vista UML de las entidades principales del sistema IslaBox, sus atributos, métodos y relaciones. Complementa al modelo de datos relacional agregando relaciones visuales, cardinalidad y métodos de comportamiento.
Diagrama general (Mermaid)¶
classDiagram
class User {
+Long id
+String email
+Boolean emailVerified
+String phone
+Boolean phoneVerified
+String fullName
+String countryCode = "US"
+String passwordHash
+Role role
+String referralCode
+User referredBy
+Integer level = 1
+Boolean isActive
+LocalDateTime createdAt
+String initials
+String fullNameFormatted
}
class LockerCode {
+Long id
+User user
+String prefix = "CP"
+Integer sequential
+Integer checkDigit
+String fullCode
+LockerCodeStatus status
+LocalDateTime createdAt
+String formatted()
+Boolean validate()
}
class KycRecord {
+Long id
+User user
+DocumentType documentType
+String documentNumber
+File documentFront
+File documentBack
+File selfie
+String residenceAddress
+String province
+String municipality
+KycStatus status
+LocalDateTime submittedAt
+User reviewedBy
+LocalDateTime reviewedAt
+String rejectionReason
+LocalDateTime expiresAt
+Boolean isApproved()
+Boolean isExpired()
}
class Address {
+Long id
+User user
+AddressType addressType
+String fullName
+String phone
+String alternatePhone
+String addressLine1
+String addressLine2
+String city
+String state
+String zipCode
+String country
+String province
+String municipality
+String deliveryReferences
+Boolean isDefault
}
class Recipient {
+Long id
+User user
+String fullName
+String identityDocument
+String phone
+String alternatePhone
+String addressLine1
+String province
+String municipality
+String deliveryReferences
+Boolean isSameAsUser
}
class Sender {
+Long id
+PurchaseReport purchaseReport
+String fullName
+String phone
+String email
+String addressLine1
+String city
+String state
+String zipCode
+String relationship
}
class PurchaseReport {
+Long id
+User user
+String marketplace
+String orderNumber
+LocalDate purchaseDate
+PurchaseReportStatus purchaseStatus
+String instructions
+Boolean consolidationPreference
+LocalDateTime createdAt
+String trackingSummary()
+Boolean isEditable()
}
class TrackingNumber {
+Long id
+PurchaseReport purchaseReport
+String number
+LocalDateTime addedAt
}
class PurchaseItem {
+Long id
+PurchaseReport purchaseReport
+CustomsCategory category
+String description
+Integer quantity
+BigDecimal valuePaid
+String productUrl
+String captureFileId
}
class PhysicalPackage {
+Long id
+User user
+PurchaseReport purchaseReport
+String trackingNumber
+String store
+BigDecimal weight
+String dimensions
+PackageStatus status
+String packagingCondition
+LocalDateTime arrivedAt
+WarehouseLocation location
+Integer daysInWarehouse
+BigDecimal totalStorageCharges
+Boolean isInFreePeriod()
+Integer daysToExpiration()
}
class PackageItem {
+Long id
+PhysicalPackage physicalPackage
+String description
+Integer quantity
}
class PackageEvent {
+Long id
+PhysicalPackage physicalPackage
+PackageStatus status
+String description
+User operator
+LocalDateTime createdAt
}
class PackagePhoto {
+Long id
+PhysicalPackage physicalPackage
+File file
+LocalDateTime createdAt
}
class Consolidation {
+Long id
+User user
+ConsolidationStatus status
+BigDecimal totalWeight
+BigDecimal totalValue
+Integer packageCount
+String trackingNumber
+String shippingAddressId
+LocalDateTime createdAt
}
class ConsolidationPackage {
+Long id
+Consolidation consolidation
+PhysicalPackage physicalPackage
+LocalDateTime addedAt
+String notes
}
class Shipment {
+Long id
+Consolidation consolidation
+User user
+Recipient recipient
+ShipmentStatus status
+BigDecimal weight
+String shippingType
+LocalDateTime estimatedDelivery
+String masterGuide
+String carrier
+LocalDateTime shippedAt
+LocalDateTime deliveredAt
}
class Quote {
+Long id
+Shipment shipment
+BigDecimal totalAmount
+String currency = "USD"
+LocalDateTime expiresAt
+QuoteStatus status
}
class QuoteItem {
+Long id
+Quote quote
+String description
+Integer quantity
+BigDecimal unitPrice
+BigDecimal total
}
class Payment {
+Long id
+Shipment shipment
+BigDecimal amount
+String currency
+PaymentStatus status
+PaymentMethodMix paymentMethodMix
+String transactionId
+Invoice invoice
+LocalDateTime createdAt
}
class PaymentAttempt {
+Long id
+Payment payment
+String provider
+String providerReference
+PaymentStatus status
+String errorCode
+LocalDateTime attemptedAt
}
class PaymentMethodMix {
+BigDecimal realMoney
+BigDecimal credit
+BigDecimal card
+String cardLastFour
+BigDecimal total
}
class Charge {
+Long id
+Payment payment
+String description
+BigDecimal amount
+ChargeCategory category
+String referenceId
+LocalDateTime createdAt
}
class Invoice {
+Long id
+String number
+List~Charge~ charges
+BigDecimal subtotal
+BigDecimal taxes
+BigDecimal total
+InvoiceStatus status
+LocalDateTime createdAt
+LocalDateTime dueDate
+LocalDateTime paidAt
}
class ServiceRequest {
+Long id
+PhysicalPackage physicalPackage
+ServiceType type
+ServiceStatus status
+BigDecimal cost
+LocalDateTime requestedAt
+LocalDateTime completedAt
+List~File~ evidenceFileIds
+String userNotes
+String operatorNotes
}
class Incident {
+Long id
+PhysicalPackage physicalPackage
+Shipment shipment
+IncidentType type
+IncidentStatus status
+String description
+User openedBy
+User assignedTo
+LocalDateTime createdAt
+LocalDateTime resolvedAt
}
class Notification {
+Long id
+User user
+String title
+String body
+NotificationChannel channel
+Boolean visibleToUser
+Boolean read
+LocalDateTime createdAt
}
class AuditLog {
+Long id
+String entityType
+Long entityId
+String action
+User user
+String ipAddress
+String beforeState
+String afterState
+LocalDateTime createdAt
}
class Referral {
+Long id
+User referrer
+User referred
+LocalDateTime registeredAt
+LocalDateTime windowExpiresAt
+Integer level
}
class CreditBalance {
+Long id
+User user
+BigDecimal available
+BigDecimal pending
+LocalDateTime expiresAt
}
class CreditMovement {
+Long id
+CreditBalance creditBalance
+BigDecimal amount
+String description
+MovementType type
+LocalDateTime createdAt
}
class PromoCard {
+Long id
+User user
+BigDecimal amount
+LocalDateTime issuedAt
+LocalDateTime expiresAt
+Boolean used
+LocalDateTime usedAt
}
class CustomsCategory {
+String code
+String name
+String description
+Acceptance accepted
+Boolean requiresInvoice
+Boolean requiresReview
+RiskLevel riskLevel
+Boolean allowsAir
+Boolean allowsSea
+BigDecimal dutyPercentage
+String userMessage
+String operatorMessage
}
class FileAttachment {
+UUID id
+String ownerType
+Long ownerId
+String bucket
+String objectKey
+String originalFilename
+String mimeType
+Long sizeBytes
+String checksum
+Visibility visibility
+Long uploadedBy
+LocalDateTime createdAt
+String presignedUploadUrl()
+String presignedReadUrl(userId)
}
class WarehouseLocation {
+Long id
+String zone
+String shelf
+String position
+Integer capacity
}
%% Relaciones
User "1" --> "1" LockerCode : tiene
User "1" --> "0..1" KycRecord : tiene
User "1" --> "*" Address : tiene
User "1" --> "*" Recipient : gestiona
User "1" --> "*" PurchaseReport : crea
User "1" --> "*" PhysicalPackage : recibe
User "1" --> "*" Consolidation : agrupa
User "1" --> "*" Shipment : envía
User "1" --> "*" Notification : recibe
User "1" --> "*" Referral : referidor
User "1" --> "*" Referral : referido
User "1" --> "0..1" CreditBalance : tiene
User "1" --> "*" PromoCard : tiene
User "1" --> "*" AuditLog : origina
PurchaseReport "1" --> "*" PurchaseItem : tiene
PurchaseReport "1" --> "*" TrackingNumber : tiene
PurchaseReport "1" --> "1" Sender : tiene
PurchaseReport "*" --> "1" CustomsCategory : clasifica
PhysicalPackage "1" --> "*" PackageItem : tiene
PhysicalPackage "1" --> "*" PackageEvent : tiene
PhysicalPackage "1" --> "*" PackagePhoto : tiene
PhysicalPackage "1" --> "1" WarehouseLocation : ubicado en
PhysicalPackage "1" --> "*" ServiceRequest : tiene
PhysicalPackage "*" --> "0..1" PurchaseReport : originado de
Consolidation "1" --> "*" ConsolidationPackage : agrupa
ConsolidationPackage "*" --> "1" PhysicalPackage : referencia
Shipment "1" --> "1" Consolidation : incluye
Shipment "1" --> "1" Recipient : entrega a
Shipment "1" --> "*" Payment : tiene
Shipment "1" --> "0..1" Quote : tiene
Quote "1" --> "*" QuoteItem : tiene
Payment "1" --> "*" PaymentAttempt : intentos
Payment "1" --> "1" PaymentMethodMix : métodos
Payment "1" --> "*" Charge : incluye
Payment "1" --> "0..1" Invoice : genera
CreditBalance "1" --> "*" CreditMovement : tiene
FileAttachment "1" --> "*" FileAccessLog : registra accesos
Detalle por módulos¶
Módulo 1: Identidad y autenticación¶
classDiagram
class User
class LockerCode
class KycRecord
class Address
class AuditLog
User "1" --> "1" LockerCode
User "1" --> "0..1" KycRecord
User "1" --> "*" Address
User "1" --> "*" AuditLog
Características:
- User es la raíz de identidad.
- LockerCode 1:1 (todo usuario tiene exactamente un identificador activo).
- KycRecord 1:0..1 (puede no tener KYC, o tener uno activo/vencido).
- Address 1:* (puede tener varias: casillero, residencia, etc.).
Módulo 2: Prealerta y paquete¶
classDiagram
class PurchaseReport
class PurchaseItem
class TrackingNumber
class PhysicalPackage
class PackageEvent
class CustomsCategory
class Sender
PurchaseReport "1" --> "*" PurchaseItem
PurchaseReport "1" --> "*" TrackingNumber
PurchaseReport "1" --> "1" Sender
PurchaseItem "*" --> "1" CustomsCategory
PhysicalPackage "0..1" --> "1" PurchaseReport
PhysicalPackage "1" --> "*" PackageEvent
Características:
- PurchaseReport (prealerta) puede existir sin PhysicalPackage (el paquete aún no llegó).
- Cuando el operador identifica el paquete, vincula la prealerta con el PhysicalPackage.
- Cada cambio de estado del paquete genera un PackageEvent (auditoría inmutable).
Módulo 3: Consolidación y envío¶
classDiagram
class Consolidation
class ConsolidationPackage
class PhysicalPackage
class Shipment
class Recipient
Consolidation "1" --> "*" ConsolidationPackage
ConsolidationPackage "*" --> "1" PhysicalPackage
Consolidation "1" --> "1" Shipment
Shipment "1" --> "1" Recipient
Características:
- Una Consolidation agrupa varios PhysicalPackage mediante la entidad débil ConsolidationPackage.
- Una Consolidation se traduce en un Shipment cuando se confirma.
- El Shipment tiene un único Recipient.
Módulo 4: Dinero y facturación¶
classDiagram
class Quote
class QuoteItem
class Payment
class PaymentMethodMix
class PaymentAttempt
class Charge
class Invoice
Quote "1" --> "*" QuoteItem
Shipment "1" --> "0..1" Quote
Shipment "1" --> "*" Payment
Payment "1" --> "1" PaymentMethodMix
Payment "1" --> "*" PaymentAttempt
Payment "1" --> "*" Charge
Payment "1" --> "0..1" Invoice
Características:
- Quote se genera al consolidar y tiene vigencia.
- Payment puede combinar realMoney + credit + card mediante PaymentMethodMix.
- Invoice se genera tras un pago confirmado.
- Charge desglosa cada concepto (servicio, envío, almacenaje, aduana, etc.).
Módulo 5: Crecimiento (Fase 2)¶
classDiagram
class User
class Referral
class CreditBalance
class CreditMovement
class PromoCard
User "1" --> "*" Referral : referidor
User "1" --> "*" Referral : referido
User "1" --> "0..1" CreditBalance
CreditBalance "1" --> "*" CreditMovement
User "1" --> "*" PromoCard
Características:
- Referral es una relación N:N con atributos (fecha, ventana de 180 días, nivel).
- CreditBalance 1:0..1 (puede no tener crédito aún).
- PromoCard se emite al convertir crédito.
Módulo 6: Archivos¶
classDiagram
class FileAttachment
class FileAccessLog
class KycRecord
class PhysicalPackage
class ServiceRequest
KycRecord "1" --> "0..1" FileAttachment : documentFront
KycRecord "1" --> "0..1" FileAttachment : documentBack
KycRecord "1" --> "0..1" FileAttachment : selfie
PhysicalPackage "1" --> "*" FileAttachment : photos
ServiceRequest "1" --> "*" FileAttachment : evidence
FileAttachment "1" --> "*" FileAccessLog
Características:
- FileAttachment es un patrón polimórfico: owner_type + owner_id.
- Cada acceso a un archivo privado se registra en FileAccessLog.
- Los buckets son privados y el acceso es solo con URL firmada.
Cardinalidad resumen¶
| Relación | Cardinalidad | Significado |
|---|---|---|
| User → LockerCode | 1:1 | Cada usuario tiene un identificador activo |
| User → KycRecord | 1:0..1 | Puede tener KYC o no |
| User → Address | 1:N | Múltiples direcciones (casillero, residencia) |
| User → PurchaseReport | 1:N | Múltiples prealertas |
| User → PhysicalPackage | 1:N | Múltiples paquetes |
| PurchaseReport → TrackingNumber | 1:N | Múltiples trackings por prealerta |
| PurchaseReport → PurchaseItem | 1:N | Múltiples productos por reporte |
| PhysicalPackage → PackageEvent | 1:N | Historial completo de cambios |
| Consolidation → PhysicalPackage | N:N | vía ConsolidationPackage |
| Shipment → Payment | 1:N | Múltiples pagos posibles (parcialidades) |
| Payment → PaymentAttempt | 1:N | Historial de intentos |
Notas de diseño¶
- Patrón polimórfico:
FileAttachmentusaowner_type + owner_idpara asociarse a cualquier entidad sin FK rígida. - Soft delete: entidades como
User,Recipient,PurchaseReportusandeleted_aten lugar de DELETE físico. - Inmutabilidad:
PackageEvent,AuditLog,CreditMovementson append-only. - Enums como strings: para serialización y compatibilidad con múltiples lenguajes.
- Timestamps universales: todas las fechas en UTC en BD, conversión a zona local en frontend.
Cómo se traduce a tablas SQL¶
Ver modelo de datos para el detalle relacional.