Integrate maintenance receipt OCR into MaintenanceRecordForm with tier gating, auto-populate form fields from accepted OCR results, and display linked receipt on existing maintenance record components.
Scope
Add "Scan Receipt" button to MaintenanceRecordForm (tier-gated)
Tier gating: useTierAccess('maintenance.receiptScan') with lock icon + upgrade dialog for non-Pro
Wire accepted OCR results to form via setValue() (React Hook Form)
Store receipt as document and pass receiptDocumentId when creating maintenance record
Display linked receipt thumbnail + view action on MaintenanceRecordEditDialog
Show receipt indicator icon on MaintenanceRecordsList rows
"Scan Receipt" button appears on maintenance record form (Pro tier only)
Non-Pro users see lock icon + upgrade dialog
Camera capture works on mobile; file upload works on desktop
Accepted OCR results auto-populate form fields
Receipt stored as document and linked via receiptDocumentId
Linked receipt viewable from maintenance record edit dialog
Receipt indicator shown on records list
Mobile and desktop responsive
Relates to #16
## Summary
Integrate maintenance receipt OCR into `MaintenanceRecordForm` with tier gating, auto-populate form fields from accepted OCR results, and display linked receipt on existing maintenance record components.
## Scope
- Add "Scan Receipt" button to `MaintenanceRecordForm` (tier-gated)
- Tier gating: `useTierAccess('maintenance.receiptScan')` with lock icon + upgrade dialog for non-Pro
- Wire accepted OCR results to form via `setValue()` (React Hook Form)
- Store receipt as document and pass `receiptDocumentId` when creating maintenance record
- Display linked receipt thumbnail + view action on `MaintenanceRecordEditDialog`
- Show receipt indicator icon on `MaintenanceRecordsList` rows
## Files
- `frontend/src/features/maintenance/components/MaintenanceRecordForm.tsx` (MODIFY - add scan button, wire OCR)
- `frontend/src/features/maintenance/components/MaintenanceRecordEditDialog.tsx` (MODIFY - show linked receipt thumbnail + view button)
- `frontend/src/features/maintenance/components/MaintenanceRecordsList.tsx` (MODIFY - show receipt indicator on list rows)
- `frontend/src/features/maintenance/api/maintenance.api.ts` (MODIFY - add receiptDocumentId to create payload)
- `frontend/src/core/config/feature-tiers.ts` (MODIFY - add maintenance.receiptScan feature key)
## Technical Notes
- Follow fuel log "Scan Receipt" button pattern (position, styling, tier gate)
- Camera capture on mobile via shared `CameraCapture` component
- File upload fallback for desktop (PDF, PNG, JPG, HEIC)
- Form auto-populate: use `mappedFields` from the hook's `acceptResult()` callback via `setValue()` calls
- Document upload: use existing documents API to store receipt, get back document ID
- Receipt display on `MaintenanceRecordEditDialog`: thumbnail + "View Receipt" button when `receiptDocument` exists
- Mobile (< 768px): 64x64 thumbnail, full-width "View Receipt" button below, stack layout
- Desktop (>= 768px): 80x80 thumbnail, inline "View Receipt" button, row layout
- Receipt indicator on `MaintenanceRecordsList`: small icon on rows with linked receipts
- Mobile-first: responsive layout, scan button prominent on mobile, 44px touch targets
## Acceptance Criteria
- [ ] "Scan Receipt" button appears on maintenance record form (Pro tier only)
- [ ] Non-Pro users see lock icon + upgrade dialog
- [ ] Camera capture works on mobile; file upload works on desktop
- [ ] Accepted OCR results auto-populate form fields
- [ ] Receipt stored as document and linked via receiptDocumentId
- [ ] Linked receipt viewable from maintenance record edit dialog
- [ ] Receipt indicator shown on records list
- [ ] Mobile and desktop responsive
Added receiptDocumentId to MaintenanceRecord and CreateMaintenanceRecordRequest, added ReceiptDocumentMeta interface, added receiptDocument to MaintenanceRecordResponse
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Relates to #16
Summary
Integrate maintenance receipt OCR into
MaintenanceRecordFormwith tier gating, auto-populate form fields from accepted OCR results, and display linked receipt on existing maintenance record components.Scope
MaintenanceRecordForm(tier-gated)useTierAccess('maintenance.receiptScan')with lock icon + upgrade dialog for non-ProsetValue()(React Hook Form)receiptDocumentIdwhen creating maintenance recordMaintenanceRecordEditDialogMaintenanceRecordsListrowsFiles
frontend/src/features/maintenance/components/MaintenanceRecordForm.tsx(MODIFY - add scan button, wire OCR)frontend/src/features/maintenance/components/MaintenanceRecordEditDialog.tsx(MODIFY - show linked receipt thumbnail + view button)frontend/src/features/maintenance/components/MaintenanceRecordsList.tsx(MODIFY - show receipt indicator on list rows)frontend/src/features/maintenance/api/maintenance.api.ts(MODIFY - add receiptDocumentId to create payload)frontend/src/core/config/feature-tiers.ts(MODIFY - add maintenance.receiptScan feature key)Technical Notes
CameraCapturecomponentmappedFieldsfrom the hook'sacceptResult()callback viasetValue()callsMaintenanceRecordEditDialog: thumbnail + "View Receipt" button whenreceiptDocumentexistsMaintenanceRecordsList: small icon on rows with linked receiptsAcceptance Criteria
Milestone: Form Integration, Tier Gating, Receipt Display (#153)
Phase: Execution | Agent: Frontend Agent | Status: PASS
Changes Made
frontend/src/features/maintenance/types/maintenance.types.tsreceiptDocumentIdtoMaintenanceRecordandCreateMaintenanceRecordRequest, addedReceiptDocumentMetainterface, addedreceiptDocumenttoMaintenanceRecordResponsefrontend/src/features/maintenance/components/MaintenanceRecordForm.tsxuseMaintenanceReceiptOcrhook +CameraCapture+MaintenanceReceiptReviewModal, auto-populate viasetValue(), upload receipt as document on submitfrontend/src/features/maintenance/components/MaintenanceRecordEditDialog.tsxfrontend/src/features/maintenance/components/MaintenanceRecordsList.tsxReceipticon on rows with linked receiptsImplementation Notes
useTierAccess('maintenance.receiptScan')withReceiptCameraButtonlocked state +UpgradeRequiredDialog(mirrors fuel log pattern)documentsApi.download(), shows responsive layout with "View Receipt" buttonmaintenance.receiptScanalready present from M2Verification
npx tsc --noEmit)anytype warnings)06ff810on branchissue-16-maintenance-receipt-upload-ocrVerdict: PASS | Next: QR post-implementation review