erp-mecanicas-diesel-backen.../src/modules/dispatch/entities/unit-status.entity.ts
Adrian Flores Cortes 7e0d4ee841 feat(MMD-011): Implement Dispatch Center module
Add complete dispatch module for incident assignment:

Entities (7):
- DispatchBoard: Board configuration
- UnitStatus: Real-time unit state
- TechnicianSkill: Skills and certifications
- TechnicianShift: Shift schedules
- DispatchRule: Assignment rules
- EscalationRule: Escalation rules
- DispatchLog: Audit trail

Services (4):
- DispatchService: Unit management, assignments, suggestions
- SkillService: Skill CRUD, validation, matrix
- ShiftService: Shift management, availability
- RuleService: Dispatch and escalation rules

Controllers (4):
- DispatchController: /api/v1/dispatch
- SkillController: /api/v1/dispatch/skills
- ShiftController: /api/v1/dispatch/shifts
- RuleController: /api/v1/dispatch/rules

Integrated in main.ts with routes and documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 02:21:40 -06:00

112 lines
2.8 KiB
TypeScript

/**
* UnitStatus Entity
* Mecanicas Diesel - ERP Suite
*
* Real-time status of fleet units for dispatch.
* Module: MMD-011 Dispatch Center
*/
import {
Entity,
PrimaryGeneratedColumn,
Column,
UpdateDateColumn,
Index,
} from 'typeorm';
export enum UnitStatusEnum {
AVAILABLE = 'available',
ASSIGNED = 'assigned',
EN_ROUTE = 'en_route',
ON_SITE = 'on_site',
RETURNING = 'returning',
OFFLINE = 'offline',
MAINTENANCE = 'maintenance',
}
export enum UnitCapacity {
LIGHT = 'light',
MEDIUM = 'medium',
HEAVY = 'heavy',
}
@Entity({ name: 'unit_statuses', schema: 'dispatch' })
@Index('idx_unit_statuses_tenant_unit', ['tenantId', 'unitId'], { unique: true })
@Index('idx_unit_statuses_status', ['tenantId', 'status'])
export class UnitStatus {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ name: 'tenant_id', type: 'uuid' })
tenantId: string;
// Unit reference
@Column({ name: 'unit_id', type: 'uuid' })
unitId: string;
@Column({ name: 'unit_code', type: 'varchar', length: 50, nullable: true })
unitCode?: string;
@Column({ name: 'unit_name', type: 'varchar', length: 100, nullable: true })
unitName?: string;
// Status
@Column({
type: 'varchar',
length: 20,
default: UnitStatusEnum.OFFLINE,
})
status: UnitStatusEnum;
// Current assignment
@Column({ name: 'current_incident_id', type: 'uuid', nullable: true })
currentIncidentId?: string;
@Column({ name: 'current_technician_ids', type: 'uuid', array: true, default: [] })
currentTechnicianIds: string[];
// Location (cached from GPS)
@Column({ name: 'last_position_id', type: 'uuid', nullable: true })
lastPositionId?: string;
@Column({ name: 'last_known_lat', type: 'decimal', precision: 10, scale: 7, nullable: true })
lastKnownLat?: number;
@Column({ name: 'last_known_lng', type: 'decimal', precision: 10, scale: 7, nullable: true })
lastKnownLng?: number;
@Column({ name: 'last_location_update', type: 'timestamptz', nullable: true })
lastLocationUpdate?: Date;
// Timing
@Column({ name: 'last_status_change', type: 'timestamptz', default: () => 'NOW()' })
lastStatusChange: Date;
@Column({ name: 'estimated_available_at', type: 'timestamptz', nullable: true })
estimatedAvailableAt?: Date;
// Capacity and capabilities
@Column({
name: 'unit_capacity',
type: 'varchar',
length: 20,
default: UnitCapacity.LIGHT,
})
unitCapacity: UnitCapacity;
@Column({ name: 'can_tow', type: 'boolean', default: false })
canTow: boolean;
@Column({ name: 'max_tow_weight_kg', type: 'integer', nullable: true })
maxTowWeightKg?: number;
@Column({ type: 'text', nullable: true })
notes?: string;
@Column({ type: 'jsonb', default: {} })
metadata: Record<string, any>;
@UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
updatedAt: Date;
}