Summary\n\nReplaces the NHTSA vPIC API integration for VIN string decoding with Google Gemini, routed through the Python OCR microservice (mvp-ocr).\n\n### Changes\n- M1 (#224): New POST /decode/vin endpoint on OCR service using GeminiEngine.decode_vin()\n- M2 (#225): VinDecodeResponse type and OcrClient.decodeVin() method (JSON POST)\n- M3 (#226): Rewired VehiclesController to use OcrClient instead of NHTSAClient, moved cache logic to VehiclesService with format-aware reads, renamed nhtsaValue to sourceValue\n- M4 (#227): Deleted vehicles/external/nhtsa/ (3 files), removed VPICVariable/VPICResponse, updated 16 doc files\n- M5 (#228): Renamed nhtsaValue to sourceValue in frontend types/components, updated guide pages\n\n### Key Design Decisions\n- No TRUNCATE migration: Format-aware cache reads (check for success field) let old NHTSA entries expire naturally via 1-year TTL\n- Separate decode router: POST /decode/vin on its own router (not on /extract) since VIN decode accepts JSON, not multipart\n- Error codes: OCR service returns 400/422/503; backend maps 503/422 to 502\n\nFixes #223\nFixes #224\nFixes #225\nFixes #226\nFixes #227\nFixes #228\n\n## Test Plan\n- [x] Backend TypeScript compiles clean (0 errors)\n- [x] Frontend TypeScript compiles clean (0 errors)\n- [x] Backend lint: 0 errors (544 pre-existing warnings)\n- [x] Frontend lint: 0 errors (227 pre-existing warnings)\n- [x] OCR Python tests: 31 pass (13 new VIN decode + 18 existing)\n- [x] Zero NHTSA references in codebase (verified via grep)\n- [ ] Container integration test: VIN decode end-to-end\n- [ ] Existing OCR image-based VIN extraction unaffected
## Summary\n\nReplaces the NHTSA vPIC API integration for VIN string decoding with Google Gemini, routed through the Python OCR microservice (mvp-ocr).\n\n### Changes\n- **M1** (#224): New `POST /decode/vin` endpoint on OCR service using `GeminiEngine.decode_vin()`\n- **M2** (#225): `VinDecodeResponse` type and `OcrClient.decodeVin()` method (JSON POST)\n- **M3** (#226): Rewired `VehiclesController` to use `OcrClient` instead of `NHTSAClient`, moved cache logic to `VehiclesService` with format-aware reads, renamed `nhtsaValue` to `sourceValue`\n- **M4** (#227): Deleted `vehicles/external/nhtsa/` (3 files), removed `VPICVariable`/`VPICResponse`, updated 16 doc files\n- **M5** (#228): Renamed `nhtsaValue` to `sourceValue` in frontend types/components, updated guide pages\n\n### Key Design Decisions\n- **No TRUNCATE migration**: Format-aware cache reads (check for `success` field) let old NHTSA entries expire naturally via 1-year TTL\n- **Separate decode router**: `POST /decode/vin` on its own router (not on `/extract`) since VIN decode accepts JSON, not multipart\n- **Error codes**: OCR service returns 400/422/503; backend maps 503/422 to 502\n\nFixes #223\nFixes #224\nFixes #225\nFixes #226\nFixes #227\nFixes #228\n\n## Test Plan\n- [x] Backend TypeScript compiles clean (0 errors)\n- [x] Frontend TypeScript compiles clean (0 errors)\n- [x] Backend lint: 0 errors (544 pre-existing warnings)\n- [x] Frontend lint: 0 errors (227 pre-existing warnings)\n- [x] OCR Python tests: 31 pass (13 new VIN decode + 18 existing)\n- [x] Zero NHTSA references in codebase (verified via grep)\n- [ ] Container integration test: VIN decode end-to-end\n- [ ] Existing OCR image-based VIN extraction unaffected
Add POST /decode/vin endpoint using Gemini 2.5 Flash for VIN string
decoding. Returns structured vehicle data (year, make, model, trim,
body/drive/fuel type, engine, transmission) with confidence score.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add VinDecodeResponse type and OcrClient.decodeVin() method that sends
JSON POST to the new /decode/vin OCR endpoint. Unlike other OCR methods,
this uses JSON body instead of multipart since there is no file upload.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Replace NHTSAClient with OcrClient in vehicles controller. Move cache
logic into VehiclesService with format-aware reads (Gemini vs legacy
NHTSA entries). Rename nhtsaValue to sourceValue in MatchedField.
Remove vpic config from Zod schema and YAML config files.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Delete vehicles/external/nhtsa/ directory (3 files), remove VPICVariable
and VPICResponse from platform models. Update all documentation to
reflect Gemini VIN decode via OCR service architecture.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Rename nhtsaValue to sourceValue in frontend MatchedField type and
VinOcrReviewModal component. Update NHTSA references to vehicle
database across guide pages, hooks, and API documentation.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Prevent lower-confidence Gemini results from overwriting higher-confidence
cache entries, add reverse-contains matching so values like "X5 xDrive35i"
match DB option "X5", and show amber hint when dropdown matching fails.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary\n\nReplaces the NHTSA vPIC API integration for VIN string decoding with Google Gemini, routed through the Python OCR microservice (mvp-ocr).\n\n### Changes\n- M1 (#224): New
POST /decode/vinendpoint on OCR service usingGeminiEngine.decode_vin()\n- M2 (#225):VinDecodeResponsetype andOcrClient.decodeVin()method (JSON POST)\n- M3 (#226): RewiredVehiclesControllerto useOcrClientinstead ofNHTSAClient, moved cache logic toVehiclesServicewith format-aware reads, renamednhtsaValuetosourceValue\n- M4 (#227): Deletedvehicles/external/nhtsa/(3 files), removedVPICVariable/VPICResponse, updated 16 doc files\n- M5 (#228): RenamednhtsaValuetosourceValuein frontend types/components, updated guide pages\n\n### Key Design Decisions\n- No TRUNCATE migration: Format-aware cache reads (check forsuccessfield) let old NHTSA entries expire naturally via 1-year TTL\n- Separate decode router:POST /decode/vinon its own router (not on/extract) since VIN decode accepts JSON, not multipart\n- Error codes: OCR service returns 400/422/503; backend maps 503/422 to 502\n\nFixes #223\nFixes #224\nFixes #225\nFixes #226\nFixes #227\nFixes #228\n\n## Test Plan\n- [x] Backend TypeScript compiles clean (0 errors)\n- [x] Frontend TypeScript compiles clean (0 errors)\n- [x] Backend lint: 0 errors (544 pre-existing warnings)\n- [x] Frontend lint: 0 errors (227 pre-existing warnings)\n- [x] OCR Python tests: 31 pass (13 new VIN decode + 18 existing)\n- [x] Zero NHTSA references in codebase (verified via grep)\n- [ ] Container integration test: VIN decode end-to-end\n- [ ] Existing OCR image-based VIN extraction unaffected