feat: Add VIN decoding with NHTSA vPIC API (#9) #24

Merged
egullickson merged 6 commits from issue-9-vin-decoding into main 2026-01-11 22:22:36 +00:00
Owner

Summary

  • Add VIN decode button to Add/Edit Vehicle dialogs that calls NHTSA vPIC API
  • Pro/Enterprise tier restriction via existing tier gating system
  • Tiered confidence matching (high/medium/none) for dropdown population
  • Only populates empty fields (preserves user input)
  • Responsive layout: stacks on mobile, inline on desktop

Fixes #9

Changes

Backend

  • NHTSA Client (external/nhtsa/): axios-based client with VIN validation, 5s timeout, caching in vin_cache table
  • VIN Decode Endpoint (POST /api/vehicles/decode-vin): Tier-gated endpoint with proper error handling (400, 403, 502, 504)
  • Dropdown Matching: Case-insensitive exact matching against existing dropdown options
  • Feature Config: Added vehicle.vinDecode feature key with Pro minimum tier

Frontend

  • Decode Button: Next to VIN input with loading state and error handling
  • Tier Check: Uses useTierAccess() hook with UpgradeRequiredDialog
  • Field Population: Only populates empty fields based on confidence level

Test Plan

  • Decode valid VIN as Pro user - fields populated
  • Decode VIN as Free user - shows upgrade dialog
  • Decode invalid VIN - shows error message
  • Decode with existing year filled - year unchanged
  • Mobile viewport - button stacks below VIN input
  • Desktop viewport - button inline with VIN input

🤖 Generated with Claude Code

## Summary - Add VIN decode button to Add/Edit Vehicle dialogs that calls NHTSA vPIC API - Pro/Enterprise tier restriction via existing tier gating system - Tiered confidence matching (high/medium/none) for dropdown population - Only populates empty fields (preserves user input) - Responsive layout: stacks on mobile, inline on desktop Fixes #9 ## Changes ### Backend - **NHTSA Client** (`external/nhtsa/`): axios-based client with VIN validation, 5s timeout, caching in `vin_cache` table - **VIN Decode Endpoint** (`POST /api/vehicles/decode-vin`): Tier-gated endpoint with proper error handling (400, 403, 502, 504) - **Dropdown Matching**: Case-insensitive exact matching against existing dropdown options - **Feature Config**: Added `vehicle.vinDecode` feature key with Pro minimum tier ### Frontend - **Decode Button**: Next to VIN input with loading state and error handling - **Tier Check**: Uses `useTierAccess()` hook with `UpgradeRequiredDialog` - **Field Population**: Only populates empty fields based on confidence level ## Test Plan - [ ] Decode valid VIN as Pro user - fields populated - [ ] Decode VIN as Free user - shows upgrade dialog - [ ] Decode invalid VIN - shows error message - [ ] Decode with existing year filled - year unchanged - [ ] Mobile viewport - button stacks below VIN input - [ ] Desktop viewport - button inline with VIN input --- 🤖 Generated with [Claude Code](https://claude.com/claude-code)
egullickson added 2 commits 2026-01-11 19:57:01 +00:00
- Add NHTSA client for VIN decoding with caching and validation
- Add POST /api/vehicles/decode-vin endpoint with tier gating
- Add dropdown matching service with confidence levels
- Add decode button to VehicleForm with tier check
- Responsive layout: stacks on mobile, inline on desktop
- Only populate empty fields (preserve user input)

Backend:
- NHTSAClient with 5s timeout, VIN validation, vin_cache table
- Tier gating with 'vehicle.vinDecode' feature key (Pro+)
- Tiered matching: high (exact), medium (normalized), none

Frontend:
- Decode button with loading state and error handling
- UpgradeRequiredDialog for free tier users
- Mobile-first responsive layout

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
docs: Update vehicles README with VIN decode endpoint (refs #9)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 4m36s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 28s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
9b4f94e1ee
- Add VIN decode endpoint to API section
- Document request/response format with confidence levels
- Add error response examples (400, 403, 502)
- Update architecture diagram with external/ directory

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
egullickson added 1 commit 2026-01-11 21:20:13 +00:00
fix: Prevent cascade clearing of VIN decoded form values (refs #9)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 2m40s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 38s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
19bc10a1f7
VIN decode was setting year/make/model/trim values, but the cascading
dropdown useEffects would immediately clear dependent fields because
they detected a value change. Added isVinDecoding ref flag (mirroring
the existing isInitializing pattern for edit mode) to skip cascade
clearing during VIN decode and properly load dropdown options.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
egullickson added 1 commit 2026-01-11 22:12:17 +00:00
feat: Add fuzzy matching to VIN decode for partial model/trim names (refs #9)
Some checks failed
Deploy to Staging / Build Images (pull_request) Failing after 3m1s
Deploy to Staging / Deploy to Staging (pull_request) Has been skipped
Deploy to Staging / Verify Staging (pull_request) Has been skipped
Deploy to Staging / Notify Staging Ready (pull_request) Has been skipped
Deploy to Staging / Notify Staging Failure (pull_request) Successful in 6s
a6607d5882
Backend: Enhanced matchField function with prefix and contains matching
so NHTSA values like "Sierra" match dropdown options like "Sierra 1500".

Matching hierarchy:
1. Exact match (case-insensitive) -> high confidence
2. Normalized match (remove special chars) -> medium confidence
3. Prefix match (option starts with value) -> medium confidence (NEW)
4. Contains match (option contains value) -> medium confidence (NEW)

Frontend: Fixed VIN decode form population by loading dropdown options
before setting form values, preventing cascade useEffects from clearing
decoded values.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
egullickson added 1 commit 2026-01-11 22:13:29 +00:00
chore: Add hooks directory and update CLAUDE.md navigation
Some checks failed
Deploy to Staging / Build Images (pull_request) Has been cancelled
Deploy to Staging / Deploy to Staging (pull_request) Has been cancelled
Deploy to Staging / Verify Staging (pull_request) Has been cancelled
Deploy to Staging / Notify Staging Ready (pull_request) Has been cancelled
Deploy to Staging / Notify Staging Failure (pull_request) Has been cancelled
1bc0e60235
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
egullickson added 1 commit 2026-01-11 22:17:54 +00:00
fix: Remove unused variables in VIN decode handler (refs #9)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 2m38s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 38s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
f541c58fa7
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
egullickson merged commit dff743ca36 into main 2026-01-11 22:22:36 +00:00
egullickson deleted branch issue-9-vin-decoding 2026-01-11 22:22:36 +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#24