Register all active platform services and base features in core DB so admin can manage them, add delivery/hospitality/sports-center backend phases, update apps catalog and production deploy tooling. Co-authored-by: Cursor <cursoragent@cursor.com>
168 lines
6.0 KiB
Python
168 lines
6.0 KiB
Python
"""Driver management aggregates — Phase 10.1.
|
|
|
|
UUID refs only within delivery_db. No fleet/dispatch ownership.
|
|
Identity/CRM/Storage are external refs only.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import uuid
|
|
from datetime import date, datetime
|
|
|
|
from sqlalchemy import (
|
|
Boolean,
|
|
Date,
|
|
DateTime,
|
|
Index,
|
|
String,
|
|
Text,
|
|
UniqueConstraint,
|
|
)
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
from sqlalchemy.types import JSON
|
|
|
|
from app.core.database import Base
|
|
from app.models.base import (
|
|
ActorAuditMixin,
|
|
OptimisticLockMixin,
|
|
SoftDeleteMixin,
|
|
TenantMixin,
|
|
TimestampMixin,
|
|
UUIDPrimaryKeyMixin,
|
|
)
|
|
from app.models.types import (
|
|
DriverCredentialKind,
|
|
DriverDocumentKind,
|
|
DriverLifecycleAction,
|
|
DriverStatus,
|
|
GUID,
|
|
)
|
|
|
|
|
|
class Driver(
|
|
Base,
|
|
UUIDPrimaryKeyMixin,
|
|
TenantMixin,
|
|
TimestampMixin,
|
|
SoftDeleteMixin,
|
|
ActorAuditMixin,
|
|
OptimisticLockMixin,
|
|
):
|
|
"""Courier/driver profile owned by Delivery Platform."""
|
|
|
|
__tablename__ = "drivers"
|
|
|
|
organization_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
|
|
hub_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True)
|
|
code: Mapped[str] = mapped_column(String(50), nullable=False)
|
|
display_name: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
first_name: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
|
last_name: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
|
mobile: Mapped[str | None] = mapped_column(String(32), nullable=True)
|
|
email: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
|
status: Mapped[DriverStatus] = mapped_column(
|
|
default=DriverStatus.PENDING, nullable=False
|
|
)
|
|
external_user_ref: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
|
external_crm_contact_ref: Mapped[str | None] = mapped_column(
|
|
String(100), nullable=True
|
|
)
|
|
hire_date: Mapped[date | None] = mapped_column(Date, nullable=True)
|
|
notes: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
capability_tags: Mapped[list | None] = mapped_column(JSON, nullable=True)
|
|
metadata_json: Mapped[dict | None] = mapped_column(JSON, nullable=True)
|
|
status_reason: Mapped[str | None] = mapped_column(String(500), nullable=True)
|
|
status_changed_at: Mapped[datetime | None] = mapped_column(
|
|
DateTime(timezone=True), nullable=True
|
|
)
|
|
|
|
__table_args__ = (
|
|
UniqueConstraint("tenant_id", "code", name="uq_drivers_tenant_code"),
|
|
Index("ix_drivers_tenant_status", "tenant_id", "status"),
|
|
Index("ix_drivers_org", "tenant_id", "organization_id"),
|
|
Index("ix_drivers_hub", "tenant_id", "hub_id"),
|
|
Index("ix_drivers_mobile", "tenant_id", "mobile"),
|
|
Index("ix_drivers_tenant_deleted", "tenant_id", "is_deleted"),
|
|
Index("ix_drivers_display_name", "tenant_id", "display_name"),
|
|
)
|
|
|
|
|
|
class DriverCredential(
|
|
Base,
|
|
UUIDPrimaryKeyMixin,
|
|
TenantMixin,
|
|
TimestampMixin,
|
|
SoftDeleteMixin,
|
|
ActorAuditMixin,
|
|
):
|
|
"""Credential / compliance refs for a driver (binaries via Storage refs)."""
|
|
|
|
__tablename__ = "driver_credentials"
|
|
|
|
driver_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
|
|
kind: Mapped[DriverCredentialKind] = mapped_column(
|
|
default=DriverCredentialKind.LICENSE, nullable=False
|
|
)
|
|
number: Mapped[str] = mapped_column(String(100), nullable=False)
|
|
issued_at: Mapped[date | None] = mapped_column(Date, nullable=True)
|
|
expires_at: Mapped[date | None] = mapped_column(Date, nullable=True)
|
|
is_verified: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
|
|
document_file_ref: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
|
metadata_json: Mapped[dict | None] = mapped_column(JSON, nullable=True)
|
|
|
|
__table_args__ = (
|
|
UniqueConstraint(
|
|
"tenant_id",
|
|
"driver_id",
|
|
"kind",
|
|
"number",
|
|
name="uq_driver_credentials_tenant_kind_number",
|
|
),
|
|
Index("ix_driver_credentials_driver", "tenant_id", "driver_id"),
|
|
Index("ix_driver_credentials_tenant_deleted", "tenant_id", "is_deleted"),
|
|
)
|
|
|
|
|
|
class DriverDocument(
|
|
Base,
|
|
UUIDPrimaryKeyMixin,
|
|
TenantMixin,
|
|
TimestampMixin,
|
|
SoftDeleteMixin,
|
|
ActorAuditMixin,
|
|
):
|
|
"""Driver document metadata — Storage owns file blobs."""
|
|
|
|
__tablename__ = "driver_documents"
|
|
|
|
driver_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
|
|
kind: Mapped[DriverDocumentKind] = mapped_column(
|
|
default=DriverDocumentKind.OTHER, nullable=False
|
|
)
|
|
title: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
storage_file_ref: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
notes: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
|
|
__table_args__ = (
|
|
Index("ix_driver_documents_driver", "tenant_id", "driver_id"),
|
|
Index("ix_driver_documents_tenant_deleted", "tenant_id", "is_deleted"),
|
|
)
|
|
|
|
|
|
class DriverLifecycleEvent(Base, UUIDPrimaryKeyMixin, TenantMixin, TimestampMixin):
|
|
"""Append-only driver lifecycle history."""
|
|
|
|
__tablename__ = "driver_lifecycle_events"
|
|
|
|
driver_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
|
|
action: Mapped[DriverLifecycleAction] = mapped_column(nullable=False)
|
|
from_status: Mapped[DriverStatus] = mapped_column(nullable=False)
|
|
to_status: Mapped[DriverStatus] = mapped_column(nullable=False)
|
|
reason: Mapped[str | None] = mapped_column(String(500), nullable=True)
|
|
actor_user_id: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
|
metadata_json: Mapped[dict | None] = mapped_column(JSON, nullable=True)
|
|
|
|
__table_args__ = (
|
|
Index("ix_driver_lifecycle_driver", "tenant_id", "driver_id"),
|
|
Index("ix_driver_lifecycle_created", "tenant_id", "created_at"),
|
|
)
|