feat: Pending vehicle association resolution UI (#149) #160

Closed
opened 2026-02-13 03:52:41 +00:00 by egullickson · 1 comment
Owner

Relates to #149

Scope

Frontend UI for resolving pending vehicle associations when multi-vehicle users submit receipts via email.

API Endpoints (Backend)

  • GET /api/email-ingestion/pending: List pending vehicle associations for authenticated user
  • POST /api/email-ingestion/pending/:id/resolve: Resolve by selecting a vehicle (body: { vehicleId })
  • DELETE /api/email-ingestion/pending/:id: Dismiss/discard a pending association

Frontend Components

  • PendingAssociationBanner: Shown on dashboard when user has pending associations. Shows count + link to resolve.
  • PendingAssociationList: List view of pending items showing extracted receipt data (merchant, date, amount, type)
  • ResolveAssociationDialog: Modal/drawer to select vehicle from dropdown and confirm. On confirm, creates the fuel log or maintenance record with the selected vehicle.

Mobile + Desktop

  • Mobile: Bottom sheet for resolution dialog, full-width cards for list
  • Desktop: Dialog modal for resolution, table/card layout for list

Files

  • backend/src/features/email-ingestion/api/email-ingestion.routes.ts (add user-facing routes)
  • backend/src/features/email-ingestion/api/email-ingestion.controller.ts (add handlers)
  • frontend/src/features/email-ingestion/ (new feature directory)
  • frontend/src/features/email-ingestion/components/PendingAssociationBanner.tsx
  • frontend/src/features/email-ingestion/components/PendingAssociationList.tsx
  • frontend/src/features/email-ingestion/components/ResolveAssociationDialog.tsx
  • frontend/src/features/email-ingestion/hooks/usePendingAssociations.ts

Acceptance Criteria

  • Dashboard shows banner when pending associations exist
  • User can view list of pending items with receipt details
  • User can select vehicle and resolve association (creates record)
  • User can dismiss/discard pending items
  • Mobile and desktop responsive
  • 44px touch targets on mobile
Relates to #149 ## Scope Frontend UI for resolving pending vehicle associations when multi-vehicle users submit receipts via email. ### API Endpoints (Backend) - `GET /api/email-ingestion/pending`: List pending vehicle associations for authenticated user - `POST /api/email-ingestion/pending/:id/resolve`: Resolve by selecting a vehicle (body: { vehicleId }) - `DELETE /api/email-ingestion/pending/:id`: Dismiss/discard a pending association ### Frontend Components - **PendingAssociationBanner**: Shown on dashboard when user has pending associations. Shows count + link to resolve. - **PendingAssociationList**: List view of pending items showing extracted receipt data (merchant, date, amount, type) - **ResolveAssociationDialog**: Modal/drawer to select vehicle from dropdown and confirm. On confirm, creates the fuel log or maintenance record with the selected vehicle. ### Mobile + Desktop - Mobile: Bottom sheet for resolution dialog, full-width cards for list - Desktop: Dialog modal for resolution, table/card layout for list ### Files - `backend/src/features/email-ingestion/api/email-ingestion.routes.ts` (add user-facing routes) - `backend/src/features/email-ingestion/api/email-ingestion.controller.ts` (add handlers) - `frontend/src/features/email-ingestion/` (new feature directory) - `frontend/src/features/email-ingestion/components/PendingAssociationBanner.tsx` - `frontend/src/features/email-ingestion/components/PendingAssociationList.tsx` - `frontend/src/features/email-ingestion/components/ResolveAssociationDialog.tsx` - `frontend/src/features/email-ingestion/hooks/usePendingAssociations.ts` ## Acceptance Criteria - [ ] Dashboard shows banner when pending associations exist - [ ] User can view list of pending items with receipt details - [ ] User can select vehicle and resolve association (creates record) - [ ] User can dismiss/discard pending items - [ ] Mobile and desktop responsive - [ ] 44px touch targets on mobile
egullickson added the
status
backlog
type
feature
labels 2026-02-13 03:52:51 +00:00
egullickson added this to the Sprint 2026-02-02 milestone 2026-02-13 03:53:01 +00:00
egullickson added
status
in-progress
and removed
status
backlog
labels 2026-02-13 15:29:02 +00:00
Author
Owner

Milestone: Implementation Complete

Phase: Execution | Agent: Developer | Status: PASS

Backend Changes

  • Repository: Added getPendingAssociationById() and getPendingAssociationCount() to email-ingestion.repository.ts
  • Service: Added public resolveAssociation() (creates record + marks resolved) and dismissAssociation() methods to email-ingestion.service.ts
  • Controller: Added 4 authenticated endpoint handlers: getPendingAssociations, getPendingAssociationCount, resolveAssociation, dismissAssociation
  • Routes: New emailIngestionRoutes plugin with JWT-authenticated endpoints:
    • GET /api/email-ingestion/pending - List pending associations
    • GET /api/email-ingestion/pending/count - Count for banner
    • POST /api/email-ingestion/pending/:id/resolve - Resolve with vehicle selection
    • DELETE /api/email-ingestion/pending/:id - Dismiss/discard
  • App registration: New routes registered in app.ts

Frontend Changes

  • New feature: frontend/src/features/email-ingestion/ with types, API, hooks, components
  • Types: PendingVehicleAssociation, ExtractedReceiptData, ResolveAssociationResult
  • API client: emailIngestionApi with getPending, getPendingCount, resolve, dismiss
  • Hooks: usePendingAssociationCount (polled), usePendingAssociations, useResolveAssociation, useDismissAssociation
  • PendingAssociationBanner: Shown on dashboard when count > 0, with "Review" button
  • PendingAssociationList: Card list showing merchant, type, date, amount with Assign/Dismiss actions
  • ResolveAssociationDialog: Vehicle selector with receipt summary, full-screen on mobile
  • Dashboard integration: Banner + dialog integrated into DashboardScreen.tsx

Quality Checks

  • TypeScript: Zero errors (backend + frontend)
  • ESLint: Zero errors (pre-existing any warnings only)
  • Mobile: 44px touch targets, full-screen dialogs, responsive flex layout
  • Desktop: Standard dialog modals, card layout

Verdict: PASS | Next: Quality Agent review

## Milestone: Implementation Complete **Phase**: Execution | **Agent**: Developer | **Status**: PASS ### Backend Changes - **Repository**: Added `getPendingAssociationById()` and `getPendingAssociationCount()` to `email-ingestion.repository.ts` - **Service**: Added public `resolveAssociation()` (creates record + marks resolved) and `dismissAssociation()` methods to `email-ingestion.service.ts` - **Controller**: Added 4 authenticated endpoint handlers: `getPendingAssociations`, `getPendingAssociationCount`, `resolveAssociation`, `dismissAssociation` - **Routes**: New `emailIngestionRoutes` plugin with JWT-authenticated endpoints: - `GET /api/email-ingestion/pending` - List pending associations - `GET /api/email-ingestion/pending/count` - Count for banner - `POST /api/email-ingestion/pending/:id/resolve` - Resolve with vehicle selection - `DELETE /api/email-ingestion/pending/:id` - Dismiss/discard - **App registration**: New routes registered in `app.ts` ### Frontend Changes - **New feature**: `frontend/src/features/email-ingestion/` with types, API, hooks, components - **Types**: `PendingVehicleAssociation`, `ExtractedReceiptData`, `ResolveAssociationResult` - **API client**: `emailIngestionApi` with `getPending`, `getPendingCount`, `resolve`, `dismiss` - **Hooks**: `usePendingAssociationCount` (polled), `usePendingAssociations`, `useResolveAssociation`, `useDismissAssociation` - **PendingAssociationBanner**: Shown on dashboard when count > 0, with "Review" button - **PendingAssociationList**: Card list showing merchant, type, date, amount with Assign/Dismiss actions - **ResolveAssociationDialog**: Vehicle selector with receipt summary, full-screen on mobile - **Dashboard integration**: Banner + dialog integrated into `DashboardScreen.tsx` ### Quality Checks - TypeScript: Zero errors (backend + frontend) - ESLint: Zero errors (pre-existing `any` warnings only) - Mobile: 44px touch targets, full-screen dialogs, responsive flex layout - Desktop: Standard dialog modals, card layout *Verdict*: PASS | *Next*: Quality Agent review
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: egullickson/motovaultpro#160