Commit Graph
100 Commits
Author SHA1 Message Date
Eric GullicksonandClaude Opus 4.5 48aea409d8 fix: remove colored hover fills from icon buttons (refs #51)
Deploy to Staging / Build Images (pull_request) Successful in 2m53s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 38s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Changed icon button hover behavior to match VehicleCard pattern:
- Removed background color fills on hover (was primary.main/error.main)
- Icons now use default MUI IconButton gray ripple on hover
- Edit icons use text.secondary color (matches VehicleCard)
- Delete icons use error.main color (matches VehicleCard)

Affected files:
- DocumentsPage.tsx
- FuelLogsList.tsx
- MaintenanceRecordsList.tsx
- MaintenanceSchedulesList.tsx

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-18 12:21:44 -06:00
Eric GullicksonandClaude Opus 4.5 5ad5ea12e6 fix: add Edit (pencil) icon to Documents page (refs #51)
Deploy to Staging / Build Images (pull_request) Successful in 2m50s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 38s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Added missing Edit icon button between Eye and Trash icons.
Clicking Edit opens EditDocumentDialog to modify the document.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-18 12:10:10 -06:00
Eric GullicksonandClaude Opus 4.5 5e045526d6 fix: standardize card/list action buttons and hover states (refs #51)
Deploy to Staging / Build Images (pull_request) Successful in 2m47s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 38s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
- Documents page: Convert from text buttons to icon buttons (Eye for
  View Details, Trash for Delete), add card hover shadow effect,
  convert to MUI components for consistency
- Fuel Logs: Add row hover background effect on list items
- Maintenance Records: Add card hover shadow effect
- Maintenance Schedules: Add card hover shadow effect

All changes follow the VehicleCard pattern with:
- Light gray shadow/elevation on hover with 0.2s transition
- Consistent icon button styling with mobile-responsive touch targets
- Proper MUI component usage throughout

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-18 11:51:29 -06:00
Eric GullicksonandClaude Opus 4.5 5c62b6ac96 fix: convert DECIMAL columns to numbers in fuel logs API (refs #49)
Deploy to Staging / Build Images (pull_request) Successful in 4m50s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 38s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
PostgreSQL DECIMAL columns return as strings from pg driver.
- Add Number() conversion for fuelUnits and costPerUnit in toEnhancedResponse()
- Add query invalidation for 'all' key to fix dynamic updates

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-17 22:37:59 -06:00
Eric Gullickson 444abf2255 chore: updates
Deploy to Staging / Build Images (pull_request) Successful in 3m49s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 29s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
2026-01-17 22:27:17 -06:00
Eric GullicksonandClaude Opus 4.5 574acf3e87 fix: return raw rows from enhanced repository methods (refs #47)
Deploy to Staging / Build Images (pull_request) Successful in 2m28s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 29s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Enhanced repository methods were incorrectly calling mapRow() which
converts snake_case to camelCase, but the service's toEnhancedResponse()
expects raw database rows with snake_case properties. This caused
"Invalid time value" errors when calling new Date(row.created_at).

Fixed methods:
- createEnhanced
- findByVehicleIdEnhanced
- findByUserIdEnhanced
- findByIdEnhanced
- getPreviousLogByOdometer
- getLatestLogForVehicle
- updateEnhanced

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-17 22:08:23 -06:00
Eric GullicksonandClaude Opus 4.5 b6af238f43 perf: fix dashboard load performance with auth gate and API deduplication (refs #45)
Deploy to Staging / Build Images (pull_request) Successful in 2m52s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 38s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
- Replace polling-based auth detection with event-based subscription
- Remove unnecessary 100ms delay on desktop (keep 50ms for mobile)
- Unify dashboard data fetching to prevent duplicate API calls
- Use Promise.all for parallel maintenance schedule fetching

Reduces dashboard load time from ~1.5s to <500ms.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-17 21:26:31 -06:00
Eric GullicksonandClaude Opus 4.5 7c3eaeb5a3 fix: rename Open to View Details and hide empty Details section (refs #43)
Deploy to Staging / Build Images (pull_request) Successful in 2m45s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
- Rename "Open" button to "View Details" on desktop and mobile document lists
- Add hasDisplayableMetadata helper to check if document has metadata to display
- Conditionally render Details section only when metadata exists
- Prevents showing empty "Details" header for documents without metadata

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-17 20:56:57 -06:00
Eric GullicksonandClaude Opus 4.5 b0e392fef1 feat: add type-specific metadata and expiration badges to documents UX (refs #43)
Deploy to Staging / Build Images (pull_request) Successful in 2m46s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
- Create ExpirationBadge component with 30-day warning and expired states
- Create DocumentCardMetadata component for type-specific field display
- Update DocumentsPage to show metadata and expiration badges on cards
- Update DocumentsMobileScreen with metadata and badges (mobile variant)
- Redesign DocumentDetailPage with side-by-side layout (desktop) and
  stacked layout (mobile) showing full metadata panel
- Add 33 unit tests for new components
- Fix jest.config.ts testMatch pattern for test discovery

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-17 20:29:54 -06:00
Eric GullicksonandClaude Opus 4.5 731d67f324 fix: add mobile responsive breakpoint to purchase info grid (refs #41)
Deploy to Staging / Build Images (pull_request) Successful in 2m43s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 29s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-15 20:56:03 -06:00
Eric GullicksonandClaude Opus 4.5 a1d3dd965a fix: display purchase info and fix validation on vehicle detail (refs #41)
Deploy to Staging / Build Images (pull_request) Successful in 2m47s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 38s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
- Add purchase price and purchase date display to vehicle detail page
- Fix form validation to handle NaN from empty number inputs using z.preprocess

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-15 20:53:23 -06:00
Eric GullicksonandClaude Opus 4.5 fbc0186ea6 fix: remove license plate fallback from VIN field (refs #39)
Deploy to Staging / Build Images (pull_request) Successful in 2m46s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 38s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
The VIN Number field incorrectly showed license plate when VIN was empty.
Now displays "Not provided" for missing VIN values, matching mobile behavior.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-15 20:29:40 -06:00
Eric GullicksonandClaude Opus 4.5 96440104c8 fix: remove legacy TCO fields from vehicle forms (refs #37)
Deploy to Staging / Build Images (pull_request) Successful in 2m42s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 29s
Deploy to Staging / Verify Staging (pull_request) Successful in 8s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
- Remove CostInterval type and TCOResponse interface from frontend types
- Remove insurance/registration cost fields from VehicleForm schema and UI
- Keep purchasePrice and purchaseDate fields on vehicle form
- Remove TCODisplay component from VehicleDetailPage
- Delete TCODisplay.tsx component file
- Remove getTCO method from vehicles API client

Legacy TCO fields moved to ownership-costs feature in #29.
Backend endpoint preserved for future reporting feature.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-15 11:03:31 -06:00
Eric Gullickson 60aa0acbe0 chore: remove file
Deploy to Staging / Build Images (push) Successful in 2m23s
Deploy to Staging / Deploy to Staging (push) Successful in 38s
Deploy to Staging / Verify Staging (push) Successful in 7s
Deploy to Staging / Notify Staging Ready (push) Successful in 7s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
2026-01-14 21:28:57 -06:00
Eric Gullickson 4cc3083da4 chore: removed dead file
Deploy to Staging / Build Images (push) Successful in 25s
Deploy to Staging / Deploy to Staging (push) Successful in 28s
Deploy to Staging / Verify Staging (push) Successful in 7s
Deploy to Staging / Notify Staging Ready (push) Successful in 6s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
2026-01-14 21:22:30 -06:00
Eric GullicksonandClaude Opus 4.5 8c570288f9 fix: standardize checkboxes to use MUI Checkbox component (refs #35)
Deploy to Staging / Build Images (pull_request) Successful in 2m41s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 38s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Replace raw HTML checkboxes with MUI Checkbox wrapped in FormControlLabel
for consistent styling and theme integration across:
- DocumentForm.tsx (shared vehicles + scan maintenance checkboxes)
- VehicleForm.tsx (TCO enabled checkbox)
- SignupForm.tsx (terms acceptance checkbox)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-14 21:01:00 -06:00
Eric GullicksonandClaude Opus 4.5 a3b119a953 fix: resolve document upload hang by fixing stream pipeline (refs #33)
Deploy to Staging / Build Images (pull_request) Successful in 2m22s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 29s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
The upload was hanging silently because breaking early from a
`for await` loop on a Node.js stream corrupts the stream's internal
state. The remaining stream could not be used afterward.

Changes:
- Collect ALL chunks from the file stream before processing
- Use subarray() for file type detection header (first 4100 bytes)
- Create single readable stream from complete buffer for storage
- Remove broken headerStream + remainingStream piping logic

This fixes the root cause where uploads would hang after logging
"Document upload requested" without ever completing or erroring.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-14 20:28:19 -06:00
Eric GullicksonandClaude Opus 4.5 1014475c0f fix: add dynamic timeout for document uploads (refs #33)
Deploy to Staging / Build Images (pull_request) Successful in 2m43s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Document uploads were failing with "timeout of 10000ms exceeded" error
because the global axios client timeout (10s) was too short for
medium-sized files (1-5MB).

Added calculateUploadTimeout() function that calculates timeout based on
file size: 30s base + 10s per MB. This allows uploads to complete on
slower connections while still having reasonable timeout limits.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-14 20:16:17 -06:00
Eric GullicksonandClaude Opus 4.5 354ce47fc4 fix: remove debug console.log statements (refs #31)
Deploy to Staging / Build Images (pull_request) Successful in 4m40s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 29s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-14 19:45:51 -06:00
Eric GullicksonandClaude Opus 4.5 bdb329f7c3 feat: add context-aware document delete from vehicle screen (refs #31)
- Created DeleteDocumentConfirmDialog with context-aware messaging:
  - Primary vehicle with no shares: Full delete
  - Shared vehicle: Remove association only
  - Primary vehicle with shares: Full delete (affects all)
- Integrated documents display in VehicleDetailPage records table
- Added delete button per document with 44px touch target
- Document deletion uses appropriate backend calls based on context
- Mobile-friendly dialog with responsive design

Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-14 19:41:52 -06:00
Eric GullicksonandClaude Opus 4.5 b71e2cff3c feat: add document edit functionality with multi-vehicle support (refs #31)
Implemented comprehensive document editing capabilities:

1. Created EditDocumentDialog component:
   - Responsive MUI Dialog with fullScreen on mobile
   - Wraps DocumentForm in edit mode
   - Proper close handlers with refetch

2. Enhanced DocumentForm to support edit mode:
   - Added mode prop ('create' | 'edit')
   - Pre-populate all fields from initialValues
   - Use useUpdateDocument hook when in edit mode
   - Multi-select for shared vehicles (insurance only)
   - Vehicle and document type disabled in edit mode
   - Optional file upload in edit mode
   - Dynamic button text (Create/Save Changes)

3. Updated DocumentDetailPage:
   - Added Edit button with proper touch targets
   - Integrated EditDocumentDialog
   - Refetch document on successful edit

Mobile-first implementation:
- All touch targets >= 44px
- Dialog goes fullScreen on mobile
- Form fields stack on mobile
- Shared vehicle checkboxes have min-h-[44px]
- Buttons use flex-wrap for mobile overflow

Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-14 19:38:20 -06:00
Eric GullicksonandClaude Opus 4.5 8968cad805 feat: display vehicle names instead of UUIDs in document views (refs #31)
- Created shared utility getVehicleLabel() for consistent vehicle display
- Updated DocumentsPage to show vehicle names with clickable links
- Added "Shared with X vehicles" indicator for multi-vehicle docs
- Updated DocumentDetailPage with vehicle name and shared vehicle list
- Updated DocumentsMobileScreen with vehicle names and "Shared" indicator
- All vehicle names link to vehicle detail pages
- Mobile-first with 44px touch targets on all links

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-14 19:34:02 -06:00
Eric GullicksonandClaude Opus 4.5 e558fdf8f9 feat: add frontend document-vehicle API client and hooks (refs #31)
- Update DocumentRecord interface to include sharedVehicleIds array
- Add optional sharedVehicleIds to Create/UpdateDocumentRequest types
- Add documentsApi.listByVehicle() method for fetching by vehicle
- Add documentsApi.addSharedVehicle() for linking vehicles
- Add documentsApi.removeVehicleFromDocument() for unlinking
- Add useDocumentsByVehicle() query hook with vehicle filter
- Add useAddSharedVehicle() mutation with optimistic updates
- Add useRemoveVehicleFromDocument() mutation with optimistic updates
- Ensure query invalidation includes both documents and documents-by-vehicle keys
- Update test mocks to include sharedVehicleIds field
- Fix optimistic update in useCreateDocument to include new fields

Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-14 19:31:03 -06:00
Eric GullicksonandClaude Opus 4.5 5dbc17e28d feat: add document-vehicle API endpoints and context-aware delete (refs #31)
Updates documents backend service and API to support multi-vehicle insurance documents:
- Service: createDocument/updateDocument validate and handle sharedVehicleIds for insurance docs
- Service: addVehicleToDocument validates ownership and adds vehicles to shared array
- Service: removeVehicleFromDocument with context-aware delete logic:
  - Shared vehicle only: remove from array
  - Primary with no shared: soft delete document
  - Primary with shared: promote first shared to primary
- Service: getDocumentsByVehicle returns all docs for a vehicle (primary or shared)
- Controller: Added handlers for listByVehicle, addVehicle, removeVehicle with proper error handling
- Routes: Added POST/DELETE /documents/:id/vehicles/:vehicleId and GET /documents/by-vehicle/:vehicleId
- Validation: Added DocumentVehicleParamsSchema for vehicle management routes

Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-14 19:28:00 -06:00
Eric GullicksonandClaude Opus 4.5 57debe4252 feat: add shared_vehicle_ids schema and repository methods (refs #31)
- Add migration 004_add_shared_vehicle_ids.sql with UUID array column and GIN index
- Update DocumentRecord interface to include sharedVehicleIds field
- Add sharedVehicleIds to CreateDocumentBody and UpdateDocumentBody schemas
- Update repository mapDocumentRecord() to map shared_vehicle_ids from database
- Update insert() and batchInsert() to handle sharedVehicleIds
- Update updateMetadata() to support sharedVehicleIds updates
- Add addSharedVehicle() method using atomic array_append()
- Add removeSharedVehicle() method using atomic array_remove()
- Add listByVehicle() method to query by primary or shared vehicle

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-14 19:24:34 -06:00
Eric GullicksonandClaude Opus 4.5 025ab30726 fix: add schema migration for ownership_costs table (refs #29)
Deploy to Staging / Build Images (pull_request) Successful in 2m21s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 28s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
The ownership_costs table was created with an outdated schema that had
different column names (start_date/end_date vs period_start/period_end)
and was missing the notes column. This migration aligns the database
schema with the current code expectations.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-13 21:51:44 -06:00
Eric GullicksonandClaude Opus 4.5 1d95eba395 fix: resolve lint error in ownership-costs types (refs #29)
Deploy to Staging / Build Images (pull_request) Successful in 4m37s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Milestone 6: Change empty interface to type alias to fix
@typescript-eslint/no-empty-object-type error

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-13 21:37:30 -06:00
Eric GullicksonandClaude Opus 4.5 f0deab8210 feat: add frontend ownership-costs feature (refs #29)
Milestone 4: Complete frontend with:
- Types aligned with backend schema
- API client for CRUD operations
- React Query hooks with optimistic updates
- OwnershipCostForm with all 6 cost types
- OwnershipCostsList with edit/delete actions
- Mobile-friendly (44px touch targets)
- Full dark mode support

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-13 21:35:44 -06:00
Eric GullicksonandClaude Opus 4.5 7928b87ef5 feat: integrate DocumentsService with ownership_costs (refs #29)
Milestone 2: Auto-create ownership_cost when insurance/registration
document is created with cost data (premium or cost field).

- Add OwnershipCostsService integration
- Auto-create cost on document create when amount > 0
- Sync cost changes on document update
- mapDocumentTypeToCostType() validation
- extractCostAmount() for premium/cost field extraction
- CASCADE delete handled by FK constraint

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-13 21:30:02 -06:00
Eric GullicksonandClaude Opus 4.5 81b1c3dd70 feat: create ownership_costs backend feature capsule (refs #29)
Milestone 1: Complete backend feature with:
- Migration with CHECK (amount > 0) constraint
- Repository with mapRow() for snake_case -> camelCase
- Service with CRUD and vehicle authorization
- Controller with HTTP handlers
- Routes registered at /api/ownership-costs
- Validation with Zod schemas
- README with endpoint documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-13 21:28:43 -06:00
Eric Gullickson 395670c3bd fix: add ownership-costs to migration order and improve error handling (refs #15)
Deploy to Staging / Build Images (pull_request) Successful in 4m41s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 38s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
- Add 'features/ownership-costs' to MIGRATION_ORDER in run-all.ts
- Improve OwnershipCostsList error display to not block the page
- Show friendly message when feature needs migration
2026-01-13 08:15:53 -06:00
Eric Gullickson cb93e3ccc5 feat: integrate ownership-costs UI into vehicle detail pages (refs #15)
Deploy to Staging / Build Images (pull_request) Successful in 4m43s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 38s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
- Add OwnershipCostsList to desktop VehicleDetailPage
- Add OwnershipCostsList to mobile VehicleDetailMobile
- Users can now view, add, edit, and delete recurring costs directly
  from the vehicle detail view
2026-01-13 07:57:23 -06:00
Eric GullicksonandClaude Opus 4.5 a8c4eba8d1 feat: add ownership-costs feature capsule (refs #15)
- Create ownership_costs table for recurring vehicle costs
- Add backend feature capsule with types, repository, service, routes
- Update TCO calculation to use ownership_costs (with fallback to legacy vehicle fields)
- Add taxCosts and otherCosts to TCO response
- Create frontend ownership-costs feature with form, list, API, hooks
- Update TCODisplay to show all cost types

This implements a more flexible approach to tracking recurring ownership costs
(insurance, registration, tax, other) with explicit date ranges and optional
document association.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-12 21:28:25 -06:00
Eric GullicksonandClaude Opus 4.5 5c93150a58 fix: add TCO unit tests and fix blocking issues (refs #15)
Deploy to Staging / Build Images (pull_request) Successful in 4m34s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 28s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Quality Review Fixes:
- Add comprehensive unit tests for getTCO() method (12 test cases)
- Add tests for normalizeRecurringCost() via getTCO integration
- Add future date validation guard in calculateMonthsOwned()
- Fix pre-existing unused React import in VehicleLimitDialog.test.tsx
- Fix pre-existing test parameter types in vehicles.service.test.ts

Test Coverage:
- Vehicle not found / unauthorized access
- Missing optional TCO fields handling
- Zero odometer (costPerDistance = 0)
- Monthly/semi-annual/annual cost normalization
- Division by zero guard (new purchase)
- Future purchase date handling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-12 20:32:15 -06:00
Eric GullicksonandClaude Opus 4.5 9e8f9a1932 feat: add TCO display component (refs #15)
Deploy to Staging / Build Images (pull_request) Successful in 5m41s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 29s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
- Create TCODisplay component showing lifetime cost and cost per distance
- Display cost breakdown (purchase, insurance, registration, fuel, maintenance)
- Integrate into VehicleDetailPage right-justified next to vehicle details
- Responsive layout: stacks vertically on mobile, side-by-side on desktop
- Only shows when tcoEnabled is true

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-12 20:05:31 -06:00
Eric GullicksonandClaude Opus 4.5 5e40754c68 feat: add ownership cost fields to vehicle form (refs #15)
- Add CostInterval type and TCOResponse interface
- Add TCO fields to Vehicle, CreateVehicleRequest, UpdateVehicleRequest
- Add "Ownership Costs" section to VehicleForm with:
  - Purchase price and date
  - Insurance cost and interval
  - Registration cost and interval
  - TCO display toggle
- Add getTCO API method
- Mobile-responsive grid layout with 44px touch targets

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-12 20:04:21 -06:00
Eric GullicksonandClaude Opus 4.5 47de6898cd feat: add TCO API endpoint (refs #15)
- Add GET /api/vehicles/:id/tco route
- Add getTCO controller method with error handling
- Returns 200 with TCO data, 404 for not found, 403 for unauthorized

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-12 20:02:15 -06:00
Eric GullicksonandClaude Opus 4.5 381f602e9f feat: add TCO calculation service (refs #15)
- Add TCOResponse interface
- Add getTCO() method aggregating all cost sources
- Add normalizeRecurringCost() with division-by-zero guard
- Integrate FuelLogsService and MaintenanceService for cost data
- Respect user preferences for distance unit and currency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-12 20:01:24 -06:00
Eric GullicksonandClaude Opus 4.5 35fd1782b4 feat: add maintenance cost aggregation for TCO (refs #15)
- Add MaintenanceCostStats interface
- Add getVehicleMaintenanceCosts() method to maintenance service
- Validates numeric cost values and throws on invalid data

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-12 19:59:41 -06:00
Eric GullicksonandClaude Opus 4.5 8517b1ded2 feat: add TCO types and repository updates (refs #15)
- Add CostInterval type and PAYMENTS_PER_YEAR constant
- Add 7 TCO fields to Vehicle, CreateVehicleRequest, UpdateVehicleRequest
- Update VehicleResponse and Body types
- Update mapRow() with snake_case to camelCase mapping
- Update create(), update(), batchInsert() for new fields
- Add Zod validation for TCO fields with interval enum

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-12 19:58:59 -06:00
Eric GullicksonandClaude Opus 4.5 b0d79a26ae feat: add TCO fields migration (refs #15)
Add database columns for Total Cost of Ownership:
- purchase_price, purchase_date
- insurance_cost, insurance_interval
- registration_cost, registration_interval
- tco_enabled toggle

Includes CHECK constraints for interval values and non-negative costs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-12 19:56:30 -06:00
Eric Gullickson 9059c09d2f Merge branch 'main' of 172.30.1.72:egullickson/motovaultpro
Deploy to Staging / Build Images (push) Successful in 26s
Deploy to Staging / Deploy to Staging (push) Successful in 28s
Deploy to Staging / Verify Staging (push) Successful in 7s
Deploy to Staging / Notify Staging Ready (push) Successful in 6s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
2026-01-11 21:52:36 -06:00
Eric Gullickson 34401179bd chore: update script default 2026-01-11 21:52:23 -06:00
Eric GullicksonandClaude Sonnet 4.5 28574b0eb4 fix: preserve vehicle identity by checking ID first in merge mode (refs #26)
Deploy to Staging / Build Images (pull_request) Successful in 2m21s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 28s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Critical fix for merge mode vehicle matching logic.

Problem:
- Vehicles with same license plate but no VIN were matched to the same existing vehicle
- Example: 2 vehicles with license plate "TEST-123" both updated the same vehicle
- Result: "Updated: 2" but only 1 vehicle in database, second vehicle overwrites first

Root Cause:
- Matching order was: VIN → license plate
- Both vehicles had no VIN and same license plate
- Both matched the same existing vehicle by license plate

Solution:
- New matching order: ID → VIN → license plate
- Preserves vehicle identity across export/import cycles
- Vehicles exported with IDs will update the same vehicle on re-import
- New vehicles (no matching ID) will be created as new records
- Security check: Verify ID belongs to same user before matching

Benefits:
- Export-modify-import workflow now works correctly
- Vehicles maintain identity across imports
- Users can safely import data with duplicate license plates
- Prevents unintended overwrites

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
2026-01-11 21:15:30 -06:00
Eric GullicksonandClaude Sonnet 4.5 62b4dc31ab debug: add comprehensive logging to vehicle import merge (refs #26)
Deploy to Staging / Build Images (pull_request) Successful in 2m52s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 28s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Added detailed logging to diagnose import merge issues:

- Log vehicle count at merge start
- Log each vehicle being processed with VIN/make/model/year
- Log when existing vehicles are found (by VIN or license plate)
- Log successful vehicle creation with new vehicle ID
- Log errors with full context (userId, VIN, make, model, error message)
- Log merge completion with summary statistics

This will help diagnose why vehicles show as "successfully imported" but don't appear in the UI.

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
2026-01-11 21:03:20 -06:00
Eric GullicksonandClaude Sonnet 4.5 f48a18287b fix: prevent vehicle duplication and enforce tier limits in merge mode (refs #26)
Deploy to Staging / Build Images (pull_request) Successful in 2m20s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 28s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Critical bug fixes for import merge mode:

1. Vehicle duplication bug (RULE 0 - CRITICAL):
   - Previous: Vehicles without VINs always inserted as new, creating duplicates
   - Fixed: Check by VIN first, then fallback to license plate matching
   - Impact: Prevents duplicate vehicles on repeated imports

2. Vehicle limit bypass (RULE 0 - CRITICAL):
   - Previous: Direct repo.create() bypassed tier-based vehicle limits
   - Fixed: Use VehiclesService.createVehicle() which enforces FOR UPDATE locking and tier checks
   - Impact: Free users properly limited to 1 vehicle, prevents limit violations

Changes:
- Added VehiclesService to import service constructor
- Updated mergeVehicles() to check VIN then license plate for matches
- Replace repo.create() with service.createVehicle() for limit enforcement
- Added VehicleLimitExceededError handling with clear error messages

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
2026-01-11 20:54:38 -06:00
Eric GullicksonandClaude Sonnet 4.5 566deae5af fix: match import button style to export button (refs #26)
Deploy to Staging / Build Images (pull_request) Successful in 2m39s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Desktop changes:
- Replace ImportButton component with MUI Button matching Export style
- Use hidden file input with validation
- Dark red/maroon button with consistent styling

Mobile changes:
- Update both Import and Export buttons to use primary-500 style
- Consistent dark primary button appearance
- Maintains 44px touch target requirement

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
2026-01-11 20:23:56 -06:00
Eric GullicksonandClaude Sonnet 4.5 5648f4c3d0 fix: add import UI to desktop settings page (refs #26)
Deploy to Staging / Build Images (pull_request) Successful in 2m38s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
2026-01-11 20:16:42 -06:00
Eric GullicksonandClaude Sonnet 4.5 197927ef31 test: add integration tests and documentation (refs #26)
Deploy to Staging / Build Images (pull_request) Successful in 4m37s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 29s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
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 Sonnet 4.5 <[email protected]>
2026-01-11 20:05:06 -06:00
Eric GullicksonandClaude Sonnet 4.5 7a5579df7b feat: add frontend import UI (refs #26)
Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
2026-01-11 19:58:17 -06:00
Eric Gullickson 068db991a4 chore: Update footer 2026-01-11 19:51:34 -06:00
Eric GullicksonandClaude Sonnet 4.5 a35d05f08a feat: add import service and API layer (refs #26)
Implements Milestone 3: Backend import service and API with:

Service Layer (user-import.service.ts):
- generatePreview(): extract archive, validate, detect VIN conflicts
- executeMerge(): chunk-based import (100 records/batch), UPDATE existing by VIN, INSERT new via batchInsert
- executeReplace(): transactional DELETE all user data, batchInsert all records
- Conflict detection: VIN duplicates in vehicles
- Error handling: collect errors per record, continue, report in summary
- File handling: copy vehicle images and documents from archive to storage
- Cleanup: delete temp directory in finally block

API Layer:
- POST /api/user/import: multipart upload, mode selection (merge/replace)
- POST /api/user/import/preview: preview without executing import
- Authentication: fastify.authenticate preHandler
- Content-Type validation: application/gzip or application/x-gzip
- Magic byte validation: FileType.fromBuffer verifies tar.gz
- Request validation: Zod schema for mode selection
- Response: ImportResult with success, mode, summary, warnings

Files Created:
- backend/src/features/user-import/domain/user-import.service.ts
- backend/src/features/user-import/api/user-import.controller.ts
- backend/src/features/user-import/api/user-import.routes.ts
- backend/src/features/user-import/api/user-import.validation.ts

Files Updated:
- backend/src/app.ts: register userImportRoutes with /api prefix

Quality:
- Type-check: PASS (0 errors)
- Linting: PASS (0 errors, 470 warnings - all pre-existing)
- Repository pattern: snake_case→camelCase conversion
- User-scoped: all queries filter by user_id
- Transaction boundaries: Replace mode atomic, Merge mode per-batch

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
2026-01-11 19:50:59 -06:00
Eric GullicksonandClaude Sonnet 4.5 ffadc48b4f feat: add archive extraction and validation service (refs #26)
Implement archive service to extract and validate user data import archives. Validates manifest structure, data files, and ensures archive format compatibility with export feature.

- user-import.types.ts: Type definitions for import feature
- user-import-archive.service.ts: Archive extraction and validation
- Validates manifest version (1.0.0) and required fields
- Validates all data files exist and contain valid JSON
- Temp directory pattern mirrors export (/tmp/user-import-work)
- Cleanup method for archive directories

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
2026-01-11 19:30:43 -06:00
Eric GullicksonandClaude Sonnet 4.5 e6af7ed5d5 feat: add batch insert operations to repositories (refs #26)
Add batchInsert methods to vehicles, fuel-logs, maintenance, and documents repositories. Multi-value INSERT syntax provides 10-100x performance improvement over individual operations for bulk data import.

- vehicles.repository: batchInsert for vehicles
- fuel-logs.repository: batchInsert for fuel logs
- maintenance.repository: batchInsertRecords and batchInsertSchedules
- documents.repository: batchInsert for documents
- All methods support empty array (immediate return) and optional transaction client
- Fix lint error: replace require() with ES6 import in test mock

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
2026-01-11 19:28:11 -06:00
Eric Gullickson bb8fdf33cf chore: update docs
Deploy to Staging / Build Images (push) Successful in 22s
Deploy to Staging / Deploy to Staging (push) Successful in 37s
Deploy to Staging / Verify Staging (push) Successful in 6s
Deploy to Staging / Notify Staging Ready (push) Successful in 5s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
2026-01-11 18:13:58 -06:00
Eric GullicksonandClaude Sonnet 4.5 8703e7758a fix: Replace COUNT(*) with SELECT id in FOR UPDATE query (refs #23)
Deploy to Staging / Build Images (pull_request) Successful in 2m18s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 29s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
PostgreSQL error 0A000 (feature_not_supported) occurs when using
FOR UPDATE with aggregate functions like COUNT(*). Row-level locking
requires actual rows to lock.

Changes:
- Select id column instead of COUNT(*) aggregate
- Count rows in application using .length
- Maintains transaction isolation and race condition prevention

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
2026-01-11 18:08:49 -06:00
Eric GullicksonandClaude Sonnet 4.5 20189a1d37 feat: Add tier-based vehicle limit enforcement (refs #23)
Deploy to Staging / Build Images (pull_request) Successful in 4m37s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 38s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Backend:
- Add VEHICLE_LIMITS configuration to feature-tiers.ts
- Add getVehicleLimit, canAddVehicle helper functions
- Implement transaction-based limit check with FOR UPDATE locking
- Add VehicleLimitExceededError and 403 TIER_REQUIRED response
- Add countByUserId to VehiclesRepository
- Add comprehensive tests for all limit logic

Frontend:
- Add getResourceLimit, isAtResourceLimit to useTierAccess hook
- Create VehicleLimitDialog component with mobile/desktop modes
- Add useVehicleLimitCheck shared hook for limit state
- Update VehiclesPage with limit checks and lock icon
- Update VehiclesMobileScreen with limit checks
- Add tests for VehicleLimitDialog

Implements vehicle limits per tier (Free: 2, Pro: 5, Enterprise: unlimited)
with race condition prevention and consistent UX across mobile/desktop.

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
2026-01-11 16:36:53 -06:00
Eric GullicksonandClaude Opus 4.5 f541c58fa7 fix: Remove unused variables in VIN decode handler (refs #9)
Deploy to Staging / Build Images (pull_request) Successful in 2m38s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 38s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-11 16:17:50 -06:00
Eric GullicksonandClaude Opus 4.5 1bc0e60235 chore: Add hooks directory and update CLAUDE.md navigation
Deploy to Staging / Build Images (pull_request) Has been cancelled
Deploy to Staging / Deploy to Staging (pull_request) Has been cancelled
Deploy to Staging / Verify Staging (pull_request) Has been cancelled
Deploy to Staging / Notify Staging Ready (pull_request) Has been cancelled
Deploy to Staging / Notify Staging Failure (pull_request) Has been cancelled
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-11 16:13:21 -06:00
Eric GullicksonandClaude Opus 4.5 a6607d5882 feat: Add fuzzy matching to VIN decode for partial model/trim names (refs #9)
Deploy to Staging / Build Images (pull_request) Failing after 3m1s
Deploy to Staging / Deploy to Staging (pull_request) Has been skipped
Deploy to Staging / Verify Staging (pull_request) Has been skipped
Deploy to Staging / Notify Staging Ready (pull_request) Has been skipped
Deploy to Staging / Notify Staging Failure (pull_request) Successful in 6s
Backend: Enhanced matchField function with prefix and contains matching
so NHTSA values like "Sierra" match dropdown options like "Sierra 1500".

Matching hierarchy:
1. Exact match (case-insensitive) -> high confidence
2. Normalized match (remove special chars) -> medium confidence
3. Prefix match (option starts with value) -> medium confidence (NEW)
4. Contains match (option contains value) -> medium confidence (NEW)

Frontend: Fixed VIN decode form population by loading dropdown options
before setting form values, preventing cascade useEffects from clearing
decoded values.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-11 16:12:09 -06:00
Eric GullicksonandClaude Opus 4.5 19bc10a1f7 fix: Prevent cascade clearing of VIN decoded form values (refs #9)
Deploy to Staging / Build Images (pull_request) Successful in 2m40s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 38s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
VIN decode was setting year/make/model/trim values, but the cascading
dropdown useEffects would immediately clear dependent fields because
they detected a value change. Added isVinDecoding ref flag (mirroring
the existing isInitializing pattern for edit mode) to skip cascade
clearing during VIN decode and properly load dropdown options.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-11 15:20:05 -06:00
Eric GullicksonandClaude Opus 4.5 9b4f94e1ee docs: Update vehicles README with VIN decode endpoint (refs #9)
Deploy to Staging / Build Images (pull_request) Successful in 4m36s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 28s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
- Add VIN decode endpoint to API section
- Document request/response format with confidence levels
- Add error response examples (400, 403, 502)
- Update architecture diagram with external/ directory

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-11 13:56:32 -06:00
Eric GullicksonandClaude Opus 4.5 2aae89acbe feat: Add VIN decoding with NHTSA vPIC API (refs #9)
- Add NHTSA client for VIN decoding with caching and validation
- Add POST /api/vehicles/decode-vin endpoint with tier gating
- Add dropdown matching service with confidence levels
- Add decode button to VehicleForm with tier check
- Responsive layout: stacks on mobile, inline on desktop
- Only populate empty fields (preserve user input)

Backend:
- NHTSAClient with 5s timeout, VIN validation, vin_cache table
- Tier gating with 'vehicle.vinDecode' feature key (Pro+)
- Tiered matching: high (exact), medium (normalized), none

Frontend:
- Decode button with loading state and error handling
- UpgradeRequiredDialog for free tier users
- Mobile-first responsive layout

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-11 13:55:26 -06:00
Eric GullicksonandClaude Opus 4.5 911b7c0e3a fix: Display user email instead of Auth0 UID in audit logs (refs #10)
Deploy to Staging / Build Images (pull_request) Successful in 4m40s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
- Add userEmail field to AuditLogEntry type in backend and frontend
- Update audit-log repository to LEFT JOIN with user_profiles table
- Update AdminLogsPage to show email with fallback to truncated userId
- Update AdminLogsMobileScreen with same display logic

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-11 12:30:57 -06:00
Eric GullicksonandClaude Opus 4.5 fbde51b8fd feat: Add login/logout audit logging (refs #10)
Deploy to Staging / Build Images (pull_request) Successful in 4m42s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 38s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Backend:
- Add login event logging to getUserStatus() controller method
- Create POST /auth/track-logout endpoint for logout tracking

Frontend:
- Create useLogout hook that wraps Auth0 logout with audit tracking
- Update all logout locations to use the new hook (SettingsPage,
  Layout, MobileSettingsScreen, useDeletion)

Login events are logged when the frontend calls /auth/user-status after
Auth0 callback. Logout events are logged via fire-and-forget call to
/auth/track-logout before Auth0 logout.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-11 12:08:41 -06:00
Eric GullicksonandClaude Opus 4.5 cdfba3c1a8 fix: Add audit-log to migration order (refs #10)
Deploy to Staging / Build Images (pull_request) Successful in 2m23s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 28s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
The audit_logs table migration was not being executed because the
audit-log feature was missing from MIGRATION_ORDER in run-all.ts,
causing 500 errors when accessing the audit logs API.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-11 11:42:42 -06:00
Eric GullicksonandClaude Opus 4.5 6f2ac3e22b fix: Add Audit Logs navigation to Admin Console settings (refs #10)
Deploy to Staging / Deploy to Staging (push) Has been cancelled
Deploy to Staging / Verify Staging (push) Has been cancelled
Deploy to Staging / Notify Staging Ready (push) Has been cancelled
Deploy to Staging / Notify Staging Failure (push) Has been cancelled
Deploy to Staging / Build Images (push) Has been cancelled
Deploy to Staging / Build Images (pull_request) Successful in 2m36s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
The routes and screen components for AdminLogsPage were implemented but
the navigation links to access them were missing from both desktop and
mobile Settings pages.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-11 11:32:12 -06:00
Eric GullicksonandClaude Opus 4.5 80275c1670 fix: Remove duplicate audit-logs route from admin routes (refs #10)
Deploy to Staging / Build Images (pull_request) Successful in 2m23s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 28s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
The old /api/admin/audit-logs route in admin.routes.ts conflicted with the
new centralized audit-log feature. Removed the old route since we're now
using the unified audit logging system.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-11 11:18:45 -06:00
Eric GullicksonandClaude Opus 4.5 c98211f4a2 feat: Implement centralized audit logging admin interface (refs #10)
Deploy to Staging / Build Images (pull_request) Successful in 4m42s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Failing after 6s
Deploy to Staging / Notify Staging Ready (pull_request) Has been skipped
Deploy to Staging / Notify Staging Failure (pull_request) Successful in 6s
- Add audit_logs table with categories, severities, and indexes
- Create AuditLogService and AuditLogRepository
- Add REST API endpoints for viewing and exporting logs
- Wire audit logging into auth, vehicles, admin, and backup features
- Add desktop AdminLogsPage with filters and CSV export
- Add mobile AdminLogsMobileScreen with card layout
- Implement 90-day retention cleanup job
- Remove old AuditLogPanel from AdminCatalogPage

Security fixes:
- Escape LIKE special characters to prevent pattern injection
- Limit CSV export to 5000 records to prevent memory exhaustion
- Add truncation warning headers for large exports

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-11 11:09:09 -06:00
Eric GullicksonandClaude Opus 4.5 19ece562ed fix: Implement tiered backup retention classification (refs #6)
Deploy to Staging / Build Images (pull_request) Successful in 6m15s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 28s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Replace per-schedule count-based retention with unified tiered classification.
Backups are now classified by timestamp into categories (hourly/daily/weekly/monthly)
and are only deleted when they exceed ALL applicable category quotas.

Changes:
- Add backup-classification.service.ts for timestamp-based classification
- Rewrite backup-retention.service.ts with tiered logic
- Add categories and expires_at columns to backup_history
- Add Expires column to desktop and mobile backup UI
- Add unit tests for classification logic (22 tests)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-10 21:53:43 -06:00
Eric Gullickson 82a543b250 Merge branch 'main' of 172.30.1.72:egullickson/motovaultpro
Deploy to Staging / Build Images (push) Successful in 24s
Deploy to Staging / Deploy to Staging (push) Successful in 36s
Deploy to Staging / Verify Staging (push) Successful in 6s
Deploy to Staging / Notify Staging Ready (push) Successful in 5s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
Mirror Base Images / Mirror Base Images (push) Successful in 24s
2026-01-04 20:05:22 -06:00
Eric Gullickson 4e43f63f4b feat: purge scripts for CI/CD artifacts 2026-01-04 20:05:17 -06:00
Eric GullicksonandClaude Opus 4.5 0e9d94dafa fix: Wrap file input in flex container for vertical centering (refs #19)
Deploy to Staging / Build Images (pull_request) Successful in 2m42s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 38s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
File inputs are replaced elements that ignore CSS centering properties.
The only reliable solution is to wrap the input in a flex container
with items-center.

Changes:
- Added wrapper div with `flex items-center h-11`
- Moved border/background/focus styles to the wrapper
- Input now uses flex-1 to fill available space
- Used focus-within for focus ring on wrapper

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-04 18:45:25 -06:00
Eric GullicksonandClaude Opus 4.5 75d1a421d4 fix: Use line-height for file input vertical centering (refs #19)
Deploy to Staging / Build Images (pull_request) Successful in 2m41s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Use leading-[44px] to match the h-11 height, which should vertically
center the file input content. Removed padding that was conflicting.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-04 18:36:45 -06:00
Eric GullicksonandClaude Opus 4.5 1534f33232 fix: Vertically center file input content (refs #19)
Deploy to Staging / Build Images (pull_request) Successful in 2m39s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
The "Choose File" button and "No file chosen" text were not vertically
centered within the file input box.

Fixed by:
- Using py-2.5 for input padding (10px top/bottom)
- Adding file:my-auto to center the button vertically
- Adjusting file:py-1.5 for button internal padding

Note: flex/items-center don't work on <input> elements as they are
replaced elements. Using padding and margin-auto instead.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-04 18:28:09 -06:00
Eric GullicksonandClaude Opus 4.5 510420e4fd fix: Vertically center file input content (refs #19)
Deploy to Staging / Build Images (pull_request) Successful in 2m39s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
The "Choose File" button and "No file chosen" text were not vertically
centered within the file input. This was caused by:
1. Browser default `align-items: baseline` for file inputs
2. Conflicting `py-2` padding on the input container

Fixed by:
- Removing `py-2` (conflicting vertical padding)
- Adding `flex items-center` (explicit vertical centering)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-04 18:21:14 -06:00
Eric GullicksonandClaude Opus 4.5 f494f77150 feat: Implement user tier-based feature gating system (refs #8)
Deploy to Staging / Build Images (pull_request) Successful in 4m35s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 27s
Deploy to Staging / Verify Staging (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Add subscription tier system to gate features behind Free/Pro/Enterprise tiers.

Backend:
- Create feature-tiers.ts with FEATURE_TIERS config and utilities
- Add /api/config/feature-tiers endpoint for frontend config fetch
- Create requireTier middleware for route-level tier enforcement
- Add subscriptionTier to request.userContext in auth plugin
- Gate scanForMaintenance in documents controller (Pro+ required)
- Add migration to reset scanForMaintenance for free users

Frontend:
- Create useTierAccess hook for tier checking
- Create UpgradeRequiredDialog component (responsive)
- Gate DocumentForm checkbox with lock icon for free users
- Add SubscriptionTier type to profile.types.ts

Documentation:
- Add TIER-GATING.md with usage guide

Tests: 30 passing (feature-tiers, tier-guard, controller)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-04 14:34:47 -06:00
Eric Gullickson 453083b7db Merge branch 'main' of 172.30.1.72:egullickson/motovaultpro
Deploy to Staging / Build Images (push) Successful in 21s
Deploy to Staging / Deploy to Staging (push) Successful in 25s
Deploy to Staging / Verify Staging (push) Successful in 6s
Deploy to Staging / Notify Staging Ready (push) Successful in 6s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
2026-01-04 13:35:43 -06:00
Eric Gullickson a396fc0f38 feat: OCR Pipeline tech stack file 2026-01-04 13:35:38 -06:00
Eric GullicksonandClaude Opus 4.5 19203aa2b5 fix: My Vehicles manage button navigates to vehicles page (refs #11)
Deploy to Staging / Build Images (pull_request) Successful in 2m39s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 27s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-04 13:28:36 -06:00
Eric GullicksonandClaude Opus 4.5 4fc5b391e1 feat: Add admin vehicle management and profile vehicles display (refs #11)
Deploy to Staging / Build Images (pull_request) Successful in 4m34s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
- Add GET /api/admin/stats endpoint for Total Vehicles widget
- Add GET /api/admin/users/:auth0Sub/vehicles endpoint for user vehicle list
- Update AdminUsersPage with Total Vehicles stat and expandable vehicle rows
- Add My Vehicles section to SettingsPage (desktop) and MobileSettingsScreen
- Update AdminUsersMobileScreen with stats header and vehicle expansion
- Add defense-in-depth admin checks and error handling
- Update admin README documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-04 13:18:38 -06:00
Eric GullicksonandClaude Opus 4.5 17484d7b5f fix: FAB maintenance button navigates to correct screen (refs #13)
Deploy to Staging / Build Images (pull_request) Successful in 5m22s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
The mobile FAB 'Maintenance' option was navigating to the Vehicles screen
instead of the Maintenance screen. Updated handleQuickAction to navigate
to 'Maintenance' which displays MaintenanceMobileScreen.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-03 22:31:07 -06:00
Eric Gullickson 3053b62fa5 chore: Update Documentation
Deploy to Staging / Build Images (push) Successful in 2m19s
Deploy to Staging / Deploy to Staging (push) Successful in 27s
Deploy to Staging / Verify Staging (push) Successful in 5s
Deploy to Staging / Notify Staging Ready (push) Successful in 5s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
Mirror Base Images / Mirror Base Images (push) Successful in 29s
2026-01-03 15:10:19 -06:00
Eric Gullickson 485bfd3dfc fix: Improve .ai/context.json for better effeciency
Deploy to Staging / Build Images (push) Successful in 23s
Deploy to Staging / Deploy to Staging (push) Successful in 37s
Deploy to Staging / Verify Staging (push) Successful in 6s
Deploy to Staging / Notify Staging Ready (push) Successful in 6s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
2026-01-03 14:30:02 -06:00
Eric Gullickson 6e0d7ff5bd fix: change border radius on logo
Deploy to Staging / Build Images (push) Successful in 2m35s
Deploy to Staging / Deploy to Staging (push) Successful in 37s
Deploy to Staging / Verify Staging (push) Successful in 6s
Deploy to Staging / Notify Staging Ready (push) Successful in 5s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
2026-01-03 13:46:02 -06:00
Eric Gullickson d016e69485 chore: update README with development workflow
Deploy to Staging / Build Images (push) Successful in 23s
Deploy to Staging / Deploy to Staging (push) Successful in 37s
Deploy to Staging / Verify Staging (push) Successful in 6s
Deploy to Staging / Notify Staging Ready (push) Successful in 5s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
2026-01-03 13:33:28 -06:00
Eric GullicksonandClaude Opus 4.5 dec91ccfc2 feat: add Terms & Conditions checkbox to signup (refs #4)
Deploy to Staging / Build Images (pull_request) Successful in 4m38s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 28s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
- Add terms_agreements table for legal audit trail
- Create terms-agreement feature capsule with repository
- Modify signup to create terms agreement atomically
- Add checkbox with PDF link to SignupForm
- Capture IP, User-Agent, terms version, content hash
- Update CLAUDE.md documentation index

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-03 12:27:45 -06:00
Eric Gullickson 0391a23bb6 fix: Clean up docs
Deploy to Staging / Build Images (push) Successful in 2m39s
Deploy to Staging / Deploy to Staging (push) Successful in 28s
Deploy to Staging / Verify Staging (push) Successful in 6s
Deploy to Staging / Notify Staging Ready (push) Successful in 5s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
2026-01-03 12:01:53 -06:00
Eric Gullickson b933329539 feat: update docs for token efficient usage
Deploy to Staging / Build Images (push) Has started running
Deploy to Staging / Deploy to Staging (push) Has been cancelled
Deploy to Staging / Verify Staging (push) Has been cancelled
Deploy to Staging / Notify Staging Ready (push) Has been cancelled
Deploy to Staging / Notify Staging Failure (push) Has been cancelled
2026-01-03 11:59:47 -06:00
Eric Gullickson 3dd86c37ff feat: added T&C pdf
Deploy to Staging / Build Images (push) Successful in 2m39s
Deploy to Staging / Deploy to Staging (push) Successful in 37s
Deploy to Staging / Verify Staging (push) Successful in 6s
Deploy to Staging / Notify Staging Ready (push) Successful in 5s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
2026-01-03 11:39:02 -06:00
Eric Gullickson 9f00797925 feat: implement new claude skills and workflow
Deploy to Staging / Build Images (push) Successful in 23s
Deploy to Staging / Deploy to Staging (push) Successful in 36s
Deploy to Staging / Verify Staging (push) Successful in 6s
Deploy to Staging / Notify Staging Ready (push) Successful in 6s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
2026-01-03 11:02:30 -06:00
Eric Gullickson c443305007 Fix .gitea ISSUE_TEMPLATE casing conflict
Deploy to Staging / Build Images (push) Successful in 22s
Deploy to Staging / Deploy to Staging (push) Successful in 36s
Deploy to Staging / Verify Staging (push) Successful in 6s
Deploy to Staging / Notify Staging Ready (push) Successful in 5s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
2026-01-03 10:04:04 -06:00
Eric Gullickson 01297424e1 Merge branch 'main' of 172.30.1.72:egullickson/motovaultpro
Deploy to Staging / Build Images (push) Successful in 23s
Deploy to Staging / Deploy to Staging (push) Successful in 36s
Deploy to Staging / Verify Staging (push) Successful in 6s
Deploy to Staging / Notify Staging Ready (push) Successful in 5s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
2026-01-03 09:54:04 -06:00
Eric GullicksonandClaude Opus 4.5 2059afaaef fix: mobile dashboard navigation for Add Vehicle and Maintenance
Deploy to Staging / Build Images (pull_request) Successful in 2m36s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 36s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
- Add Vehicle now navigates to Vehicles screen and opens add form
- Add Maintenance mobile screen with records/schedules tabs
- Add 'Maintenance' to MobileScreen type
- Wire up onViewMaintenance callback to navigate to Maintenance screen

refs #2

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-02 22:40:42 -06:00
Eric GullicksonandClaude Opus 4.5 98a4a62ea5 fix: add vehicle button opens add vehicle form (refs #2)
Deploy to Staging / Build Images (pull_request) Successful in 2m35s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 36s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
- Add onAddVehicle prop to DashboardScreen
- Mobile: triggers setShowAddVehicle(true) in App.tsx
- Desktop: navigates to /garage/vehicles with showAddForm state
- VehiclesPage auto-opens form when receiving showAddForm state

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-02 22:25:35 -06:00
Eric GullicksonandClaude Opus 4.5 544428fca2 fix: maintenance button navigates to maintenance screen (refs #2)
Deploy to Staging / Build Images (pull_request) Successful in 2m37s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
- Add onViewMaintenance prop to DashboardScreen
- Desktop: navigates to /garage/maintenance
- Mobile: falls back to Vehicles (no dedicated mobile maintenance screen)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-02 22:16:47 -06:00
Eric GullicksonandClaude Opus 4.5 55fb01d5bd fix: reduce border radius on quick action buttons (refs #2)
Deploy to Staging / Build Images (pull_request) Successful in 2m35s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 36s
Deploy to Staging / Verify Staging (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Changed from borderRadius 3 (24px) to 1.5 (12px) for more rectangular look

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-02 22:10:28 -06:00
Eric GullicksonandClaude Opus 4.5 927b1a4128 fix: use primary color for all summary card icons (refs #2)
Deploy to Staging / Build Images (pull_request) Successful in 2m37s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
All summary cards now use primary.main for consistent branding

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-02 22:07:43 -06:00
Eric GullicksonandClaude Opus 4.5 d3c8d377f8 fix: replace emojis with MUI icons and use theme colors in dashboard (refs #2)
Deploy to Staging / Build Images (pull_request) Successful in 2m39s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Visual consistency fixes:
- Replace all emojis with MUI Rounded icons
- Use theme colors (primary.main, warning.main, success.main, error.main)
- Use MUI Box with sx prop for consistent styling
- Use shared Button component instead of custom styled buttons
- Use theme tokens for dark mode (avus, titanio, canna)

Components updated:
- SummaryCards: DirectionsCarRoundedIcon, BuildRoundedIcon, LocalGasStationRoundedIcon
- QuickActions: MUI icons with primary.main color
- VehicleAttention: ErrorRoundedIcon, WarningAmberRoundedIcon, ScheduleRoundedIcon
- DashboardScreen: Proper icons for error/empty states, shared Button component

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-02 21:57:53 -06:00
Eric GullicksonandClaude Opus 4.5 7b00dc7631 chore: add visual integration criteria to feature template (refs #2)
Deploy to Staging / Build Images (pull_request) Successful in 23s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Adds Visual Integration section to prevent design inconsistencies:
- Icons: Must use MUI Rounded icons only, no emoji in UI
- Colors: Theme colors only, no hardcoded hex, dark mode support
- Components: Use existing shared components (GlassCard, Button, etc.)
- Typography & Spacing: MUI variants, consistent spacing multiples

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-02 21:51:18 -06:00