The obvious migration had a non-obvious consequence
Base fare is the anchor on which later pricing multipliers operate. The earlier path could fall back to a broader model-group price even when different variants had meaningfully different acquisition costs. That simplification made onboarding possible, but it also compressed distinctions that mattered to host economics and downstream recommendations.
Moving to the more specific source sounded like a data-quality upgrade. When I replayed it over the actual fleet, however, Zoomcar's distribution of variants sat differently across the old price-to-PPH curve. A mechanically correct migration would have lowered prices across a meaningful part of the marketplace. The source became more accurate while the business output moved in the wrong structural direction.
This article is intentionally public-safe. It explains the engineering decisions and lessons without exposing customer data, proprietary prompts, internal identifiers, operational commands or confidential decision thresholds.
- CARResolve the active asset and its variant
- VARIANTUse the specific acquisition-price record
- FALLBACKUse the broader group only when required
- VALIDATEReject missing or invalid effective prices
- PUBLISHRetain the source identity for audit
Data: define an effective source, not a fragile join
The data model joined each active car to its variant and the variant to an acquisition-price source. A broader group-level value remained available as fallback. The resulting effective price carried both the numeric value and the identity of the source used, so later validation could distinguish variant-priced cars from fallback-priced cars.
Before calculating fare, the pipeline rejected records where neither source produced a valid positive input. That guardrail mattered more than filling every row: publishing a plausible-looking zero or null-derived fare would propagate silently through every later multiplier.
Recalibrate the mathematical mapping, not the target data
I kept the variant acquisition value as the correct economic input and changed the mathematical mapping that converted car price into hourly fare. The revised function remained monotonic—a more valuable car could not become cheaper merely because it crossed a boundary—but its anchors and slopes were recalibrated against the real fleet distribution and the existing price surface.
This was not a blanket offset designed to hide movement. I compared old and proposed fares by variant, age, city and price band, inspected discontinuities and protected the parts of the distribution where a migration artefact would otherwise dominate. Depreciation, minimum protections, incremental publication and consumer contracts continued to operate around the new mapping.
Evaluation and rollout
Validation compared four surfaces: old source with old mapping, variant source with old mapping, variant source with the proposed mapping and the final published distribution. That decomposition separated movement caused by better data from movement caused by the function itself. I checked missing and invalid inputs, monotonicity, boundary jumps, price-band movement and the share of cars using fallback.
The incremental release kept the existing schedule and topic contract, reducing operational change. Logs and stored identifiers provided the post-release evidence needed to investigate individual cars without reconstructing the full join manually.
Impact
Variant-aware pricing made the base layer better aligned with the actual asset without confusing a catalogue migration for a deliberate marketplace price cut. Pricing provenance became a first-class field, and the car-price-to-PPH function became an explicitly validated piece of economic logic rather than an inherited constant.
The reusable lesson is that changing a feature's definition changes the distribution seen by every downstream formula. A schema migration can be an economic release. You have to validate the transformed output, not only congratulate the join for becoming more precise.