Commit Graph

655 Commits

Author SHA1 Message Date
8d6434f166 Merge pull request 'fix: Mobile login redirects to homepage without showing Auth0 login page (#188)' (#193) from issue-188-fix-mobile-login-redirect into main
All checks were successful
Deploy to Staging / Build Images (push) Successful in 36s
Deploy to Staging / Deploy to Staging (push) Successful in 51s
Deploy to Staging / Verify Staging (push) Successful in 8s
Deploy to Staging / Notify Staging Ready (push) Successful in 7s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
Reviewed-on: #193
2026-02-15 15:36:37 +00:00
Eric Gullickson
850f713310 fix: prevent URL sync effects from stripping Auth0 callback params (refs #188)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 3m21s
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
Root cause: React fires child effects before parent effects. App's URL
sync effect called history.replaceState() on /callback, stripping the
?code= and &state= query params before Auth0Provider's useEffect could
read them via hasAuthParams(). The SDK fell through to checkSession()
instead of handleRedirectCallback(), silently failing with no error.

Guard both URL sync effects to skip on /callback, /signup, /verify-email.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 09:24:56 -06:00
Eric Gullickson
b5b82db532 fix: resolve auth callback failure from IndexedDB cache issues (refs #188)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 3m23s
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 7s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Add allKeys() to IndexedDBStorage to eliminate Auth0 CacheKeyManifest
fallback, revert set()/remove() to non-blocking persist, add auth error
display on callback route, remove leaky force-auth-check interceptor,
and migrate debug console calls to centralized logger.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 09:06:40 -06:00
Eric Gullickson
da59168d7b fix: IndexedDB cache broken on page reload - root cause of mobile login failure (refs #190)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 3m25s
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 7s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
loadCacheFromDB used store.getAll() which returns raw values, not
key-value pairs. The item.key check always failed, so memoryCache
was empty after every page reload. Auth0 SDK state stored before
redirect was lost on mobile Safari (no bfcache).

Also fixed set()/remove() to await IDB persistence so Auth0 state
is fully written before loginWithRedirect() navigates away.

Added 10s timeout on callback loading state as safety net.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 22:20:34 -06:00
Eric Gullickson
38debaad5d fix: skip stale token validation during callback code exchange (refs #190)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 3m28s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 22s
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
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 22:09:09 -06:00
Eric Gullickson
db127eb24c fix: address QR review findings for token validation and clearAll reliability (refs #190)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 3m32s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 22s
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
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 21:59:31 -06:00
Eric Gullickson
15128bfd50 fix: add missing hook dependencies for stale token effect (refs #190)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 21:57:28 -06:00
Eric Gullickson
723e25e1a7 fix: add pre-auth session clear mechanism on HomePage (refs #192)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 21:56:24 -06:00
Eric Gullickson
6e493e9bc7 fix: detect and clear stale IndexedDB auth tokens (refs #190)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 21:55:54 -06:00
Eric Gullickson
a195fa9231 fix: allow callback route to complete Auth0 code exchange (refs #189)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 21:55:24 -06:00
82e8afc215 Merge pull request 'fix: Desktop sidebar clips logo after collapse-mode UX changes (#187)' (#191) from issue-187-fix-sidebar-logo-clipping into main
All checks were successful
Deploy to Staging / Build Images (push) Successful in 34s
Deploy to Staging / Deploy to Staging (push) Successful in 52s
Deploy to Staging / Verify Staging (push) Successful in 9s
Deploy to Staging / Notify Staging Ready (push) Successful in 7s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
Reviewed-on: #191
2026-02-15 03:51:56 +00:00
Eric Gullickson
19cd917c66 fix: resolve sidebar logo clipping with flex-based layout (refs #187)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 4m41s
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 7s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 21:45:03 -06:00
c816dd39ab Merge pull request 'chore: UX design audit cleanup and receipt flow improvements' (#186) from issue-162-ux-design-audit-cleanup into main
All checks were successful
Deploy to Staging / Build Images (push) Successful in 36s
Deploy to Staging / Deploy to Staging (push) Successful in 27s
Deploy to Staging / Verify Staging (push) Successful in 8s
Deploy to Staging / Notify Staging Ready (push) Successful in 8s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
Mirror Base Images / Mirror Base Images (push) Successful in 54s
Reviewed-on: #186
2026-02-14 03:50:21 +00:00
Eric Gullickson
7f6e4e0ec2 fix: skip image preview for PDF receipt uploads (refs #182)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 3m30s
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 7s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
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>
2026-02-13 21:43:47 -06:00
Eric Gullickson
220f8ea3ac fix: increase hybrid engine cloud timeout for WIF token exchange (refs #182)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 37s
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
The 5s cloud timeout was too tight for the initial WIF authentication
which requires 3 HTTP round-trips (STS, IAM credentials, resource
manager). First call took 5.5s and was discarded, falling back to slow
CPU-based PaddleOCR. Increased to 10s to accommodate cold-start auth.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 21:38:05 -06:00
Eric Gullickson
5e4515da7c fix: use PyMuPDF instead of pdf2image for PDF-to-image conversion (refs #182)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 37s
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 7s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
pdf2image requires poppler-utils which is not installed in the OCR
container. PyMuPDF is already in requirements.txt and can render PDF
pages to PNG at 300 DPI natively without extra system dependencies.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 21:34:17 -06:00
Eric Gullickson
5877b531f9 fix: allow PDF uploads in backend OCR controller and service (refs #182)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 3m41s
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 7s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
The backend SUPPORTED_IMAGE_TYPES set excluded application/pdf, returning
415 before the request ever reached the OCR microservice. Added PDF to
the allowed types in both controller and service validation layers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 21:27:40 -06:00
Eric Gullickson
653c535165 chore: add PDF support to receipt OCR pipeline (refs #182)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 38s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 22s
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
The receipt extractor only accepted image MIME types, rejecting PDFs at
the OCR layer. Added application/pdf to supported types and PDF-to-image
conversion (first page at 300 DPI) before OCR preprocessing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 21:22:40 -06:00
Eric Gullickson
83bacf0e2f chore: accept PDF files in receipt upload dialog (refs #182)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 3m39s
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
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 21:14:22 -06:00
Eric Gullickson
812823f2f1 chore: integrate AddReceiptDialog into MaintenanceRecordForm (refs #184)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 3m31s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 22s
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
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>
2026-02-13 20:57:37 -06:00
Eric Gullickson
6751766b0a chore: create AddReceiptDialog component with upload and camera options (refs #183)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 20:55:21 -06:00
Eric Gullickson
bc72f09557 feat: add desktop sidebar collapse to icon-only mode (refs #176)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 20:07:00 -06:00
Eric Gullickson
f987e94fed chore: verify notification bell functionality and improve empty state (refs #180)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 20:02:56 -06:00
Eric Gullickson
da4cd858fa chore: use display name instead of email in header greeting (refs #177)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 20:01:56 -06:00
Eric Gullickson
553877bfc6 chore: add upload date and file type icon to document cards (refs #172)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 20:00:49 -06:00
Eric Gullickson
daa0cd072e chore: remove Insurance default bias from Add Document modal (refs #175)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:56:34 -06:00
Eric Gullickson
afd4583450 chore: show service type in maintenance schedule names for differentiation (refs #174)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:55:25 -06:00
Eric Gullickson
f03cd420ef chore: add Maintenance page title and remove duplicate vehicle dropdown (refs #169)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:53:13 -06:00
Eric Gullickson
e4be744643 chore: restructure Fuel Logs to list-first with add dialog (refs #168)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:49:46 -06:00
Eric Gullickson
f2b20aab1a feat: add recent activity feed to dashboard (refs #166)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:48:06 -06:00
Eric Gullickson
accb0533c6 feat: add call-to-action links in zero-state dashboard stats cards (refs #179)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:45:14 -06:00
Eric Gullickson
0dc273d238 chore: remove dashboard auto-refresh footer text (refs #178)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:43:57 -06:00
Eric Gullickson
56be3ed348 chore: add Year Make Model subtitle to vehicle cards and hide empty VIN (refs #167)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:41:23 -06:00
Eric Gullickson
bc9c386300 chore: differentiate Stations icon from Fuel Logs in bottom nav (refs #181)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:40:09 -06:00
Eric Gullickson
7a74c7f81f chore: remove redundant Stations from mobile More menu (refs #173)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:39:16 -06:00
Eric Gullickson
73976a7356 fix: add Maintenance to mobile More menu (refs #164)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:38:21 -06:00
Eric Gullickson
0e8c6070ef fix: sync mobile routing with browser URL for direct navigation (refs #163)
URL-to-screen sync on mount and screen-to-URL sync via replaceState
enable direct URL navigation, page refresh, and bookmarks on mobile.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:35:53 -06:00
Eric Gullickson
325cf08df0 fix: promote vehicle display utils to core with null safety (refs #165)
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>
2026-02-13 19:32:40 -06:00
Eric Gullickson
75e4660c58 Merge branch 'main' of 172.30.1.72:egullickson/motovaultpro
All checks were successful
Deploy to Staging / Build Images (push) Successful in 3m25s
Deploy to Staging / Deploy to Staging (push) Successful in 51s
Deploy to Staging / Verify Staging (push) Successful in 9s
Deploy to Staging / Notify Staging Ready (push) Successful in 8s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
2026-02-13 16:28:52 -06:00
Eric Gullickson
ff8b04f146 chore: claude updates 2026-02-13 16:28:49 -06:00
f0b1e57089 Merge pull request 'feat: Maintenance Receipt Upload with OCR Auto-populate (#16)' (#161) from issue-16-maintenance-receipt-upload-ocr into main
All checks were successful
Deploy to Staging / Build Images (push) Successful in 36s
Deploy to Staging / Deploy to Staging (push) Successful in 51s
Deploy to Staging / Verify Staging (push) Successful in 8s
Deploy to Staging / Notify Staging Ready (push) Successful in 7s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
Reviewed-on: #161
2026-02-13 22:19:44 +00:00
Eric Gullickson
1bf550ae9b feat: add pending vehicle association resolution UI (refs #160)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 8m40s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 52s
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
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>
2026-02-13 09:39:03 -06:00
Eric Gullickson
8bcac80818 feat: add email ingestion notification handler with logging (refs #159)
- Extract all notification logic from EmailIngestionService into
  dedicated EmailIngestionNotificationHandler class
- Add notification_logs entries for every email sent (success/failure)
- Add in-app user_notifications for all error scenarios (no vehicles,
  no attachments, OCR failure, processing failure)
- Update email templates with enhanced variables: merchantName,
  totalAmount, date, guidance
- Update pending vehicle notification title to 'Vehicle Selection Required'
- Add sample variables for receipt templates in test email flow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 09:27:37 -06:00
Eric Gullickson
fce60759cf feat: add vehicle association and record creation (refs #158)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 08:53:08 -06:00
Eric Gullickson
d9a40f7d37 feat: add receipt classifier and OCR integration (refs #157)
- New ReceiptClassifier module with keyword-based classification for
  fuel vs maintenance receipts from email text and OCR raw text
- Classifier-first pipeline: classify from email subject/body keywords
  before falling back to OCR-based classification
- Fuel keywords: gas, fuel, gallons, octane, pump, diesel, unleaded,
  shell, chevron, exxon, bp
- Maintenance keywords: oil change, brake, alignment, tire, rotation,
  inspection, labor, parts, service, repair, transmission, coolant
- Confident classification (>= 2 keyword matches) routes to specific
  OCR endpoint; unclassified falls back to both endpoints + rawText
  classification + field-count heuristic

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 08:44:03 -06:00
Eric Gullickson
e7f3728771 feat: add email ingestion processing service and repository (refs #156)
- EmailIngestionRepository: queue CRUD (insert, update status, get,
  find by email ID), pending vehicle association management, mapRow
  pattern for snake_case -> camelCase conversion
- EmailIngestionService: full processing pipeline with sender validation,
  attachment filtering (PDF/PNG/JPG/JPEG/HEIC, <10MB), dual OCR
  classification (fuel vs maintenance), vehicle association logic
  (single-vehicle auto-associate, multi-vehicle pending), retry handling
  (max 3 attempts), and templated email replies (confirmation, failure,
  pending vehicle)
- Updated controller to delegate async processing to service
- Added receipt_processed/receipt_failed/receipt_pending_vehicle to
  TemplateKey union type

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 08:32:10 -06:00
Eric Gullickson
2462fff34d feat: add Resend inbound webhook endpoint and client (refs #155)
- ResendInboundClient: webhook signature verification via Svix, email
  fetch/download/parse with mailparser
- POST /api/webhooks/resend/inbound endpoint with rawBody, signature
  verification, idempotency check, queue insertion, async processing
- Config: resend_webhook_secret (optional) in secrets schema
- Route registration in app.ts following Stripe webhook pattern

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 08:22:25 -06:00
Eric Gullickson
877f844be6 feat: add email ingestion database schema and types (refs #154)
- Create email_ingestion_queue table with UNIQUE email_id constraint
- Create pending_vehicle_associations table with documents FK
- Seed 3 email templates: receipt_processed, receipt_failed, receipt_pending_vehicle
- Add TypeScript types for queue records, associations, and Resend webhook payloads
- Register email-ingestion in migration runner order

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 22:01:17 -06:00
Eric Gullickson
06ff8101dc feat: add form integration, tier gating, and receipt display (refs #153)
- 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>
2026-02-12 21:40:27 -06:00
Eric Gullickson
91166b021c feat: add maintenance receipt OCR hook and review modal (refs #152)
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>
2026-02-12 21:31:48 -06:00