feat: add maintenance tracking module foundation

Entities:
- MaintenanceSchedule: track preventive/corrective maintenance
- MaintenanceCost: record actual maintenance expenses

DTOs:
- CreateMaintenanceScheduleDto: schedule maintenance
- CreateMaintenanceCostDto: log costs
- UpdateMaintenanceScheduleDto: mark complete/adjust cost

Repository:
- getUpcomingMaintenance(): find due maintenance
- getMaintenanceCosts(): historical costs by date
- getTotalMaintenanceCost(): aggregate spending

Also fixed fuel-consumption.entity.ts: totalDistanceKm default 0

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
natib21
2026-06-30 12:17:17 +00:00
parent 5d70c3b557
commit e59a77b859
4 changed files with 245 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
import { IsUUID, IsString, IsDateString, IsNumber, IsOptional, IsEnum } from 'class-validator';
import { MaintenanceType, MaintenanceStatus } from '../entities/maintenance-schedule.entity';
export class CreateMaintenanceScheduleDto {
@IsUUID()
vehicleId!: string;
@IsEnum(MaintenanceType)
maintenanceType!: MaintenanceType;
@IsString()
description!: string;
@IsDateString()
scheduledDate!: string;
@IsOptional()
@IsNumber()
estimatedCost?: number;
@IsOptional()
@IsString()
serviceProvider?: string;
@IsOptional()
@IsString()
notes?: string;
@IsOptional()
@IsNumber()
nextDueKm?: number;
@IsOptional()
@IsDateString()
nextDueDate?: string;
}
export class CreateMaintenanceCostDto {
@IsUUID()
vehicleId!: string;
@IsOptional()
@IsUUID()
maintenanceScheduleId?: string;
@IsDateString()
incurredDate!: string;
@IsNumber()
costAmount!: number;
@IsString()
costType!: string;
@IsString()
description!: string;
@IsOptional()
@IsString()
serviceProvider?: string;
@IsOptional()
@IsString()
invoiceNumber?: string;
@IsOptional()
@IsString()
notes?: string;
}
export class UpdateMaintenanceScheduleDto {
@IsOptional()
@IsEnum(MaintenanceStatus)
status?: MaintenanceStatus;
@IsOptional()
@IsDateString()
completedDate?: string;
@IsOptional()
@IsNumber()
actualCost?: number;
@IsOptional()
@IsString()
notes?: string;
}