When a user's subscription is auto-downgraded to free tier (via grace period expiration) and they have more than 2 vehicles, they are now prompted to select which 2 vehicles to keep active on their next login.
## Summary
When a user's subscription is auto-downgraded to free tier (via grace period expiration) and they have more than 2 vehicles, they are now prompted to select which 2 vehicles to keep active on their next login.
Fixes #60
## Changes
### Backend
- Added `GET /api/subscriptions/needs-vehicle-selection` endpoint
- Returns `{ needsSelection, vehicleCount, maxAllowed }` based on:
- User is on free tier
- User has >2 active vehicles
- User has no existing vehicle selections in `tier_vehicle_selections`
### Frontend
- Added `useNeedsVehicleSelection` hook with `staleTime: 0` for fresh checks on login
- Modified `VehicleSelectionDialog` with `blocking` prop:
- Disables backdrop click and escape key
- Hides Cancel button
- Updated messaging for auto-downgrade scenario
- Integrated in `App.tsx` after auth gate ready:
- Checks if vehicle selection is needed
- Shows blocking dialog until user selects vehicles
- Calls existing downgrade API to save selections
## Test Plan
- [ ] Free tier user with 3+ vehicles, no selections: Dialog shown on login
- [ ] Free tier user with 3+ vehicles, has selections: No dialog, app loads
- [ ] Free tier user with 2 vehicles: No dialog, app loads
- [ ] Pro/Enterprise tier user: No dialog, app loads
- [ ] Dialog cannot be dismissed without selection
- [ ] Selected vehicles saved correctly
- [ ] Mobile + desktop responsive validation
## Acceptance Criteria from Issue
- [x] Backend endpoint returns correct `needsSelection` status
- [x] VehicleSelectionDialog shown automatically on login when needed
- [x] Dialog cannot be dismissed without making selection
- [x] Selected vehicles saved correctly
- [ ] Mobile + desktop responsive validation (manual testing needed)
---
🤖 Generated with [Claude Code](https://claude.com/claude-code)
- Add NeedsVehicleSelectionResponse type
- Add needsVehicleSelection API method
- Add useNeedsVehicleSelection hook with staleTime: 0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add blocking prop to prevent dismissal
- Disable backdrop click and escape key when blocking
- Hide Cancel button in blocking mode
- Update messaging for auto-downgrade scenario
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add useNeedsVehicleSelection and useVehicles hooks in App.tsx
- Show blocking VehicleSelectionDialog after auth gate ready
- Call downgrade API on confirm to save vehicle selections
- Invalidate queries after selection to proceed to app
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <[email protected]>
- GET /api/vehicles now uses getUserVehiclesWithTierStatus() and filters
out vehicles with tierStatus='locked' so only selected vehicles appear
in the vehicle list
- GET /api/vehicles/:id now checks tier status and returns 403 TIER_REQUIRED
if user tries to access a locked vehicle directly
This ensures that after a user selects 2 vehicles during downgrade to
free tier, only those 2 vehicles appear in the summary and details screens.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <[email protected]>
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.
Summary
When a user's subscription is auto-downgraded to free tier (via grace period expiration) and they have more than 2 vehicles, they are now prompted to select which 2 vehicles to keep active on their next login.
Fixes #60
Changes
Backend
GET /api/subscriptions/needs-vehicle-selectionendpoint{ needsSelection, vehicleCount, maxAllowed }based on:tier_vehicle_selectionsFrontend
useNeedsVehicleSelectionhook withstaleTime: 0for fresh checks on loginVehicleSelectionDialogwithblockingprop:App.tsxafter auth gate ready:Test Plan
Acceptance Criteria from Issue
needsSelectionstatus🤖 Generated with Claude Code
- Add GET /api/subscriptions/needs-vehicle-selection endpoint - Returns { needsSelection, vehicleCount, maxAllowed } - Checks: free tier, >2 vehicles, no existing selections 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>