feat: add fleet-wide fuel and maintenance stats endpoints

Backend:
FuelService + FuelController:
- Added getFleetFuelStats() aggregating all vehicles
- Route: GET /api/fuel/stats (before :vehicleId route)
- Returns: totalCost, totalLiters, totalPurchases, averagePricePerLiter

MaintenanceService + MaintenanceController:
- Added getFleetMaintenanceStats() aggregating all vehicles
- Route: GET /api/maintenance/stats (before :vehicleId route)
- Returns: totalCost, numberOfMaintenanceItems, averageCostPerMaintenance, costByType

Both endpoints aggregate over past 12 months (customizable via query param).

Enables dashboard to show fleet-wide operating costs.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
natib21
2026-06-30 14:32:12 +00:00
parent 17a6d846a4
commit 558f7f38cd
4 changed files with 54 additions and 0 deletions

View File

@@ -38,6 +38,12 @@ export class MaintenanceController {
return this.maintenanceService.getMaintenanceHistory(vehicleId);
}
@Get('stats')
@ApiOperation({ summary: 'Get fleet-wide maintenance statistics' })
async getFleetStats() {
return this.maintenanceService.getFleetMaintenanceStats();
}
@Get('stats/:vehicleId')
@ApiOperation({ summary: 'Get maintenance statistics' })
async getStats(@Param('vehicleId') vehicleId: string) {

View File

@@ -55,6 +55,25 @@ export class MaintenanceService {
return this.maintenanceRepository.getMaintenanceCosts(vehicleId, startDate, endDate);
}
async getFleetMaintenanceStats(monthsBack: number = 12) {
const endDate = new Date();
const startDate = new Date(endDate.getFullYear(), endDate.getMonth() - monthsBack, 1);
const costs = await this.costRepository
.createQueryBuilder('cost')
.where('cost.incurredDate BETWEEN :startDate AND :endDate', { startDate, endDate })
.getMany();
const totalCost = costs.reduce((sum: number, c: MaintenanceCost) => sum + Number(c.costAmount), 0);
return {
totalCost,
numberOfMaintenanceItems: costs.length,
averageCostPerMaintenance: costs.length > 0 ? totalCost / costs.length : 0,
costByType: this.groupCostsByType(costs),
};
}
async getVehicleMaintenanceStats(vehicleId: string, monthsBack: number = 12) {
const endDate = new Date();
const startDate = new Date(endDate.getFullYear(), endDate.getMonth() - monthsBack, 1);