Default 10s API client timeout caused frontend "Failed to decode" errors
when Gemini engine cold-starts (34s+ on first call).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
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>
Backend test fixtures:
- Replace auth0|xxx format with UUID in all test userId values
- Update admin tests for new id/userProfileId schema
- Add missing deletionRequestedAt/deletionScheduledFor to auth test mocks
- Fix admin integration test supertest usage (app.server)
Frontend:
- AdminUser type: auth0Sub -> id + userProfileId
- admin.api.ts: all user management methods use userId (UUID) params
- useUsers/useAdmins hooks: auth0Sub -> userId/id in mutations
- AdminUsersPage + AdminUsersMobileScreen: user.auth0Sub -> user.id
- Remove encodeURIComponent (UUIDs don't need encoding)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Make stripe_customer_id NULLABLE via migration, clean up admin_override_*
values to NULL, and update Subscription/SubscriptionResponse/UpdateSubscriptionData
types in both backend and frontend.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rename "Schedule Maintenance" to "Add Maintenance", match contained
button style to "Add Fuel Log", and open inline MaintenanceRecordForm
dialog on click. Applied to both desktop and mobile views.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
URL.createObjectURL on a PDF creates a blob URL that cannot render in
an img tag, showing broken image alt text. Skip preview creation for
PDF files so the review modal displays without a thumbnail.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace ReceiptCameraButton with "Add Receipt" button that opens
AddReceiptDialog. Upload path feeds handleCaptureImage, camera path
calls startCapture. Tier gating preserved.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create shared getVehicleLabel/getVehicleSubtitle in core/utils with
VehicleLike interface. Replace all direct year/make/model concatenation
across 17 consumer files to prevent null values in vehicle names.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backend: Add authenticated endpoints for pending association CRUD
(GET/POST/DELETE /api/email-ingestion/pending). Service methods for
resolving (creates fuel/maintenance record) and dismissing associations.
Frontend: New email-ingestion feature with types, API client, hooks,
PendingAssociationBanner (dashboard), PendingAssociationList, and
ResolveAssociationDialog. Mobile-first responsive with 44px touch
targets and full-screen dialogs on small screens.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add tier-gated "Scan Receipt" button to MaintenanceRecordForm
- Wire useMaintenanceReceiptOcr hook with CameraCapture and ReviewModal
- Auto-populate form fields from accepted OCR results via setValue
- Upload receipt as document and pass receiptDocumentId on record create
- Show receipt thumbnail + "View Receipt" button in edit dialog
- Add receipt indicator chip on records list rows
- Add receiptDocumentId and receiptDocument to frontend types
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add useMaintenanceReceiptOcr hook mirroring fuel receipt OCR pattern,
MaintenanceReceiptReviewModal with confidence indicators and inline editing,
and maintenance-receipt.types.ts for extraction field types. Includes
category/subtype suggestion via keyword matching from service descriptions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
EmailNotificationToggle used a custom button-based toggle that rendered
as a circle. Replaced with MUI Switch component to match the pill-style
toggles used on the SettingsPage throughout the app.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Maintenance page called useMaintenanceRecords() without a vehicleId,
causing the schedules query (enabled: !!vehicleId) to never execute.
Added vehicle selector to both desktop and mobile pages, auto-selects
first vehicle, and passes selectedVehicleId to the hook. Also fixed
stale query invalidation keys in delete handlers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Handle poll errors including 410 Gone in useManualExtraction hook
- Add specific progress stage messages (Preparing/Processing/Mapping/Complete)
- Enforce 44px minimum touch targets on all interactive elements
- Add tests for inline editing, mobile fullscreen, and desktop modal layouts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds minHeight/minWidth: 44 to ReceiptCameraButton, ReceiptOcrReviewModal
action buttons, and UpgradeRequiredDialog buttons and close icon to meet
mobile accessibility requirements.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add/update documentation across backend, Python OCR service, and frontend
for receipt scanning, manual extraction, and Gemini integration. Create
new CLAUDE.md files for engines/, fuel-logs/, documents/, and maintenance/
features.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Google Places Text Search to match receipt merchant names (e.g.
"Shell", "COSTCO #123") to real gas stations. Backend exposes
POST /api/stations/match endpoint. Frontend calls it after OCR
extraction and pre-fills locationData with matched station's placeId,
name, and address. Users can clear the match in the review modal.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Free tier users see locked button with upgrade prompt dialog.
Pro+ users can capture receipts normally. Works on mobile and desktop.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
VIN OCR confidence now reflects recognition accuracy only (not match quality).
Review modal replaces read-only fields with editable cascade dropdowns
pre-populated from NHTSA decode, with NHTSA reference hints for unmatched fields.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add useReceiptOcr hook for OCR extraction orchestration
- Add ReceiptCameraButton component for triggering capture
- Add ReceiptOcrReviewModal for reviewing/editing extracted fields
- Add ReceiptPreview component with zoom capability
- Integrate camera capture, OCR processing, and form population
- Include confidence indicators and low-confidence field highlighting
- Support inline editing of extracted fields before acceptance
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add VinCameraButton component that opens CameraCapture with VIN guidance
- Add VinOcrReviewModal showing extracted VIN and decoded vehicle data
- Confidence indicators (high/medium/low) for each field
- Mobile-responsive bottom sheet on small screens
- Accept, Edit Manually, or Retake Photo options
- Add useVinOcr hook orchestrating OCR extraction and NHTSA decode
- Update VehicleForm with camera button next to VIN input
- Form auto-populates with OCR result and decoded data on accept
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add useNeedsVehicleSelection and useVehicles hooks in App.tsx
- Show blocking VehicleSelectionDialog after auth gate ready
- Call downgrade API on confirm to save vehicle selections
- Invalidate queries after selection to proceed to app
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>