Skip to content

Domain Model

ER Diagram

Fuente canónica: docs/assets/diagrams/schema.dbml. Regenerar con scripts/update-diagram.sh tras cada migración Alembic.

Core Entities

Tenant

The top-level organization (company) using the platform.

Tenant
├── id: UUID (PK)
├── name: String
├── flight_notification_level: Enum
└── created_at: DateTime

User

Platform users belonging to tenants.

User
├── id: UUID (PK)
├── email: String (unique)
├── hashed_password: String
├── tenant_id: UUID (FK → Tenant)
├── role_id: UUID (FK → Role)
└── is_active: Boolean

Recipient

Package recipients (accessed via recipient_id from shipment and package).

Recipient
├── id: UUID (PK)
├── tenant_id: UUID (FK → Tenant)
├── name: String
├── dni: String (optional)
├── email: String
└── phone: String

Shipment

A shipment contains multiple packages and is the main tracking unit.

Shipment
├── id: UUID (PK)
├── tenant_id: UUID (FK → Tenant)
├── tracking_id: String (unique)
├── recipient_id: UUID (FK → Recipient, optional) -- set if all packages have same recipient
├── sender_name: String
├── sender_phone: String
├── origin: String
├── destination: String
├── status: ShipmentStatus enum
├── payment_status: PaymentStatus enum
├── bag_id: UUID (FK → Bag, optional)
├── estimated_arrival: DateTime
└── created_at: DateTime

Relationships:
└── recipient_id → Recipient.name (denormalized for performance)

Package

Individual items within a shipment. Can have different recipients.

Package
├── id: UUID (PK)
├── tenant_id: UUID (FK → Tenant)
├── shipment_id: UUID (FK → Shipment)
├── recipient_id: UUID (FK → Recipient, optional) -- for multi-recipient shipments
├── qr_code: String (unique)
├── weight: Float
├── category: String
├── status: PackageStatus enum
└── created_at: DateTime

Relationships:
└── recipient_id → Recipient.name (via join)

Bag

Container for shipments during transport.

Bag
├── id: UUID (PK)
├── user_id: UUID (FK → User - courier)
├── route: String
├── departure_date: DateTime
├── capacity_kg: Float
├── current_weight: Float
└── status: BagStatus enum

Relationships:
├── BagShipment → Shipment (N:N)
└── BagFlight → Flight (N:N)

Flight

A flight associated with a bag.

Flight
├── id: UUID (PK)
├── flight_number: String
├── origin: String (airport code)
├── destination: String (airport code)
├── departure_date: DateTime
├── airline: String
├── flight_status: FlightStatus enum
└── bag_id: UUID (FK → Bag, optional)

Courier

Delivery person associated with a user.

Courier
├── id: UUID (PK)
├── user_id: UUID (FK → User)
├── tenant_id: UUID (FK → Tenant)
├── full_name: String
├── passport_number: String
├── phone: String
├── status: CourierStatus enum
└── rating: Float

Relationships Diagram

Tenant (1) ──────┬──> (N) User
                 ├──> (N) Shipment ───> (N) Package
                 │          │                    │
                 │          │                    └──> (FK) Recipient
                 │          │
                 │          └──> (N) BagAssignment ──> (N) Bag ──> (N) Flight
                 ├──> (N) Recipient ───> (N) Package
                 ├──> (N) Warehouse
                 └──> (N) Courier

Business Rules

Multi-Recipient Shipments

  1. Same recipient for all packages: Shipment.recipient_id is set, Package.recipient_id is NULL
  2. Different recipients: Shipment.recipient_id is NULL, each Package.recipient_id is set

Recipient Data

  • recipient_name is stored in Recipient table, accessed via recipient_id
  • recipient_name is also denormalized in Shipment for query performance
  • recipient_email and recipient_phone can be stored at shipment level for convenience

Status Flow

See Workflows for detailed status transitions.

Audit Fields

All tables include: - _created_at: UTC timestamp of creation - _updated_at: UTC timestamp of last update (auto via DB trigger) - _user_created: Who created the record (UUID, "SYSTEM", "WEBHOOK:*") - _user_updated: Who last modified the record

Entity-to-Repository Mapping

Entity saas-shared (Schema) saas-backend (Model) saas-frontend (Entity)
Shipment ShipmentSchema ShipmentModel Shipment (frozen dataclass)
Package PackageSchema PackageModel Package (frozen dataclass)
Bag BagSchema BagModel Bag (frozen dataclass)
Flight FlightSchema FlightModel Flight (frozen dataclass)
Courier CourierSchema CourierModel Courier (frozen dataclass)
User UserSchema UserModel User (frozen dataclass)
Tenant TenantSchema TenantModel Tenant (frozen dataclass)
Recipient RecipientSchema RecipientModel Recipient (frozen dataclass)

Ver también: Database Schema · ER Diagram · Glossary