feat: Add VIN decoding button to vehicle dialogs #9
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Add a VIN decoding button to the "Add Vehicle" and "Edit Vehicle" dialogs that uses the NHTSA vPIC API to automatically populate vehicle fields based on the entered VIN.
Feature Details
Tier Restriction
User Interface
Behavior
Fields to Populate
Populate all available fields where data exists in the NHTSA response, including but not limited to:
Technical Implementation
Acceptance Criteria
Priority
Medium
Plan: VIN Decoding Feature
Phase: Planning | Agent: Planner | Status: AWAITING_REVIEW
Executive Summary
Add a VIN decode button to vehicle dialogs that calls NHTSA vPIC API through backend, with tiered auto-fill based on match confidence. Pro/Enterprise tier restriction enforced via existing tier gating system.
Architectural Decision (from Decision Critic)
Verdict: REVISE to Tiered Hybrid Approach
Instead of complex fuzzy matching, implement tiered confidence levels:
This eliminates false positive risk while still providing value from VIN decoding.
Milestone 1: Backend NHTSA Integration
Deliverables:
Create
backend/src/features/vehicles/external/nhtsa/nhtsa.client.tshttps://vpic.nhtsa.dot.gov/api/vehicles/decodevin/{VIN}?format=jsonvin_cachetableCreate
backend/src/features/vehicles/external/nhtsa/nhtsa.types.tsNHTSADecodeResponseinterfaceDecodedVehicleDatainterface with normalized fieldsAdd tier gating in
backend/src/core/config/feature-tiers.ts:Files: 3 new, 1 modified
Milestone 2: VIN Decode Endpoint
Deliverables:
Add route in
backend/src/features/vehicles/api/vehicles.routes.ts:Add controller method in
vehicles.controller.ts:Add service method in
vehicles.service.ts:Create unit tests for NHTSA client and decode logic
Files: 3 modified, 1 test file
Milestone 3: Dropdown Matching Service
Deliverables:
Create
backend/src/features/vehicles/domain/dropdown-matcher.ts:matchMake(nhtsaValue, makes[]): Case-insensitive exact matchmatchModel(nhtsaValue, models[]): Case-insensitive exact matchmatchTrim(nhtsaValue, trims[]): Case-insensitive exact match{ value: string | null, confidence: 'high' | 'medium' | 'none' }Integrate with decode endpoint to:
Unit tests for matching logic
Files: 1 new, 1 modified, 1 test file
Milestone 4: Frontend Decode Button
Deliverables:
Modify
frontend/src/features/vehicles/components/VehicleForm.tsx:useTierAccess()hookUpgradeRequiredDialogfor free tier usersAdd API method in
frontend/src/features/vehicles/api/vehicles.api.ts:Handle decoded data:
Error handling for invalid VINs, API failures
Files: 2 modified
Milestone 5: Mobile + Desktop UI Polish
Deliverables:
Files: 1 modified (VehicleForm.tsx)
Milestone 6: Integration Testing + Documentation
Deliverables:
Files: 1 test file, 1 doc file
Test Plan
File Summary
New Files (5):
backend/src/features/vehicles/external/nhtsa/nhtsa.client.tsbackend/src/features/vehicles/external/nhtsa/nhtsa.types.tsbackend/src/features/vehicles/domain/dropdown-matcher.tsbackend/src/features/vehicles/tests/unit/nhtsa.client.test.tsbackend/src/features/vehicles/tests/integration/vin-decode.integration.test.tsModified Files (5):
backend/src/core/config/feature-tiers.tsbackend/src/features/vehicles/api/vehicles.routes.tsbackend/src/features/vehicles/api/vehicles.controller.tsbackend/src/features/vehicles/domain/vehicles.service.tsfrontend/src/features/vehicles/components/VehicleForm.tsxfrontend/src/features/vehicles/api/vehicles.api.tsVerdict: AWAITING_REVIEW | Next: QR plan-completeness review
QR Review: Plan Completeness
Phase: Plan-Review | Agent: Quality Reviewer | Status: NEEDS_REVISION
Findings
CRITICAL GAP: Acceptance criterion "Only empty fields are populated" not explicitly addressed in plan.
Required Changes
1. Milestone 4 Addition - Preserve Existing Values Logic
Add to Milestone 4 deliverables:
2. Additional Test Cases Required
Minor Recommendations (Non-Blocking)
Verdict: NEEDS_REVISION | Next: Update plan with fixes, re-review
Plan Update: Addressing QR Feedback
Phase: Planning | Agent: Planner | Status: REVISED
Milestone 4 (Revised): Frontend Decode Button
Deliverables:
Modify
frontend/src/features/vehicles/components/VehicleForm.tsx:useTierAccess()hookUpgradeRequiredDialogfor free tier usersAdd API method in
frontend/src/features/vehicles/api/vehicles.api.tsHandle decoded data with field preservation:
Error handling for invalid VINs, API failures
Test Plan (Updated)
Dropdown Option Behavior Clarified
getTierLevel()comparison)Verdict: REVISED | Next: TW plan-scrub review
TW Plan-Scrub Review: VIN Decoding Feature
Phase: Technical Review | Agent: Technical Writer | Status: NEEDS_MINOR_REVISIONS
Executive Summary
The plan is well-structured and implementable, with clear milestones and strong alignment to project patterns. However, 4 minor clarifications are needed for developer implementation:
POST /api/vehicles/decode-vinbut should clarify exact field/body structurevin_cachetable but not confirmed in projectuseTierAccess()hook may not exist yetCLARITY - Excellent
The plan is clear and well-written:
No clarity issues identified.
CONSISTENCY - Minor Issues
1. Endpoint Naming - Request Body Structure
Issue: Plan states:
Clarification Needed: The request body structure should be explicitly documented.
Recommendation:
Rationale: Project pattern shows detailed endpoint documentation (see
/api/vehicles/dropdown/...in routes.ts). Developers will need the exact request/response contracts.2. Cache Table Verification
Issue: Milestone 1 references
vin_cachetable:Clarification Needed: Verify this table exists in schema.
Recommendation:
vin_cachetable (migration pending)"vehicles:${vin}:nhtsaRationale: Current vehicles.service.ts shows Redis cache with key prefixes (e.g.,
vehicles:prefix). Confirm whether DB caching is needed alongside Redis.3. Case Convention - Variable Naming
Issue: Plan uses mixed case in code examples:
decoded.year,decoded.make,decoded.trimLevel(camelCase) ✓Recommendation: Add clarification to Milestone 1:
Rationale: Project naming standard is strict (database snake_case → TypeScript camelCase). Mapping NHTSA response fields to internal types needs explicit documentation.
STRUCTURE - Excellent
Milestone flow is logical:
Dependencies are clear - each milestone builds on previous ones.
TERMINOLOGY - Minor Consistency Issue
Current usage:
Suggestion: The plan uses "VIN decode" inconsistently in some places. Standardize:
Recommendation:
/decode-vin(lowercase with hyphen)decodeVin()(camelCase)Apply consistently throughout. Current draft is close but would benefit from explicit terminology section.
TECHNICAL ACCURACY - Strong
Architecture patterns align with codebase:
No technical issues detected.
MISSING DETAILS (Non-Blocking Recommendations)
1. Error Cases - Expand Test Plan
Current test plan covers happy path and tier restriction. Consider adding:
2. Frontend Error Handling - Toast Configuration
Plan mentions "error toast" but doesn't specify:
toastService.error(message, { duration: 5000 }))Recommend documenting error messages for:
3. Route Registration Order
Plan should note: "Route must be registered before dynamic
:idroutes" (per existing vehicles.routes.ts pattern on line 34).FILE PATH VERIFICATION
All file paths follow project conventions:
backend/src/features/vehicles/external/nhtsa/backend/src/features/vehicles/domain/dropdown-matcher.tsfrontend/src/features/vehicles/components/backend/src/features/vehicles/tests/unit/&/integration/No path issues.
RECOMMENDATIONS SUMMARY
Required Changes (block implementation):
vin_cachetable or Redis? Add migration if DB table.POST /api/vehicles/decode-vinRecommended Changes (improve clarity, non-blocking):
useTierAccess()hook source or create if missingREADY TO IMPLEMENT?
Status: ✅ YES - with clarifications below
The plan is implementation-ready once these three items are addressed:
Estimated implementation time: 8-12 story points across 6 milestones
Verdict: NEEDS_MINOR_REVISIONS | Next: Planner updates clarifications, TW re-reviews
TW Review: Plan Scrub
Phase: Plan-Review | Agent: Technical Writer | Status: PASS with minor notes
Clarity: EXCELLENT
Consistency: MINOR NOTES
Endpoint Contract: Add request/response documentation
Cache Clarification: The
vin_cachetable exists in vehicles migrations (001_create_vehicles_tables.sql). No new migration needed.NHTSA Field Mapping: Document key mappings:
ModelYear→year(number)Make→make(string)Model→model(string)Trim→trimLevel(string)BodyClass→bodyType(string)DriveType→driveType(string)FuelTypePrimary→fuelType(string)Structure: EXCELLENT
decode-vinroute should be registered before:idroutesTerminology: CONSISTENT
/decode-vindecodeVin()Verdict: PASS | Next: QR plan-code review
QR Review: Plan Code Quality
Phase: Plan-Review | Agent: Quality Reviewer | Mode: plan-code | Status: PASS_WITH_CONCERNS
RULE 0 (CRITICAL) - Production Reliability
1. VIN Validation Missing in NHTSA Client
/^[A-HJ-NPR-Z0-9]{17}$/regex check before API call2. No Timeout Configuration
3. NHTSA API Error Handling
RULE 1 (HIGH) - Project Standards
4. Mobile Responsive Specification
flexDirection: { xs: 'column', sm: 'row' }minWidth: { xs: '100%', sm: '120px' }5. NHTSA Field Mapping
RULE 2 (SHOULD_FIX) - Structural Quality
6. Field Preservation Logic
7. Cache TTL Strategy
Code Snippets for Fixes
Verdict: PASS_WITH_CONCERNS (implement fixes during development) | Next: QR plan-docs review
QR Review: Plan Documentation
Phase: Plan-Review | Agent: Quality Reviewer | Mode: plan-docs | Status: NEEDS_REVISION
Critical Gaps
1. Missing CLAUDE.md for New Directory (MANDATORY)
backend/src/features/vehicles/external/nhtsa/backend/src/features/vehicles/external/CLAUDE.mdAdd to Milestone 1:
2. API Endpoint Documentation Incomplete
Required content for
POST /api/vehicles/decode-vin:{ vin: string }DecodedVehicleDatawith confidence levels3. Test Coverage Not Specified
Milestone 6 Revision
Update to specify:
Documentation Checklist
Verdict: NEEDS_REVISION | Next: Planner updates plan with documentation requirements
Plan: Final Revision
Phase: Planning | Agent: Planner | Status: APPROVED
All QR review feedback incorporated. Plan is ready for implementation.
Summary of Revisions
From QR plan-completeness:
From TW plan-scrub:
From QR plan-code:
From QR plan-docs:
Updated Milestone 1
Deliverables:
Create
backend/src/features/vehicles/external/nhtsa/nhtsa.client.ts/^[A-HJ-NPR-Z0-9]{17}$/before API callCreate
backend/src/features/vehicles/external/nhtsa/nhtsa.types.tsCreate
backend/src/features/vehicles/external/CLAUDE.mdAdd tier gating in
backend/src/core/config/feature-tiers.tsUpdated Milestone 5
Mobile Responsive Specification:
Updated Milestone 6
Deliverables:
backend/src/features/vehicles/README.md:{ vin: string }Updated Test Plan (12 cases)
Verdict: APPROVED | Next: Create branch, begin implementation
Milestone Update: Implementation Complete
Phase: Execution | Agent: Developer | Status: COMPLETE
Completed Milestones
Milestone 1: Backend NHTSA Integration - COMPLETE
external/nhtsa/nhtsa.client.tswith VIN validation and cachingexternal/nhtsa/nhtsa.types.tswith TypeScript interfacesexternal/CLAUDE.mddocumenting integration patternvehicle.vinDecodefeature key to tier configMilestone 2: VIN Decode Endpoint - COMPLETE
POST /api/vehicles/decode-vinroute with tier gatingMilestone 3: Dropdown Matching Service - COMPLETE
mapNHTSAResponse()to VehiclesServicematchField()with confidence levels (high/medium/none)Milestone 4: Frontend Decode Button - COMPLETE
useTierAccess()hookUpgradeRequiredDialogfor free tier usersMilestone 5: Mobile + Desktop UI Polish - COMPLETE
flex-col sm:flex-rowMilestone 6: Documentation - COMPLETE
Commits
feat: Add VIN decoding with NHTSA vPIC API (refs #9)- 760 insertionsdocs: Update vehicles README with VIN decode endpoint (refs #9)Files Changed
New (6):
backend/src/features/vehicles/external/CLAUDE.mdbackend/src/features/vehicles/external/nhtsa/index.tsbackend/src/features/vehicles/external/nhtsa/nhtsa.client.tsbackend/src/features/vehicles/external/nhtsa/nhtsa.types.tsModified (8):
backend/src/core/config/feature-tiers.tsbackend/src/features/vehicles/api/vehicles.controller.tsbackend/src/features/vehicles/api/vehicles.routes.tsbackend/src/features/vehicles/domain/vehicles.service.tsbackend/src/features/vehicles/README.mdfrontend/src/features/vehicles/api/vehicles.api.tsfrontend/src/features/vehicles/components/VehicleForm.tsxfrontend/src/features/vehicles/types/vehicles.types.tsVerdict: COMPLETE | Next: Push to remote, create PR
Plan: Add Fuzzy Matching to VIN Decode
Phase: Execution | Agent: Orchestrator | Status: IN_PROGRESS
Problem
The
matchFieldfunction inbackend/src/features/vehicles/domain/vehicles.service.tsonly does exact case-insensitive matching. NHTSA returns partial names (e.g., "Sierra") that don't match dropdown options (e.g., "Sierra 1500", "Sierra 2500HD").Current Response Example
Solution
Add prefix/partial matching to
matchFieldfunction:highconfidencemediumconfidencemediumconfidencemediumconfidencenoneconfidenceDesign Decision
Ambiguity handling: Return first match when multiple options match (user can adjust from dropdown).
Files to Modify
backend/src/features/vehicles/domain/vehicles.service.tsmatchFieldfunction with prefix/contains matchingAcceptance Criteria
Verdict: APPROVED | Next: Delegate to feature-agent for implementation
Milestone: Fuzzy Matching Implementation
Phase: Execution | Agent: feature-agent | Status: PASS
Changes Made
File:
backend/src/features/vehicles/domain/vehicles.service.tsEnhanced
matchFieldfunction with 4-level matching hierarchy:highconfidencemediumconfidencemediumconfidencemediumconfidenceExamples
Validation
QR Review: RULE 0/1/2 Validation
Phase: Review | Agent: quality-agent | Status: PASS
RULE 0 (CRITICAL): Production Reliability
RULE 1 (HIGH): Project Standards
RULE 2 (SHOULD_FIX): Structural Quality
Verdict: PASS | Next: Commit and push changes