Services layer
このコンテンツはまだ日本語訳がありません。
Business logic does not live in API routes. API routes are thin wrappers. Logic lives in src/lib/services/.
The five services
FleetService.ts
The big one. Aggregates fleet-wide metrics for the home page, EU ETS dashboard, and FuelEU dashboard. Methods include:
getFleetSummary(year, ytd?)— KPIs for the home pagegetFleetVessels(year)— per-vessel metrics for the fleet tablegetFleetEmissionsDaily(year)— daily timeline for the home page chartgetEUETSCost(year)— fleet-wide ETS cost projectiongetFuelEUCompliance(year)— fleet-wide GHG intensity, balance, penalty
Has a 30-second request-level cache for the expensive EU metrics queries.
VoyageSegmentService.ts
Voyage segmentation used by every page that touches voyages. Methods:
getVesselVoyageSegments(imo, year)— list of segments with EU metrics, fuel breakdown, CII per segmentgetFleetVoyages(year)— flat list of all segments across fleet for ETS dashboard
Wraps extractVoyageLegs() from portClassifier.ts and adds caching and aggregation.
VesselService.ts
Per-vessel reads:
getVesselDetails(imo)— header infogetVesselAnnualSummary(imo, year)— vessel detail page datagetVesselCIIDaily(imo, year)— rolling CII chart datagetVesselPositions(imo, year)— Maps page positions
UploadService.ts
Two flows:
previewUpload(buffer, vesselId)— parse, validate, count duplicates, return previewcommitUpload(buffer, vesselId)— same parse + actual insert
ReportExportService.ts
PDF generation for the five regulatory reports. Each method takes the same inputs the dashboard already has access to:
generateIMODCS(imo, year)generateCIIStatement(imo, year)generateEUMRV(imo, year)generateEUETSReport(year)(fleet-level)generateFuelEUReport(year)(fleet-level)
Why services, not API-route logic
- Reuse.
VoyageSegmentServiceis called from 4 different API routes. Putting logic in routes would mean copy-paste. - Testability. Services are pure-ish; routes are coupled to
Request/Response. - Same code path everywhere. Reports use the same service the dashboard uses. No “report-time” recalculation drift.
Caching strategy
FleetService has a 30-second in-process cache keyed on year + ytd. Multiple parallel requests during a single dashboard load (summary + vessels + emissions-daily) all hit the same cached intermediate computations.
Calculator utilities
The services delegate the actual maths to pure utility files:
src/lib/utils/ciiCalculator.tssrc/lib/utils/fuelEUCalculator.tssrc/lib/utils/portClassifier.ts
These are zero-dependency TypeScript modules — they’re imported by services, by API routes, and by the methodology page’s interactive calculators.