feat: Replace NHTSA VIN decode with Google Gemini via OCR service (#223) #229

Merged
egullickson merged 9 commits from issue-223-replace-nhtsa-vin-decode-gemini into main 2026-02-20 03:10:48 +00:00
Owner

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
egullickson added 5 commits 2026-02-19 03:53:19 +00:00
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
feat: update frontend for Gemini VIN decode (refs #228)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 6m31s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 23s
Deploy to Staging / Verify Staging (pull_request) Successful in 9s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 8s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
d96736789e
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 <noreply@anthropic.com>
egullickson added 1 commit 2026-02-20 02:15:04 +00:00
fix: resolve VIN decode cache race, fuzzy matching, and silent failure (refs #229)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 6m31s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 52s
Deploy to Staging / Verify Staging (pull_request) Successful in 9s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 8s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
361f58d7c6
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 <noreply@anthropic.com>
egullickson added 1 commit 2026-02-20 02:35:15 +00:00
chore: Change to Gemini 3.0 Flash
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 36s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 21s
Deploy to Staging / Verify Staging (pull_request) Successful in 8s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
5bb44be8bc
egullickson added 1 commit 2026-02-20 02:36:42 +00:00
chore: Gemini 3.0 Flash Preview model
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 33s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 51s
Deploy to Staging / Verify Staging (pull_request) Successful in 8s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 8s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
bf6742f6ea
egullickson added 1 commit 2026-02-20 02:59:48 +00:00
chore: change google region
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 38s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 51s
Deploy to Staging / Verify Staging (pull_request) Successful in 9s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 8s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
781241966c
egullickson merged commit d9df9193dc into main 2026-02-20 03:10:48 +00:00
egullickson deleted branch issue-223-replace-nhtsa-vin-decode-gemini 2026-02-20 03:10:48 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: egullickson/motovaultpro#229