Maintaining the Pricing Engine
When to add a strategy or rate versus refactoring the algorithm, and the configuration-first principle for the pricing subsystem.
The pricing engine is the most configuration-dense subsystem in Sixième Étoile. Before touching any code in packages/api/src/services/, determine whether the business requirement can be satisfied through configuration alone.
Configuration-first principle
The pricing engine is designed so that the majority of business changes — new pricing zones, rates, seasonal multipliers, optional fees, and margin rules — are data changes, not code changes.
Always attempt to satisfy a new pricing requirement through one of the following configuration mechanisms before writing any code:
| Mechanism | Model / table | What it controls |
|---|---|---|
| Zones | PricingZone | Geographic pricing regions (POINT, RADIUS, POLYGON) |
| Zone routes | ZoneRoute | Fixed-price routes between zone pairs |
| Zone multipliers | PricingZone.multiplier | Zone-specific price factors |
| Zone conflict strategy | ZoneConflictStrategy enum | Which zone wins when a trip crosses multiple zones |
| Multiplier aggregation | ZoneMultiplierAggregationStrategy enum | How per-zone multipliers combine |
| Optional fees | OptionalFee | Airport surcharges, waiting fees, tolls, etc. |
| Advanced rates | AdvancedRate | NIGHT / WEEKEND / HOLIDAY rate overrides |
| Seasonal multipliers | SeasonalMultiplier | Date-range price factors |
| Margins | PricingMargin | Operator margin policies |
| Cost parameters | Organization cost fields | Fuel cost, hotel/meal/second-driver daily rates |
If the requirement fits any of these rows, implement it as a database change (a new record or an updated value), not as code.
When to add a new strategy (code change)
A code change to packages/api/src/services/ is justified when:
- A new pricing algorithm is needed that cannot be expressed as a multiplier chain or a fixed price (e.g., a new
TripTypevariant that computes price differently). - A new
ZoneConflictStrategyorZoneMultiplierAggregationStrategyvariant is required that does not map to any existing enum value. - The shadow-cost calculation (segments A/B/C — fuel, tolls, wear, staffing, parking) needs a new cost component.
- A new pricing mode beyond
FIXED_GRIDandDYNAMICis required.
Procedure for adding a new strategy
- Add the new enum value in
packages/database/prisma/schema/enums.prisma(or the relevant schema file). - Create a Prisma migration — see the Data Model maintenance guide.
- Implement the strategy in the appropriate service file under
packages/api/src/services/. - Add the strategy to the pricing resolver (
packages/api/src/services/pricing/resolver.tsor equivalent). - Update the OpenAPI spec — adding a new enum value to a request/response schema requires regenerating
openapi.json. See Story 85-5. - Update the Pricing Engine documentation to document the new strategy.
When to refactor the algorithm
Refactoring the pricing algorithm is a high-risk operation that should be reserved for cases where:
- The current algorithm produces incorrect results for an entire class of trips.
- A new regulatory requirement cannot be satisfied by any configuration mechanism or an additive code change.
- Performance profiling shows the pricing calculation is a measurable bottleneck.
Before refactoring, run the full pricing test suite:
pnpm --filter api test --grep pricingAfter refactoring, verify that existing database configurations (zones, rates, multipliers) still produce the correct output for all TripType values: TRANSFER, EXCURSION, DISPO, and OFF_GRID.
Documentation impact
Pricing engine changes that add new configuration options or new strategy names must update:
- The Pricing Engine documentation pages.
- Any affected user-facing screens in the operator back-office (
apps/web) that surface the new configuration option — check the traceability matrix (FR415) for the affected pages.
See also: Pricing Engine internals · Data Model maintenance · API maintenance
Maintenance Overview
When and how to update each major subsystem, and how the FR→page traceability matrix signals when documentation itself must be updated.
Maintaining the Data Model
The Prisma schema-change procedure, backward-compatibility considerations, and when to reach for a migration versus a code change.