MyGarage
Self-hosted vehicle maintenance tracking application
What is MyGarage?
MyGarage is a self-hosted vehicle maintenance tracker. Add your cars, log services, track fuel economy, and get reminders when maintenance is due. It decodes VINs automatically, checks for recalls, and keeps all your receipts and documents in one place.
The app supports multiple users with OIDC/SSO integration (works with Authentik, Keycloak, etc.) so your whole household can manage their vehicles. Garage analytics show spending trends across all vehicles, while individual dashboards break down costs per car.
Everything runs on your own hardwareβno subscriptions, no cloud accounts, your data stays yours. Take a photo of a receipt and OCR extracts the details. Export reports as PDF or CSV when you need them.
Technology Stack
Backend
- β Python 3.14+ with FastAPI 0.121.1 and Granian 2.6.1 ASGI server
- β SQLAlchemy 2.0.44 + SQLite (WAL mode) via aiosqlite 0.21.0
- β Pydantic 2.12.3 for data validation and settings management
- β JWT auth with Argon2id hashing and OIDC/SSO (authlib 1.6.5)
- β NHTSA API for VIN decoding and recall checks (httpx 0.27.2)
- β Tesseract OCR for receipt scanning (PyMuPDF 1.25.0)
- β ReportLab 4.0.0 for PDF generation and analytics export
- β Multi-service notifications via aiosmtplib 3.0+ for email delivery
Frontend
- β React 19.2.3 + TypeScript 5.9.3 with Bun 1.3.6 runtime and Vite 7.3.1 bundler
- β Tailwind CSS 4.1.18 with custom garage theme and light/dark mode
- β React Router 7.12.0 for client-side navigation
- β Recharts 3.6.0 for interactive analytics charts
- β react-big-calendar 1.19.4 for comprehensive calendar UI
- β date-fns 4.1.0 for date manipulation and formatting
- β Zod 4.3.5 + React Hook Form 7.71.1 for form validation
- β Lucide React 0.562.0 iconography and Sonner 2.0.7 for toasts
Project Statistics
Version History
Track the evolution of MyGarage through its version releases. Each release includes new features, improvements, and bug fixes.
v2.20.0 2026-01-19
π Security
- β’ **CodeQL Security Remediation - 173 Issues Fixed** β **Log Injection Prevention (138 fixes)** - CWE-117 β Created `sanitize_for_log()` utility function that escapes control characters (newlines, tabs, ANSI escapes) β Applied to all user-controlled values in logger calls across 44+ files β Prevents log forging and log injection attacks β **Clear-Text Logging of Sensitive Data (10 fixes)** - CWE-532 β Created `mask_coordinates()` function to reduce GPS precision for privacy (~1.1km) β Created `mask_api_key()` function to show only first 4 characters β Applied to shop discovery, POI providers, and integration services β **Unsafe Cyclic Imports (13 fixes)** - Python best practices β Moved runtime imports to `TYPE_CHECKING` blocks in SQLAlchemy models β Fixed `Vehicle` model (16 forward reference imports) β Fixed `MaintenanceTemplate` model (1 forward reference import) β **Partial SSRF Protection (1 fix)** - CWE-918 β Added URL validation in `MaintenanceTemplateService` for GitHub template URLs β Allowlisted hosts: `raw.githubusercontent.com`, `github.com`, `raw.github.com` β Path component sanitization prevents directory traversal β **Stack Trace Exposure (1 fix)** - CWE-209 β Fixed provider test endpoint in settings routes β Exception details now logged server-side only, generic message returned to client β **Code Quality Fixes (5 fixes)** β Fixed empty-except in OSM provider with meaningful error handling β Fixed unused-import in maintenance template validator β Fixed mixed-returns in pytest conftest with proper `NoReturn` typing
β¨ Added
- β’ **Maintenance System Overhaul - Complete Service Tracking Redesign** β **Vendors**: New vendor management system replacing address book for service providers β Dedicated vendor table with type (shop, dealer, self, other) β Vendor history tracking (service count, total spent, last visit) β Search/autocomplete for existing vendors when creating service visits β **Service Visits**: Replaced service records with comprehensive visit tracking β Visit-level data: date, vendor, mileage, notes β Multiple line items per visit (parts, labor, services) β Line items: description, category, service type, cost, notes β Tax & fees tracking: tax amount, shop supplies, misc fees β Subtotal (line items only) and calculated total (including all fees) β Attachment support migrated from old service records β **Maintenance Schedule Items**: New proactive maintenance tracking β Schedule items with due dates (by date or mileage) β Status tracking: upcoming, due soon, overdue, completed β Link service visits to schedule items when completing maintenance β "Log Service" quick action from schedule items β **UI Reorganization** β Removed duplicate reminders from Service tab (now only in Tracking β Reminders) β Moved Maintenance Templates into Maintenance Schedule modal β Collapsible service visit cards with cost breakdown in expanded view β Maintenance Schedule button opens modal with templates and schedule items
- β’ **Tax & Fees on Service Visits** β Three new fields: Tax Amount, Shop Supplies, Misc Fees β Live subtotal/total calculation in form β Cost breakdown display in service visit list (expanded view) β Totals now match real-world invoices with all charges included
- β’ **POI Finder - Interactive Map & Multiple Providers** β Interactive Leaflet map with POI markers and clustering β Map/List view toggle with persistent preference β Click marker to see POI details, click card to highlight on map β **New Providers**: Google Places, Yelp Fusion, Foursquare β Provider priority configuration in Settings β Integrations β Automatic fallback when primary provider fails or hits quota β Rate limiting and caching per provider
- β’ **POI Finder - Multi-Category Points of Interest Discovery** β Renamed "Shop Finder" to "POI Finder" with expanded functionality β Multi-category search: Auto/RV Shops, EV Charging Stations, Fuel Stations β Category toggle switches (red=off, green=on) - multiple categories can be active simultaneously β 2-column grid layout for results (responsive 1-column on mobile) β Icon-only save buttons (check icon when saved, save icon when not saved) β Category badges on POI cards with color coding β EV charging station metadata: connector types, charging speeds, network β Fuel station metadata: prices by grade, fuel types available β Multi-provider architecture with priority-based fallback β Provider management UI in Settings β Integrations β New API endpoints: `/api/poi/*` with backward compatibility for `/api/shop-discovery/*` β Database: Added `poi_category` and `poi_metadata` fields to address_book table β Supported providers: TomTom (priority 1), OpenStreetMap (always available fallback)
π Changed
- β’ **Navigation Updates** β Desktop header: "Find Shops" β "Find POI" β Mobile bottom nav: "Shops" β "POI" β Primary route changed from `/shop-finder` to `/poi-finder` β Old `/shop-finder` route maintained for backward compatibility
- β’ **Service Records β Service Visits Migration** β Old service records automatically migrated to new service visit format β Each old record becomes a visit with a single line item β Attachments migrated to new service visit attachment system β Vendors created from existing address book entries used in service records
π Fixed
- β’ **Service Visit Bugs** β Fixed 500 error on service visits endpoint (missing subtotal in response) β Fixed line items not saving on edit (schema missing line_items field) β Fixed 422 validation error on create (vin incorrectly required in body) β Fixed total mismatch between collapsed and expanded views
π Technical
- β’ **Backend - Maintenance System** β New models: `Vendor`, `ServiceVisit`, `ServiceLineItem`, `MaintenanceScheduleItem` β New schemas with full CRUD support for all new entities β Service layer with business logic for visits, line items, schedule items β Migration 028: Convert reminders to maintenance schedule items β Migration 029: Cleanup migrated reminders β Migration 030: Create vendors, service_visits, service_line_items tables β Migration 031: Add tax/fee columns to service_visits
- β’ **Backend - POI Providers** β Google Places provider with Places API (New) integration β Yelp Fusion provider with business search β Foursquare Places provider with FSQ Places API β Provider health monitoring and automatic failover β Request caching with configurable TTL per provider
- β’ **Frontend - Maintenance System** β New components: `VendorSearch`, `ServiceVisitForm`, `ServiceVisitList`, `ServiceLineItemForm` β `MaintenanceSchedule` component with status indicators β Tab reorganization in vehicle detail view β Form state management for complex nested data (visits with line items)
- β’ **Frontend - POI Map** β Leaflet integration with OpenStreetMap tiles β Custom marker icons per POI category β Marker clustering for dense areas β Synchronized map/list selection state
v2.19.0 2026-01-03
β¨ Added
- β’ **Shop Discovery - Standalone Shop Finder Page** β Moved shop discovery to dedicated `/shop-finder` page (removed from Service Record form) β Navigation links in desktop header and mobile bottom nav β Geolocation-based shop discovery within 5 miles of current location β TomTom Places API primary source (2,500 free requests/day, high-quality commercial data) β OpenStreetMap Overpass fallback (unlimited free, crowd-sourced data) β Automatic fallback to OSM when TomTom unavailable or quota exceeded β Usage-based shop recommendations (previously used shops displayed first) β Save discovered shops directly to address book β TomTom API key configuration in Settings β Integrations (optional) β SSRF protection for TomTom API URLs β Works without configuration using OSM (no API key required) β Distance calculation and sorting (Haversine formula, shows miles from current location) β Shop details: name, address, phone, rating, distance, website links
- β’ **Service Record Categories - Detailing & Upgrades Expansion** β New "Detailing" category with 12 service types: Car Wash, Hand Wash, Wax, Ceramic Coating, Paint Correction, Interior/Exterior Detailing, Full Detailing, Engine Bay Cleaning, Headlight Restoration, Odor Removal, Upholstery Cleaning β Added to "Upgrades" category: Accessory Upgrade (renamed from Interior Upgrade), Window Tinting, Tonneau Cover
ποΈ Removed
- β’ **Technical Service Bulletins (TSB) Feature - Complete Removal** β Removed all TSB functionality from backend and frontend β Backend: Deleted `/api/tsbs` endpoints, TSB model, schemas, and routes β Frontend: Removed TSB tab, TSBList, TSBForm components β Removed TSB relationship from Vehicle model β Database: TSB table remains (data preserved for manual migration if needed) β Safety Recalls tab now shows only Safety Recalls (TSB tab removed) β **Reason:** Non-functional NHTSA TSB API, feature provided no value
π Changed
- β’ **Service Record Form - Simplified Vendor Entry** β Removed "Find Nearby Shop" button from Service Record form β Users now use standalone Shop Finder page to discover and save shops β Address Book autocomplete remains for selecting saved vendors
π Fixed
- β’ **NHTSA Recall Integration** β Fixed incorrect API endpoint causing recall checks to fail β Changed from `https://vpic.nhtsa.dot.gov/api/recallsByVehicle` to `https://api.nhtsa.gov/recalls/recallsByVehicle` β Updated default `nhtsa_recalls_api_url` setting to use correct base URL β Recall checks now successfully retrieve active recalls from NHTSA database
v2.18.1 2026-01-01
π Fixed
- β’ **Analytics Data Quality & Calculation Accuracy** β Invalid MPG filtering: Filter out 0/negative miles driven and unrealistic MPG values (<5 or >100) β Prevents worst MPG showing 0.0 due to data entry errors or odometer corrections β Two-stage filtering: before calculation (invalid trips) and after (unrealistic MPG) β Handles edge cases: zero miles between fill-ups, negative mileage, extreme outliers β Weighted average MPG calculation: Changed from simple mean to total_miles/total_gallons β More accurate representation of overall fuel efficiency β Accounts for varying trip lengths (long highway vs short city trips) β Example: 450mi/15gal + 50mi/10gal = 20 MPG weighted vs 17.5 MPG simple mean β Recent MPG label clarity: Changed from 5-record rolling average to single most recent fill-up β Backend: `df["mpg"].iloc[-1]` instead of `df["mpg"].tail(5).mean()` β Frontend: Label updated from "Recent" to "Latest Fill-Up" for clarity
- β’ **Analytics UI/UX Improvements** β Card spacing consistency: Standardized Summary Stats grid spacing from `gap-4` to `gap-6` β Matches spacing standard across all analytics sections β Spacing hierarchy: major sections (`gap-8`), card grids (`gap-6`), compact rows (`gap-4`) β Spot rental filtering: Only display for RV-type vehicles (FifthWheel, RV, TravelTrailer) β Backend: Check vehicle_type before querying spot rental data β Frontend: Conditionally render bar chart based on `hasPropane` flag β Removes empty spot rental bars from car/truck analytics
- β’ **Maintenance Prediction Clarity** β Enhanced prediction display to show both AI predictions AND manual reminders β Schema additions: `has_manual_reminder`, `manual_reminder_date`, `manual_reminder_mileage` fields β Backend integration: Query active reminders and fuzzy-match to service types β Frontend enhancements: β Service type displayed in larger, prominent font β "REMINDER SET" purple badge when manual reminder exists β "AI predicts:" label in blue for AI-generated predictions from service history β "You set:" label in purple for manual user reminders β Both systems displayed simultaneously with distinct styling β Helps users understand difference between automated predictions and their own reminders β All changes backward compatible (optional fields with defaults)
π Changed
- β’ **BREAKING: Service Records Schema Redesign** β Separated service category from specific service type for better analytics and predictions β **Database Changes:** β `service_type` field renamed to `service_category` (Maintenance, Inspection, Collision, Upgrades) β `description` field renamed to `service_type` with 50+ predefined options (Oil Change, Tire Rotation, etc.) β All existing records migrated with `service_type = 'General Service'` (users update manually) β Backup table created: `service_records_backup_20251229` β **Analytics Impact:** β Predictions now group by specific service type instead of generic category β Example: "Next Oil Change due in 90 days" vs "Next Maintenance due in 45 days" β Higher confidence scores due to consistent service-specific intervals β **UI Changes:** β Service Record Form: Added cascading dropdowns (Category filters Service Type options) β Service Record List: Column headers updated (Category | Service Type | Mileage | Cost) β Search filters now search both category and service type fields β **Migration:** Database migration 022 runs automatically on backend startup β **User Action Required:** Update existing service records via UI to change 'General Service' to specific types β **Files Updated:** 17 total (10 backend, 4 frontend, 3 tests including exports, reports, calendar integration) β **Tests Updated:** pytest fixtures and payloads updated to match new schema (vin/mileage/service_type fields)
π Technical Details
- β’ Files modified: 5 (3 backend, 2 frontend)
- β’ Lines changed: 103 insertions(+), 23 deletions(-)
- β’ Quality checks: β Ruff, β ESLint, β TypeScript type check
- β’ Commit: `05c1488` - "fix: resolve 6 analytics bugs - MPG calculations, UI spacing, predictions"
v2.18.0 2025-12-27
π Security
- β’ **CodeQL Security Improvements** β Fixed 15 stack trace exposure vulnerabilities (94% reduction) β 7 notification test endpoints (ntfy, Gotify, Pushover, Slack, Discord, Telegram, Email) β 7 CSV import endpoints (service, fuel, odometer, reminder, note, warranty, tax) β 1 insurance document parsing endpoint β Replaced `str(e)` with generic error messages to prevent leaking implementation details β Stack traces now only logged server-side, not exposed to API consumers β Added VIN validation before using in file paths (prevents directory traversal) β Validates VIN format (17 alphanumeric characters) before creating directories β Protects window sticker uploads and photo storage endpoints (4 locations) β Mitigates path injection attacks like `../../etc` β Fixed 7 clear-text logging of sensitive data warnings in OIDC service (88% reduction) β Removed full URL logging (URLs may contain secrets/tokens in query params) β Removed authorization code and redirect URI from error logs β Added suppression comment for properly masked client_secret β **Overall improvement:** 454 warnings fixed (74% reduction from 610 to 156 warnings)
β¨ Added
- β’ **Propane Tank Size Tracking** β New tank size selection dropdown (20lb, 33lb, 100lb, 420lb) in propane entry form β Number of tanks input field β Auto-calculation of propane gallons based on tank size Γ quantity β Conversion formula: gallons = (pounds Γ· 4.24) Γ quantity β Manual override always available for precise measurements β Tank fields optional (backwards compatible with existing records) β Can edit existing records to add tank data β Database migration 021: Added `tank_size_lb` and `tank_quantity` columns to fuel_records β Backend auto-calculation in create/update endpoints β Analytics service extended with tank breakdown, timeline, and refill frequency data β Support for both imperial and metric unit systems
- β’ **Travel Trailer Vehicle Type** β New vehicle type: `TravelTrailer` for bumper-pull recreational trailers β Distinct from `FifthWheel` (gooseneck) and `Trailer` (utility/cargo) β Includes propane tracking for appliances (fridge, stove, furnace, water heater) β Includes spot rental tracking for RV parks β No fuel/odometer tracking (non-motorized) β Matches NHTSA vPIC "Travel Trailer" body class classification β Database migration 020: Added `TravelTrailer` to vehicle_type check constraint
π Fixed
- β’ **Fuel History UI - Propane Column Visibility** β Hide propane column in fuel history table for non-propane vehicles β Propane column now only displays when vehicle fuel_type includes "propane" β Matches existing fuel entry form behavior (form already hid propane field for non-propane vehicles) β Cleaner UI for gasoline/diesel/electric vehicles β Dynamic colSpan adjustment (9 or 10 columns) for proper table layout β Ready for RV propane tracking with BTU calculations
- β’ **Analytics - Spot Rental Inclusion** β Fixed analytics calculations to include spot rental billing costs β Spot rental costs now appear in Cost Trends with Rolling Averages β Spot rental costs now appear in Monthly Cost Trend charts (bar chart and list view) β Spot rental costs now appear in Seasonal Spending Patterns β Spot rental costs now appear in Period Comparison analysis β Updated `records_to_dataframe()` to accept SpotRentalBilling records β Updated `calculate_monthly_aggregation()` to track spot_rental_cost and spot_rental_count β All analytics endpoints now query and include spot rental billing data β Added `total_spot_rental_cost` and `spot_rental_count` fields to MonthlyCostSummary schema β Monthly Cost Trend chart now displays spot rental as orange stacked bar β Spot rental only appears in list view when amount > 0
v2.17.4 2025-12-15
π Fixed
- β’ **Number Input Bug Across All Forms** β Fixed critical bug where numeric inputs were incorrectly formatting values (e.g., 500 β 500000, 192.68 β mangled output) β Fixed issue where deleting all input left "0100" instead of clearing properly β Updated all 13 forms to use `valueAsNumber: true` with React Hook Form for proper number handling β Removed `z.coerce` from all Zod schemas and replaced with NaN transformation for optional fields β Affected forms: BillingEntry, Fuel, Service, Insurance, Propane, SpotRental, Odometer, Tax, TollTransaction, Reminder, Warranty, VehicleEdit, VehicleWizard β Fixed 40+ numeric input fields across the application
v2.17.3 2025-12-14
π Fixed
- β’ **Fifth Wheel Analytics & Reports** β Excluded fuel efficiency metrics from fifth wheel analytics (previously showing incorrectly) β Fixed cost summary PDF reports to exclude fuel data for fifth wheels β Hidden fuel efficiency alerts card for non-motorized vehicles (fifth wheels and trailers)
- β’ **Analytics UI Improvements** β Fixed propane analysis bar chart tooltip background (now displays dark theme properly) β Fixed spot rental analysis bar chart tooltip background (now displays dark theme properly) β Improved tooltip consistency across all analytics charts
- β’ **Type Safety** β Fixed TypeScript type errors in FuelRecordForm component for Decimal field handling β Fixed PropaneRecordList filter to properly handle string/number type conversions β Added proper type conversion helpers for API Decimal values returned as strings
v2.17.2 2025-12-14
π Fixed
- β’ **Spot Rental Form Improvements** β Fixed total cost auto-calculation with proper type conversion (resolved `toFixed()` errors) β Simplified rate input to single field based on selected rate type (nightly/weekly/monthly) β Auto-creates first billing entry when spot rental is created with monthly rate β Billing entries now restricted to monthly rate rentals only
- β’ **Propane Tank Management** β Fixed decimal validation to accept values like "30.5" in propane gallons field β Improved form validation for propane capacity inputs
- β’ **Address Book Enhancements** β Fixed address book edit functionality - now properly loads existing address data β Corrected form field binding for editing addresses
- β’ **PWA & Service Worker** β Fixed service worker MIME type (now served as `application/javascript`) β Fixed manifest.json MIME type (now served as `application/json`) β Fixed icon files to be served with correct `image/png` MIME type β Added explicit root route handler to serve index.html β Improved static file serving for PWA functionality
π Changed
- β’ **Billing Entry UI** β Updated styling to match dark theme consistently across billing forms β Improved visual presentation of billing entry components
v2.17.1 2025-12-14
π Security
- β’ **[HIGH] Fixed Log Injection vulnerabilities in vehicle routes** β Prevented potential log injection attacks in vehicle route endpoints β Converted f-string logging to parameterized format to prevent log forgery
π Documentation
- β’ **Streamlined README** - Reduced from 455 to 143 lines (68% reduction) β Removed verbose configuration examples and troubleshooting details β Organized wiki links into clear sections (Getting Started, Features, Configuration, Help) β Centered badges and screenshot for improved visual presentation β All detailed information now accessible through comprehensive wiki documentation
π Fixed
- β’ **Code Quality** - Fixed ESLint and TypeScript errors in fifth wheel components β Resolved type errors in PropaneTab, BillingEntryForm, and related components β Removed unused imports and variables β Updated bun lockfile to fix CI build issues
v2.17.0 2025-12-13
β¨ Added
- β’ **Electric Vehicle Support** β New vehicle types: `Electric` and `Hybrid` β kWh tracking for electric vehicle charging records β Smart fuel form adapts fields based on vehicle fuel type β Electric vehicles show Energy (kWh) field instead of Volume (gallons) β Hybrid vehicles show both gallons and kWh fields β Dynamic labels: "Price per kWh" for electric, "Charging Station" references β Conditional checkboxes: Full Tank and Hauling hidden for electric vehicles β Electric-specific tip: "Efficiency metrics (kWh/100mi) are calculated from charging records"
π Changed
- β’ **Smart Fuel Form** β Form now conditionally shows/hides fields based on vehicle fuel_type β Field visibility logic: β Electric: Shows kWh, hides gallons/propane/is_full_tank/is_hauling β Hybrid: Shows both gallons and kWh β Gas/Diesel: Shows gallons (existing behavior) β Propane: Shows propane_gallons β Auto-calculation updated to handle both gallons and kWh β Missed Fill-up label changes to "Missed Charging Session" for electric vehicles
π Fixed
- β’ **RV Propane Access Bug** β RV vehicles now have access to propane tab (previously only Fifth Wheels) β Updated `VehicleDetail.tsx` to check for both RV and FifthWheel β Updated `Analytics.tsx` propane and spot rental sections for RVs β Documentation now correctly reflects RV capabilities
π Technical
- β’ **Database Changes** β Migration 019: Added `kwh NUMERIC(8, 3)` column to `fuel_records` table β Updated vehicle_type constraint to include 'Electric' and 'Hybrid'
- β’ **Backend Changes** β `backend/app/models/fuel.py`: Added kwh field mapping β `backend/app/models/vehicle.py`: Updated CheckConstraint for new vehicle types β `backend/app/schemas/vehicle.py`: Added Electric/Hybrid to valid_types β `backend/app/schemas/fuel.py`: Added kwh validation (0-99999.999, 3 decimal places)
- β’ **Frontend Changes** β `frontend/src/types/vehicle.ts`: Added Electric and Hybrid to VehicleType β `frontend/src/schemas/vehicle.ts`: Added RV (was missing), Electric, and Hybrid to VEHICLE_TYPES β `frontend/src/types/fuel.ts`: Added kwh field to all interfaces β `frontend/src/schemas/fuel.ts`: Added optionalKwhSchema validation β `frontend/src/schemas/shared.ts`: Created optionalKwhSchema validator β `frontend/src/components/FuelRecordForm.tsx`: Major smart form refactor with conditional rendering β `frontend/src/pages/VehicleDetail.tsx`: Fixed propane tab visibility for RVs β `frontend/src/pages/Analytics.tsx`: Fixed propane/spot rental sections for RVs
v2.16.0 2025-01-28
β¨ Added
- β’ **Fifth Wheel & Trailer Enhancement System** β Propane-only tracking for fifth wheels using existing `fuel_records` table β Propane tab visible only for fifth wheel vehicles (no fuel/odometer tabs) β Spot rental billing entries system for ongoing rental cost tracking β Multiple billing entries per rental with billing date, monthly rate, utilities (electric, water, waste) β Address book integration with RV Park category filter and autocomplete β Auto-fill address when selecting from address book β "Save to Address Book?" prompt after creating new spot rentals β Fifth wheel analytics showing propane spending trends and spot rental costs β Analytics exclude MPG/fuel economy metrics for fifth wheels and trailers β Propane analysis section with monthly cost trends and cost per gallon β Spot rental analysis section with cumulative costs and monthly averages β Billing summary cards showing total billed, billing periods, and monthly average β Expandable billing history with "View All Billings" button β Auto-calculated billing totals (monthly rate + electric + water + waste)
π Changed
- β’ **Vehicle Type Tab Visibility** β Motorized vehicles (Car, Truck, SUV, Motorcycle, RV): Fuel + Odometer tabs β Fifth Wheel: Propane tab ONLY (no fuel, no odometer) β Trailer: No fuel, no odometer, no propane tabs β RVs remain motorized and keep fuel/odometer tabs
- β’ **Spot Rental UI Redesign** β Billing summary card displays by default with last billing entry β Full billing history expandable via "View All Billings" button β Edit/delete buttons for individual billing entries β Cumulative totals and monthly averages calculated automatically
π Fixed
- β’ Fifth wheel vehicle type logic - correctly excludes both 'Trailer' and 'FifthWheel' from motorized vehicles
- β’ Propane records filtered client-side: `propane_gallons > 0 && !gallons`
- β’ Billing dates validated within rental check-in/check-out period
π Technical
- β’ **Database Changes** β Migration 018: Added `spot_rental_billings` table with FK to `spot_rentals` β CASCADE delete ensures billing entries removed when parent rental deleted β Existing `fuel_records.propane_gallons` column reused (no schema changes)
- β’ **Backend Changes** β New model: `SpotRentalBilling` with relationship to `SpotRental` β New endpoints: `/vehicles/{vin}/spot-rentals/{rental_id}/billings` (CRUD) β Analytics service: `calculate_propane_costs()` and `calculate_spot_rental_costs()` β Fifth wheel detection in analytics route skips fuel economy calculations β Eager loading with `selectinload(SpotRental.billings)` prevents N+1 queries
- β’ **Frontend Changes** β New components: `PropaneRecordForm`, `PropaneRecordList`, `PropaneTab`, `BillingEntryForm` β Updated types: `SpotRentalBilling` interfaces and validation schemas β Helper functions: `getBillingTotal()`, `getMonthlyAverage()`, `getLastBilling()` β Address book autocomplete integration in `SpotRentalForm` β Analytics conditional sections based on vehicle type
π Documentation
- β’ Added comprehensive implementation summary at `/srv/raid0/docker/documents/history/mygarage/2025-01-28-fifth-wheel-enhancements.md`
- β’ Total: 5 backend files created, 8 backend files modified, 7 frontend files created, 6 frontend files modified
v2.15.1 2025-12-11
π Security
- β’ **CRITICAL: Updated React to 19.2.3** - Patches CVE-2025-55182 (CVSS 10.0), a remote code execution vulnerability actively exploited in the wild β Updated `react` from 19.2.0 to 19.2.3 β Updated `react-dom` from 19.2.0 to 19.2.3 β Updated `react-is` from 19.2.0 to 19.2.3 β Includes enhanced loop protection for React Server Functions
π Changed
- β’ **Frontend Dependencies** - Updated all low-risk dependencies for improved performance and security β Updated `vite` from 7.2.4 to 7.2.7 (security fix for request-target validation) β Updated `@testing-library/jest-dom` from 6.6.3 to 6.9.1 (new accessibility matchers) β Updated `@testing-library/react` from 16.1.0 to 16.3.0 β Updated `@testing-library/user-event` from 14.5.2 to 14.6.1 β Updated `@typescript-eslint/eslint-plugin` from 8.48.1 to 8.49.0 β Updated `@typescript-eslint/parser` from 8.48.1 to 8.49.0 β Updated `typescript-eslint` from 8.48.1 to 8.49.0 β Updated `jsdom` from 27.2.0 to 27.3.0 β Updated `react-hook-form` from 7.67.0 to 7.68.0 (new FormStateSubscribe component) β Updated `react-router-dom` from 7.9.6 to 7.10.1 (React Router v7 stabilization fixes)
- β’ **Backend Dependencies** - Updated ruff linter with new features and improved performance β Updated `ruff` from 0.7.0 to 0.14.9 β New RUF100 rule for detecting unused suppressions (preview mode) β Improved performance with faster line index computation β Better rule accuracy (S506, B008, D417 improvements)
π Fixed
- β’ **Code Quality** - Fixed 26 linting violations identified by ruff 0.14.9 β Fixed 17 E712 violations: Changed SQLAlchemy boolean comparisons from `== True/False` to `.is_(True/False)` β Fixed 5 F841 violations: Marked intentionally unused ownership validation variables with `_` β Fixed 4 F401 violations: Added `# noqa: F401` to imports used for availability checking
- β’ **Configuration** - Updated ruff configuration to fix deprecation warning β Moved `per-file-ignores` from top-level to `[tool.ruff.lint]` section in pyproject.toml
v2.15.0 2025-12-11
β¨ Added
- β’ **Unit Conversion System** - Per-user Imperial/Metric unit preferences β Full support for distance (mi/km), volume (gal/L), fuel economy (MPG/L/100km) β Per-user preferences stored in user settings β Optional "Show Both Units" mode displays both systems simultaneously (e.g., "25 MPG (9.4 L/100km)") β Applied across all forms: Fuel, Odometer, Service records β Applied across all displays: Dashboard, Analytics, Record lists β Dynamic chart labels and tooltips adapt to user preference β Canonical storage pattern: all data stored in Imperial, converted at display time β Comprehensive conversion utilities: `UnitConverter` and `UnitFormatter` classes β See [docs/UNIT_CONVERSION.md](docs/UNIT_CONVERSION.md) for technical details
- β’ **Vehicle Archive System** - Safe vehicle archiving with complete data preservation β Replace dangerous "Delete" with "Archive" workflow β Archive metadata: reason, sale price, sale date, notes β Dashboard visibility toggle for archived vehicles β Visual watermark on dashboard cards for archived vehicles (diagonal red "ARCHIVED" banner) β Un-archive capability to restore vehicles to active status β Permanent delete only available after archiving β Preserves all records: service, fuel, odometer, documents, photos, notes β Archived vehicles list in Settings with management actions β Archive reasons: Sold, Traded, Totaled, Donated, End of Lease, Other β See [docs/ARCHIVE_SYSTEM.md](docs/ARCHIVE_SYSTEM.md) for complete guide
π Changed
- β’ **Dashboard Filtering** - Now shows active vehicles + archived vehicles with visibility enabled
- β’ **Vehicle Detail Page** - "Delete" button replaced with "Remove Vehicle" (archive workflow)
- β’ **VehicleStatisticsCard** - Added unit conversion for odometer and fuel economy displays
- β’ **Analytics Page** - All charts and tables now respect unit preferences β Fuel Economy chart Y-axis shows "MPG" or "L/100km" based on preference β All statistics, tables, and tooltips display in user's preferred units
π Fixed
- β’ **Archive System - Authentication Mode Compatibility** β Archive endpoints now work correctly in `auth_mode='none'` without requiring login β CSRF middleware now skips validation when `auth_mode='none'` β Archived vehicles with NULL `user_id` now visible to all users in authenticated modes β Dashboard properly refreshes after archiving a vehicle β Archive watermark positioning corrected (no longer cut off at top edge)
- β’ **Unit Preferences - Non-Authenticated Support** β Unit preferences now work in `auth_mode='none'` using localStorage β Settings page shows Unit System and Archived Vehicles sections regardless of auth mode β Unit preferences persist across authentication mode changes
π Technical
- β’ Added database columns: `archived_at`, `archive_reason`, `archive_sale_price`, `archive_sale_date`, `archive_notes`, `archived_visible`
- β’ New backend endpoints: `/api/vehicles/{vin}/archive`, `/api/vehicles/{vin}/unarchive`, `/api/vehicles/archived/list`
- β’ Archive endpoints use `optional_auth` for compatibility with all authentication modes
- β’ CSRF middleware checks `auth_mode` setting before enforcing token validation
- β’ New frontend components: `VehicleRemoveModal`, `ArchivedVehiclesList`
- β’ New React hooks: `useUnitPreference` for accessing unit preferences (with localStorage fallback)
- β’ New utility classes: `UnitConverter` (conversion methods), `UnitFormatter` (display formatting)
- β’ Dashboard endpoint filtering: `WHERE archived_at IS NULL OR (archived_at IS NOT NULL AND archived_visible = TRUE)`
- β’ Dashboard uses `useLocation` hook to trigger reload on navigation
- β’ Archived vehicles query includes NULL `user_id` vehicles for authenticated users
π Documentation
- β’ Added [docs/UNIT_CONVERSION.md](docs/UNIT_CONVERSION.md) - Complete unit conversion system guide
- β’ Added [docs/ARCHIVE_SYSTEM.md](docs/ARCHIVE_SYSTEM.md) - Complete vehicle archive system guide
- β’ Updated [README.md](README.md) - Added new features to key features list and quick links
v2.14.4 2025-12-10
π Fixed
- β’ **CI/CD Failures** - Fixed GitHub Actions workflow failures in frontend and Docker build jobs β Fixed bun.lock dependency mismatch causing `bun install --frozen-lockfile` to fail β Updated bun.lock to match lucide-react 0.556.0 from package.json β Resolved "Process completed with exit code 1" errors in CI dependency installation β Fixed Docker multi-stage build failures during frontend dependency installation
- β’ **Vitest Integration** - Fixed test runner compatibility issues with Bun 1.3.4 in CI environment β Changed test command from `bun test --run` to `bun run test:run` to use Vitest instead of Bun's native test runner β Fixed 'document is not defined' errors caused by Bun's test runner not setting up jsdom environment β Added explicit vitest.config.ts as temporary workaround for Bun 1.3.4 CI compatibility β Bun 1.3.4 doesn't load test config from vite.config.ts in GitHub Actions environment
π Technical Notes
- β’ CI now passes all three jobs: Frontend Tests, Backend Tests, Docker Build Test
- β’ Lock file sync required after manual package.json version changes
- β’ Vitest configuration duplication (vite.config.ts + vitest.config.ts) is temporary until Bun 1.4+ improves integration
v2.14.3 2025-12-09
π Changed
- β’ **[BREAKING] Migrated frontend from Node.js 25 to Bun 1.3.4 runtime** β Package manager: npm β bun β Lockfile: package-lock.json β bun.lock β Docker base image: node:25-alpine β oven/bun:1.3.4-alpine β ~10-25x faster dependency installation (2-5s vs 30-60s) β ~40-60% smaller Docker images β All development commands now use `bun` instead of `npm`
π Developer Impact
- β’ **Install Bun 1.3.4+ for local development**: https://bun.sh/docs/installation
- β’ Run `bun install` instead of `npm ci`
- β’ Run `bun dev` instead of `npm run dev`
- β’ Run `bun test` instead of `npm test`
- β’ See [DEVELOPMENT.md](DEVELOPMENT.md) for full guide
π Infrastructure
- β’ Vite 7.2.4 bundler retained (no changes to build output)
- β’ Vitest test runner retained (all tests unchanged)
- β’ Backend unchanged (Python 3.14 + FastAPI + Granian)
- β’ Zero application code changes
- β’ Production deployment compatible (same Docker interface)
- β’ CodeQL security scanning compatible
π Performance Improvements
- β’ Package install: ~10-25x faster (19s vs 30-60s)
- β’ Build time: ~1.5-2x faster (3s vs 4-5s)
- β’ Docker image: ~40-60% smaller
- β’ CI/CD runtime: ~2x faster
β¨ Added
- β’ Added [compose.dev.yaml](compose.dev.yaml) for hot reload development with Bun + Vite HMR
π Documentation
- β’ Added comprehensive [DEVELOPMENT.md](DEVELOPMENT.md) guide
- β’ Updated [README.md](README.md) with Bun installation and usage
- β’ Updated wiki: Installation, Home, Troubleshooting guides
- β’ Updated SOPs: dev-sop.md, git-sop.md
π Migration Notes
- β’ **Phase 1 complete**: Runtime swap to Bun while keeping Vite bundler
- β’ **Phase 2 evaluation**: Consider Bun.build() in 6-12 months when manual chunk splitting is supported
- β’ Rollback instructions included in Dockerfile comments
v2.14.2 2025-12-04
π Security
- β’ **[CRITICAL] Fixed Server-Side Request Forgery (SSRF) vulnerabilities (CWE-918)** β Created comprehensive URL validation utility (`backend/app/utils/url_validation.py`) β Fixed SSRF in OIDC service (`backend/app/services/oidc.py:100`) - prevents access to internal services β Fixed SSRF in NHTSA service (`backend/app/services/nhtsa.py:48`) - validates API URLs β Protection includes: blocks private IPs (RFC 1918, RFC 4193), loopback, link-local, AWS metadata endpoint β DNS rebinding protection and domain allowlisting support β All HTTP requests to external services now validated
- β’ **[HIGH] Fixed Log Injection vulnerabilities (CWE-117) - 200+ instances across 44 files** β Converted all f-string logging to parameterized logging format β Prevents log forgery attacks via newline injection β Created automated remediation tool (`fix_log_injection.py`) β Affected files: all routes/, services/, utils/, migrations/, and core modules
- β’ **[HIGH] Fixed Secret Exposure in Logs** β Created `mask_secret()` function to safely log sensitive values β Fixed 4 instances of OIDC client secret exposure in logs β Secrets now show only first/last 4 chars (e.g., `oidc_****...****_abcd`)
- β’ **[HIGH] Fixed Path Injection vulnerabilities (CWE-22)** β Added defense-in-depth path validation in photo deletion (`backend/app/routes/photos.py:250,259`) β Validates resolved paths are within PHOTO_DIR to prevent traversal attacks β Enhanced with `validate_path_within_base()` security checks
- β’ **[MEDIUM] Fixed postMessage Origin Validation (CWE-20291)** β Added strict same-origin validation in service worker (`frontend/public/sw.js:147`) β Prevents XSS and message spoofing from unauthorized origins β Rejects messages with console warning for security monitoring
π Changed
- β’ **Exception Handling** - Verified stack trace exposure properly handled β Production mode (default): Generic error messages only, no internal details β Debug mode: Detailed traces for development only β Error handlers in `backend/app/utils/error_handlers.py` provide secure responses
β¨ Added
- β’ **New Security Utilities** β `backend/app/utils/url_validation.py` - Comprehensive SSRF protection (447 lines) β `backend/app/exceptions.py` - Added `SSRFProtectionError` exception class β `fix_log_injection.py` - Automated log injection remediation script
π Fixed
- β’ **Code Quality Improvements** - Resolved 101 CodeQL NOTE-level alerts β Removed 59 unused imports from 39 Python files (automated) β Added explanatory comments to 8 empty except blocks (optional dependency checks) β Renamed 9 unused local variables to `_` for intentionally unused values β Fixed useless comparison in frontend user count display β Documented 3 Pydantic validator false positives (require `cls` parameter) β Documented 3 pytest.skip false positives (raises exception, never returns None)
π Documentation
- β’ **SECURITY.md** - Added comprehensive CodeQL Security Analysis section β Documented all 140 fixed vulnerabilities (2 CRITICAL, 119 HIGH, 1 MEDIUM) β Documented 17 false positives with justification β Listed 136 deferred code quality items (NOTE level) β Updated security changelog for v2.14.2
- β’ **Cyclic Imports** - Documented 47 cyclic import alerts for future architectural refactoring β Saved to `/srv/raid0/docker/documents/history/mygarage/2025-12-04-cyclic-imports-deferred.txt` β Includes recommended fixes (TYPE_CHECKING, dependency injection, lazy imports)
π Technical Notes
- β’ All security and code quality fixes are backward compatible
- β’ No API changes or breaking changes
- β’ Total files modified: 86 (47 security + 39 code quality)
- β’ CodeQL analysis: 241/272 alerts resolved (140 security + 101 code quality)
- β’ Remaining 47 alerts are cyclic imports (architectural issue, deferred to refactoring sprint)
v2.14.1 2025-12-03
β¨ Added
- β’ **Single-Source-of-Truth Version Management** β Backend now reads version from `pyproject.toml` automatically at runtime β Added `get_version()` function using Python's built-in `tomllib` parser β Version bumps now only require updating 2 files instead of 3 β Eliminates version drift between config.py and pyproject.toml β Updated Dockerfile to copy `pyproject.toml` into production image
π Changed
- β’ **Zod v4 API Migration** - Updated all validation schemas to use Zod v4 API patterns β Removed deprecated `required_error` and `invalid_type_error` parameters from schemas β Simplified error messages using single `message` parameter β Updated z.enum `errorMap` syntax to new `message` format β Removed unnecessary `z.preprocess()` wrappers that were causing type inference issues β React Hook Form's zodResolver automatically handles empty string β undefined conversion
- β’ **Form Type Safety Improvements** β Fixed defaultValues type mismatches across 15+ form components β Changed numeric field defaults from `.toString() || ''` to `?? undefined` pattern β Fixed boolean field defaults using `??` instead of `||` to preserve explicit false values β Improved type inference for all form schemas (now return proper types instead of `unknown`)
- β’ **Test Infrastructure Updates** β Changed `global` to `globalThis` for Node.js/browser compatibility in test setup β Removed unused imports and variables across test files
π Fixed
- β’ **TypeScript Compilation Errors** - Resolved 100+ TypeScript errors caused by Zod v4 API changes β Fixed all schema validation patterns to match Zod v4 requirements β Fixed form component type mismatches for numeric and boolean fields β Fixed null safety issues in title length checks and property access β Removed unused imports and watch variables flagged by TypeScript strict mode
π Dependencies
- β’ **Frontend**: Updated jsdom from 25.0.1 to 27.2.0 (Dependabot security update)
π Technical Notes
- β’ All changes are backward compatible - no validation rules or API contracts changed
- β’ Build passes successfully with Vite
- β’ All 28 unit tests passing
- β’ 49 non-blocking TypeScript warnings remain (type inference cascades from resolver types)
v2.14.0 2025-12-01
β¨ Added
- β’ **Multi-User Management System** β Database setting `multi_user_enabled` to control user creation (default: false) β Backend enforcement: blocks user creation when multi-user mode is disabled β Admin password reset endpoint (`PUT /auth/users/{id}/password`) for local auth users only β Multi-User Management card in Settings > System (admin-only, local auth only) β Toggle switch to enable/disable multi-user mode β User preview showing first 3 users with avatars β "Add User" button to create new accounts β "Manage All Users" button to access full user management interface β User Management modal with: β Searchable user table (by username, email, or full name) β Role badges (Admin/User) β Status badges (Active/Inactive) β Auth method badges (OIDC/Local) β Edit user details β Reset password (local users only) β Enable/disable user accounts β Delete users (cannot delete yourself) β Add/Edit User modal with: β Username field (disabled in edit mode) β Email field (required) β Full name field (optional) β Password fields with strength indicator β Password visibility toggles β Role selector (Admin/User) β Active status checkbox β OIDC user badge (when applicable) β Delete User modal with: β User information display β Data impact warnings (vehicles, service records, fuel records) β Type "DELETE" confirmation requirement β Admin badge warning for admin users β Security safeguards: β Last admin protection: cannot disable the only active admin β Last admin protection: cannot change role of the only active admin β Self-deletion prevention: users cannot delete their own account β Warning tooltips for disabled actions β Confirmation dialogs for destructive operations
π Changed
- β’ Settings > System page now uses two-column CSS Grid layout: β Left column: System Configuration + Multi-User Management β Right column: Authentication Mode + Change Password
π Fixed
- β’ Button styling consistency across multi-user management components: β Change Password button now uses correct theme (`bg-gray-700 border border-gray-600`) β Create/Update button in Add/Edit User modal now uses correct theme β All buttons now match the application's standard gray button style
v2.13.0 2025-12-01
β¨ Added
- β’ **OIDC Username-Based Account Linking with Password Verification** β Prevents duplicate account creation (username1, username2, etc.) during OIDC login β When username matches but email differs, users are prompted to verify their password β New database table `oidc_pending_links` for temporary link tokens (migration 015) β New frontend page `/auth/link-account` for password verification β Security features: β Token expiration: 5 minutes (configurable via `oidc_link_token_expire_minutes`) β Max password attempts: 3 (configurable via `oidc_link_max_password_attempts`) β Rate limiting: 5 requests/minute on link endpoint β One-time use tokens (deleted after successful link) β Comprehensive audit logging (success and failure) β Edge case handling: β Token expiration with user-friendly error messages β Maximum attempt lockout β OIDC-only user detection (no password) β Conflict prevention (already linked to different provider) β Inactive user checks β Backward compatible with existing OIDC flows (email-based linking still works) β Files added: β `backend/app/exceptions.py` - PendingLinkRequiredException β `backend/app/models/oidc_pending_link.py` - Pending link model β `backend/app/migrations/015_add_oidc_pending_links.py` - Database migration β `frontend/src/pages/LinkAccount.tsx` - Password verification UI β Files modified: β `backend/app/services/settings_init.py` - Added 2 new settings β `backend/app/services/oidc.py` - Added 3 helper functions, modified user creation logic β `backend/app/routes/oidc.py` - Modified callback handler, added `/link-account` endpoint β `frontend/src/App.tsx` - Added route for link account page
v2.13.0 2025-11-30
β¨ Added
- β’ **Code Quality Refactoring (Phase 2)** β Complete service layer architecture for business logic separation β `VehicleService` (226 lines) - Vehicle CRUD operations with integrated authorization β `ServiceRecordService` (366 lines) - Service record management with N+1 query optimization β `FuelRecordService` (486 lines) - Fuel tracking with MPG calculations and caching β `PhotoService` (179 lines) - Photo management and thumbnail generation β Photo management extracted to dedicated router (`/app/routes/photos.py`, 448 lines, 7 endpoints) β Average MPG calculation now cached (5-minute TTL) for performance β Legacy photo hydration moved to one-time migration script (removed from request hot path) β Database migration 014: `014_hydrate_legacy_photos.py` for one-time photo metadata population
- β’ **Authentication Mode 'None' Implementation** β Support for running application without authentication in development environments β Frontend centralized auth_mode state in AuthContext (single API call to `/settings/public`) β Smart authentication dependencies check `auth_mode` setting before enforcing β `auth_mode='none'` allows guest access (user = None) with full permissions β Settings UI allows changing Authentication Mode to "None" with security warnings β Frontend ProtectedRoute respects `auth_mode` from context (no duplicate API calls)
π Changed
- β’ **Massive Code Reduction and Organization (Phase 2)** β `vehicles.py`: 1,002 β 316 lines (69% reduction) β `service.py`: 404 β 185 lines (54% reduction) β `fuel.py`: 487 β 165 lines (66% reduction) β Total: 1,227 lines removed from route files (average 63% reduction) β Route handlers now focused purely on HTTP concerns, business logic in service layer β Removed redundant `_sanitize_filename` function (using centralized utils version with better validation) β Consolidated duplicate VIN decode endpoints with shared `_decode_vin_helper()` function β All photo endpoints maintain backward compatibility with authorization checks in place
- β’ **Authentication Architecture Updates** β `require_auth()` now checks `auth_mode` setting: returns None when disabled, enforces when enabled β `get_current_admin_user()` checks `auth_mode` first: returns None when disabled (allows all access) β All helper functions accept `Optional[User]` for type safety with null checks β `get_vehicle_or_403()` and `check_vehicle_ownership()` handle None users (grant full access) β Vehicle/Service/Fuel service layers accept `Optional[User]`, show all data when user is None β Settings endpoints split: `/api/settings/public` (no auth) vs `/api/settings` (admin only) β All 100+ endpoints now work seamlessly with `auth_mode='none'`
π Fixed
- β’ **Code Quality Improvements (Phase 3 - 71% reduction in linting issues)** β Fixed F821 (undefined name): Added missing `Document` import in [vehicle.py:187](backend/app/models/vehicle.py#L187) β Fixed E722 (bare except): Replaced with specific `ValueError` in [insurance.py:129](backend/app/services/document_parsers/insurance.py#L129) β Auto-fixed 128 actionable issues via ruff (unused imports, empty f-strings, boolean comparisons, unused variables) β Reduced total ruff issues from 181 β 53 (71% reduction) β Remaining 53 issues are intentional design patterns (documented in `pyproject.toml`) β E402 (46 issues): Imports after code for FastAPI initialization order and circular dependency resolution β F401 (7 issues): Unused imports in try/except blocks for optional dependency checks β Added comprehensive ruff configuration with per-file ignores
- β’ **Authentication Flow Improvements** β Fixed CSRF token endpoint to work without authentication when `auth_mode='none'` β Fixed ProtectedRoute and Layout to use `/settings/public` instead of admin-only endpoint β Eliminated ERROR logs ("No credentials provided") on page load before authentication β CSRF endpoint now uses `optional_auth` dependency, returns `{"csrf_token": None}` when disabled β Frontend no longer makes duplicate API calls to check auth_mode (centralized in AuthContext) β Resolved infinite loop issue (3 components independently calling `/settings/public` β 200+ requests)
- β’ **Frontend Validation Error Serialization** β Fixed `TypeError: Object of type ValueError is not JSON serializable` in error handlers β Validation errors now properly converted to JSON-serializable format before response
- β’ **Auth Mode 'None' Backend Validation** β Removed overly restrictive validation blocking `auth_mode='none'` changes (kept warning logs only) β Fixed AttributeError crashes from None user references in authorization helpers β Fixed 500 errors when accessing endpoints with `auth_mode='none'` enabled β Settings page now accessible without authentication when auth is disabled
π Security
- β’ **CRITICAL: Authentication & Authorization Hardening (Phase 1)** β All vehicle data endpoints now require authentication via `require_auth` dependency β Implemented per-vehicle authorization - users can only access their own vehicles β Added `user_id` column to vehicles table with foreign key to users (database migration 013) β Admin users retain access to all vehicles for support purposes β Production safeguard: `auth_mode='none'` blocked in production without explicit `MYGARAGE_ALLOW_AUTH_NONE=true` flag β Startup warning displayed when `auth_mode='none'` is active β Authentication dependencies: `require_auth()` (smart enforcement) vs `optional_auth()` (never enforces) β Authorization helpers: `get_vehicle_or_403()`, `check_vehicle_ownership()` with None user support β 24+ endpoints hardened: vehicles, service records, fuel records, photos, settings β Public settings endpoint (`/api/settings/public`) works without authentication for frontend initialization β Prevents unauthenticated data access and cross-user data leakage in production β Allows development without authentication when explicitly configured
- β’ **Dependency Security Validation (Phase 3)** β Zero vulnerabilities found in 79 scanned packages (Safety v3.7.0) β All dependencies up-to-date with no known CVEs β Key packages verified: fastapi 0.123.0, sqlalchemy 2.0.29, pillow 12.0.0, argon2-cffi 25.1.0
- β’ **Code Security Validation (Phase 3)** β Bandit scan: Only 2 findings, both acceptable design choices β 0.0.0.0 binding (required for Docker container networking) β MD5 for cache keys (non-cryptographic use case with `usedforsecurity=False`) β No actual security vulnerabilities detected in 41,554 lines of code β Strong security posture validated by automated scanning
β‘ Performance
- β’ **Service Layer Optimizations** β MPG calculation now cached with 5-minute TTL (automatic invalidation on data changes) β Photo hydration removed from request hot path (one-time migration instead) β N+1 query optimizations in ServiceRecordService (pre-fetches attachment counts via JOIN) β Reduced code size improves application load time and memory footprint
- β’ **Authentication Flow Optimization** β Single API call to check `auth_mode` instead of 3 duplicate calls β Resolved rate limit issues (200+ requests to `/settings/public` β 1 request) β Centralized state management prevents redundant network requests
π Technical Notes
- β’ **Service Layer Architecture**: Implements dependency injection, integrated authorization, complete business logic separation from HTTP layer
- β’ **Type Safety**: All functions use `Optional[User]` to force explicit null handling throughout codebase
- β’ **Smart Authentication**: Functions check `auth_mode` setting dynamically - no hardcoded auth bypass logic
- β’ **Graceful Degradation**: None users represent guest access with full permissions when auth is disabled
- β’ **Code Quality**: 71% reduction in linting issues, 69% reduction in main route file, production-ready code
- β’ **Backward Compatibility**: All API contracts maintained, photo endpoints work identically after extraction
- β’ Database migrations: 013 (user_id for multi-user support), 014 (legacy photo hydration)
v2.12.0 2025-11-28
β¨ Added
- β’ **Multi-Service Notification System** - Expanded from ntfy-only to 7 notification providers β **ntfy** - Self-hosted push notifications with optional token authentication β **Gotify** - Self-hosted push notification server β **Pushover** - iOS/Android push notifications β **Slack** - Team channel notifications via webhooks β **Discord** - Discord channel notifications via webhooks β **Telegram** - Bot-based notifications β **Email** - SMTP-based email notifications (with STARTTLS support) β Unified NotificationDispatcher with priority-based retry logic β Per-service test endpoints (`/api/notifications/test/{service}`) β Configurable retry attempts and delays with service-specific multipliers β Event-type toggles: recalls, service due/overdue, insurance/warranty expiring, milestones
- β’ **Frontend Notification Configuration UI** β Sub-tab navigation for switching between notification providers β Individual configuration forms for each service with enable toggle, credentials, and test button β Green dot indicators showing which services are enabled β Unified Event Notifications card with expandable sections β Advance warning day configuration for insurance, warranty, and service reminders β Two-column responsive layout (service config + event settings)
π Changed
- β’ Backend notification architecture refactored to abstract base class pattern
- β’ Settings system expanded with 24 new notification-related keys
- β’ Notification services use async HTTP (httpx) and async SMTP (aiosmtplib)
v2.11.0 2025-11-26
β¨ Added
- β’ **Frontend HTTP Error Handler** - New utility for consistent error message handling β `httpErrorHandler.ts` maps HTTP status codes to user-friendly messages β `parseApiError()` - Full error parsing with status, message, retry hints β `getErrorMessage()` - Simple error message extraction β `getActionErrorMessage()` - Context-aware messages ("Failed to save...") β Re-exported from `api.ts` for convenient access throughout frontend
π Changed
- β’ **Error Handling Standardization** - Refactored generic exception handlers to use specific exception types β Reduced generic `except Exception as e:` handlers from ~120 to ~71 (40% reduction) β API routes now use specific exceptions: `IntegrityError`, `OperationalError`, `httpx.*`, `FileNotFoundError`, etc. β Improved HTTP status codes: 409 for conflicts, 503 for database unavailable, 504 for timeouts β Better error messages that don't expose internal details β Remaining generic handlers are intentional fallbacks (CSV import rows, OCR, migrations)
π Fixed
- β’ **Backup Creation Logout Bug** - Fixed issue where creating backups would log users out β Exempted `/api/backup/*` routes from CSRF protection (already protected by JWT authentication) β Backup endpoints are idempotent with no user input, making CSRF protection redundant β Added CSRF token storage validation to catch sessionStorage failures early β Added console warnings when CSRF tokens are missing on state-changing requests β Removed duplicate CSRF token cleanup from middleware (performance optimization)
v2.10.0 2025-11-23
π Security
- β’ **CRITICAL: CSRF Protection** - Implemented synchronizer token pattern for cross-site request forgery protection β Added `csrf_tokens` database table with 24-hour token expiration β CSRF tokens automatically generated on login (both local and OIDC) β Middleware validates CSRF tokens on all state-changing operations (POST/PUT/PATCH/DELETE) β Tokens returned in login response for frontend integration β Automatic cleanup of expired tokens on logout and login
- β’ **CRITICAL: Settings Endpoint Security** - Fixed privilege escalation vulnerability β **BREAKING**: Split settings endpoints - `/api/settings/public` (no auth) for initialization, `/api/settings` (admin-only) for management β All settings CRUD operations now require admin privileges (`get_current_admin_user`) β Public endpoint returns only whitelisted settings: `auth_mode`, `app_name`, `theme` β Prevents unauthorized users from reading/modifying sensitive configuration (OIDC secrets, SMTP credentials, etc.)
- β’ **HIGH: JWT Cookie Security** - Auto-detect secure cookie flag based on environment β `jwt_cookie_secure` now auto-detects: `Secure=true` in production (`debug=false`), `Secure=false` in development β Prevents session token exposure over unencrypted HTTP in production β Explicit override available via `JWT_COOKIE_SECURE` environment variable β Default changed from `false` to environment-aware
- β’ **MEDIUM: OIDC State Persistence** - Database-backed state storage for multi-worker reliability β Added `oidc_states` database table with 10-minute expiration β Replaces in-memory dictionary storage β Supports multi-worker deployments and container restarts during authentication flows β State validation and one-time-use enforcement via database
- β’ **LOW: SQLite Pool Configuration** - Conditional pool settings for database compatibility β Pool configuration now only applied to PostgreSQL/MySQL β SQLite uses appropriate NullPool automatically β Prevents future SQLAlchemy compatibility issues
π Changed
- β’ **Database Migration 012**: Added `csrf_tokens` and `oidc_states` tables with indexes
- β’ CORS middleware now allows `X-CSRF-Token` header
- β’ Login and logout endpoints updated to manage CSRF tokens
- β’ OIDC callback endpoint updated to generate CSRF tokens
- β’ Settings routes refactored for public/admin separation
π Technical Notes
- β’ Frontend integration required: Store CSRF token from login response, send in `X-CSRF-Token` header for mutations
- β’ Addresses Codex security audit findings: HIGH and MEDIUM risk items resolved
- β’ Version bump: 2.8.0 β 2.10.0 (skipped 2.9.0 to align with frontend)
v2.8.0 2025-11-23
β¨ Added
- β’ **Garage Analytics Enhancements** β CSV export functionality for garage-wide data analysis β PDF export with professional garage report generation β Garage Analytics Help Modal with comprehensive feature documentation β Rolling average trend lines (3-month and 6-month) on monthly spending chart β Visual spending trend analysis with smooth overlay indicators
- β’ **Individual Vehicle Analytics Enhancements** β CSV export for vehicle-specific analytics data β PDF export with detailed vehicle reports β Export functionality mirrors garage analytics capabilities β Consistent export button styling across both analytics pages
π Changed
- β’ Standardized export button UI across Garage and Vehicle Analytics pages
- β’ Updated button styling to use garage theme colors for consistency
- β’ Removed "Export" prefix from button labels (now just "CSV" and "PDF")
π Technical Notes
- β’ Added `garage-primary`, `garage-primary-dark`, `success`, and `danger` color classes to Tailwind theme
- β’ Frontend analytics pages now fully support data export workflows
- β’ Export buttons use consistent `bg-garage-surface` styling with theme-aware hover states
v2.7.0 2025-11-23
β¨ Added
- β’ **OpenID Connect (OIDC) / SSO Authentication** β Complete OIDC authentication integration with support for external identity providers (Authentik, Keycloak, etc.) β "Sign in with SSO" button on login page with dynamic provider name display β OIDC callback success page with automatic token handling and redirect β Email-based account linking - automatically links OIDC accounts to existing local accounts via verified email β Dual authentication support - users can login with either password OR OIDC after linking β Admin UI for OIDC configuration in Settings β System β OIDC tab β Provider configuration: Issuer URL, Client ID/Secret, Scopes β Auto-generated redirect URI display β Test connection functionality with detailed result feedback β Claim mapping configuration (username, email, full name) β Group-based admin role mapping β Authentik setup guide with step-by-step instructions β Database schema additions: `oidc_subject`, `oidc_provider`, `auth_method` fields on User model β 12 new OIDC settings with defaults and validation β `/api/auth/oidc/config` - Public OIDC configuration endpoint β `/api/auth/oidc/login` - OIDC flow initiation endpoint β `/api/auth/oidc/callback` - Provider callback handler β `/api/auth/oidc/test` - Admin-only connection testing endpoint
π Security
- β’ **OIDC Security Features** β CSRF protection via state parameter validation (10-minute expiration) β Replay attack protection via nonce validation in ID tokens β JWT signature verification using provider's JWKS public keys β Issuer claim validation (prevents token reuse from other providers) β Audience claim validation (ensures tokens issued for MyGarage) β Expiration validation on all tokens β NULL password protection - OIDC-only users cannot authenticate via password login β Made `hashed_password` column nullable to support OIDC-only users (migration 011)
π Changed
- β’ Authentication system now supports multiple auth methods (local password + OIDC)
- β’ User model `hashed_password` field is now nullable (OIDC-only users have NULL password)
- β’ Login page conditionally displays SSO button based on OIDC configuration
π Dependencies
- β’ **Backend**: Added `authlib>=1.6.5` for OIDC/OAuth2 authentication
π Technical Notes
- β’ Backend implementation: 532-line OIDC service with complete OAuth2 flow
- β’ Frontend implementation: OIDC success page, login page SSO integration, settings UI
- β’ Database migration 011 applied to support OIDC fields
v2.6.0 2025-11-22
β¨ Added
- β’ **Light/Dark Theme System** β User-selectable theme toggle in Settings β System tab β Comprehensive light theme for all pages and components β React Big Calendar fully themed for both light and dark modes β Theme preference persisted in both localStorage (instant) and database (cross-device sync) β ThemeContext provider for global theme state management β Sun/Moon icon toggle UI with visual active state indication β Default theme remains dark mode for existing users β Tailwind v4 CSS variable architecture for clean theme switching β Refactored 48+ components to use semantic theme-aware classes β Light mode color palette: white cards (#ffffff) on light gray background (#f3f4f6) β Dark mode color palette: slate cards (#1a1f28) on dark background (#0a0e14)
π Fixed
- β’ **Light Mode Styling Issues** β Removed 200+ hardcoded dark gray button styles (`bg-gray-700`) across all components β Replaced with semantic `.btn-primary` class that adapts to both themes β Fixed modal overlays being too harsh in light mode (50% β 30% opacity) β Fixed badge colors not adapting to light mode background β Fixed text contrast issues with hardcoded gray colors β Corrected CSS architecture to properly use Tailwind v4 `@theme` directive β Eliminated redundant CSS variable overrides β Removed all `!important` hacks - proper specificity through CSS layers
π Security
- β’ **Password Hashing Migration: Bcrypt β Argon2** β Migrated from bcrypt 5.0.0 to Argon2id (argon2-cffi 25.1.0) β Argon2id is the current OWASP recommended password hashing algorithm β Hybrid verification system supports both legacy bcrypt and new Argon2 hashes β Auto-rehashing: User passwords transparently upgraded to Argon2 on next login β No password resets required - zero downtime migration β Removed 72-byte password length limitation (bcrypt restriction) β Argon2 parameters: time_cost=2, memory_cost=102400 (100MB), parallelism=8 β Migration tracking via automated database migration system (migration 010) β bcrypt temporarily retained for gradual migration support
π Changed
- β’ Tailwind CSS dark mode enabled via class-based switching
- β’ Theme preference stored in global settings table with category 'general'
- β’ CSS architecture updated to support dynamic theme switching via CSS variables
v2.5.2 2025-11-22
π Changed
- β’ **Automated Database Migration System** β Migrations now run automatically on container startup β Added `schema_migrations` tracking table β Renamed migration files with numeric prefixes for ordering β Extracted inline migrations from database.py to standalone files β Prevents schema drift between development and production β No manual migration execution required after deployments
π Fixed
- β’ Database migration system now prevents schema mismatch issues
- β’ Migration tracking persists across container restarts
v2.5.1 2025-11-22
π Security
- β’ **CRITICAL: Fixed default authentication mode** β Changed default `auth_mode` from `none` to `local` to require authentication by default β Previously, all endpoints were publicly accessible out-of-the-box until manually configured β New instances now require authentication immediately after first admin setup
- β’ **CRITICAL: Fixed rate limiting enforcement** β Wired up SlowAPI middleware to actually enforce rate limits β Previously, rate limit decorators were no-ops due to missing middleware β Auth endpoints now properly rate-limited at 5 requests/minute to prevent brute-force attacks β Upload endpoints now properly rate-limited at 20 requests/minute to prevent DoS β Default global rate limit of 200 requests/minute now enforced
- β’ **CRITICAL: Fixed open user registration** β Registration endpoint now restricted to first user only β After first admin is created, public registration is disabled β Added new admin-only `/api/auth/users` POST endpoint for admins to create accounts β New users created by admins default to inactive and non-admin status β Prevents unauthorized account creation on public instances
π Changed
- β’ User registration flow: Only first user can self-register (becomes admin)
- β’ Subsequent users must be created by administrators through user management UI
- β’ New users require admin activation before they can log in
v2.5.0 2025-11-22
β¨ Added
- β’ **Zod + React-Hook-Form Integration** β Implemented declarative form validation using Zod v4 schemas β Created reusable schema infrastructure in `/frontend/src/schemas/` β `shared.ts`: Common validators (mileage, currency, dates, etc.) β `auth.ts`: Authentication forms with password strength validation β `fuel.ts`: Fuel record validation β `service.ts`: Service record validation with type enum β `reminder.ts`: Conditional validation (date OR mileage required) β Added `FormError` component for field-level error display β Migrated Register and Login forms to use react-hook-form with zodResolver β Real-time validation with field-specific error messages β Password strength indicator in registration form
π Changed
- β’ **Dependency Updates** β Updated zod: 3.24.0 β 4.1.12 β Updated @hookform/resolvers: 3.9.0 β 5.2.2 β Updated react-hook-form: 7.54.0 β 7.61.1 β Updated axios: 1.7.0 β 1.13.2 β Updated lucide-react: 0.553.0 β 0.554.0 β Updated @types/react: 19.0.6 β 19.2.6 β Updated @types/react-big-calendar: 1.8.12 β 1.16.3 β Updated @types/react-dom: 19.0.2 β 19.2.3 β Updated @typescript-eslint packages: 8.46.4 β 8.47.0 β Updated vite: 7.2.2 β 7.2.4
π Fixed
- β’ **Critical: Password Validation Mismatch** β Fixed frontend password validation to match backend requirements β Frontend now validates: uppercase, lowercase, digit, special character (!@#$...) β Previously only checked length β₯ 8, causing confusing backend rejection errors β Users now get immediate, clear feedback about password requirements
v2.4.0 2025-11-21
β¨ Added
- β’ **Unified Document Scanner with Multi-Provider Insurance Support** β Consolidated PDF/image scanning architecture for all document types β Insurance documents now use same OCR engine as window stickers (PaddleOCR + Tesseract) β Auto-detection of insurance providers from document content β Provider-specific parsers: Progressive, State Farm, GEICO, Allstate β Generic fallback parser for unknown providers β Image upload support for insurance documents (jpg, png) in addition to PDF β New `/api/insurance/parsers` endpoint to list available parsers and OCR status β New `/api/vehicles/{vin}/insurance/test-parse` endpoint for debugging extraction β Confidence scoring (0-100%) for insurance extraction β Per-field confidence levels (high/medium/low) β Optional `provider` query parameter to hint parser selection
- β’ **Window Sticker OCR Display Enhancement** β Added display of all OCR-extracted fields that were previously stored but not shown β New Standard Equipment card (collapsible) showing categorized standard features β New Optional Equipment card (collapsible) with pricing from `window_sticker_options_detail` β New Packages card showing package groupings with prices β OCR metadata display (parser used, confidence score, VIN verification) β Drivetrain field now displayed in Powertrain card
ποΈ Removed
- β’ **pdfplumber dependency** β Removed unused pdfplumber library (PyMuPDF handles all PDF operations) β Reduces container size and maintenance burden
π Fixed
- β’ **Window Sticker Data Display Gap** β Fixed 8 OCR-extracted fields not being rendered in frontend despite being stored in database β Fields now displayed: `standard_equipment`, `optional_equipment`, `window_sticker_options_detail`, `window_sticker_packages`, `sticker_drivetrain`, `window_sticker_parser_used`, `window_sticker_confidence_score`, `window_sticker_extracted_vin`
- β’ **Stellantis OCR Parser Fixes** β Fixed environmental ratings extraction (GHG/Smog) - now correctly identifies actual ratings vs scale markers β Fixed equipment categorization - optional package items no longer appear under standard equipment β Fixed confidence score display (was showing 9500% instead of 95%)
v2.3.1 2025-11-19
π Changed
- β’ **Frontend JWT Authentication Migration** β Migrated 35 components from direct `fetch()` calls to centralized axios API client β All API requests now automatically include `Authorization: Bearer <token>` header β Consistent error handling with automatic logout/redirect on 401 errors β Improved type safety and code maintainability
π Fixed
- β’ **Authentication consistency** β Eliminated "No credentials provided" errors from components bypassing auth β Fixed JWT token not being sent with dashboard, settings, form, and page requests β Corrected authentication flow in backup/restore operations β Fixed file upload/download endpoints to properly use axios with FormData and blob responses β Fixed vehicle import/export JSON functionality
π Technical Details
- β’ Updated components (35 total): β Pages: Dashboard, Register, VehicleDetail, VehicleEdit β Settings tabs: System, Files, Integrations, Notifications, Backup, AddressBook β Forms: ServiceRecord, TollTag, TollTransaction, TaxRecord, SpotRental β Uploads: PhotoUpload, WindowStickerUpload β Lists: TollTagList, TollTransactionList, TaxRecordList, SpotRentalList β Tabs: TollsTab β Utilities: AddressBookSelect, AddressBookAutocomplete, ReportsPanel, ProtectedRoute β Hooks: useAppVersion
- β’ All file downloads now use `responseType: 'blob'` with axios
- β’ FormData uploads work seamlessly without additional configuration
- β’ Updated fallback version in useAppVersion to 2.3.1
v2.3.0 2025-11-15
β¨ Added
- β’ **Propane tracking for fifth wheel vehicles** β Added `propane_gallons` field to fuel records (Numeric 8,3 precision) β New propane input field in fuel record form β Propane column in fuel record list view β Automatic database migration on startup β Input validation (0-999.999 gallons, 3 decimal places)
- β’ **Security improvements** (10 major fixes) β Path traversal protection for document uploads β VIN pattern validation (17-character alphanumeric) β SQL injection prevention via parameterized queries β MIME type validation for file uploads (PDF, images) β File size limits (10MB for images, 50MB for PDFs) β Password length limits (72 bytes for bcrypt compatibility) β Email format validation (max 254 characters) β User input sanitization across all endpoints β Rate limiting headers exposed in CORS configuration β Comprehensive error handling with proper HTTP status codes
π Fixed
- β’ **Critical:** Fixed fifth wheel fuel tab access β Corrected boolean operator precedence in vehicle type check β Fifth wheels can now properly access fuel tracking features
- β’ **Security:** Prevented path traversal in document downloads β Added strict filename validation β Restricted access to user-owned documents only
- β’ **Security:** Added MIME type validation for uploads β Prevents execution of malicious files β Validates against allowed types (PDF, JPG, PNG, HEIC, etc.)
- β’ **Security:** Implemented file size limits β Images: 10MB maximum β PDFs: 50MB maximum β Prevents DoS attacks via large file uploads
- β’ Input validation edge cases across multiple endpoints β Maintenance records: validated mileage, date ranges β Fuel records: validated amounts, prices, odometer readings β Documents: validated descriptions, file metadata β Settings: validated configuration values
π Changed
- β’ Updated version to 2.3.0 (MINOR bump for propane feature)
- β’ Enhanced fuel record form layout (3-column grid)
- β’ Improved About page organization and statistics
v2.2.1 2025-11-15
π Fixed
- β’ **Critical:** Removed non-functional token refresh logic β Eliminated dead code calling non-existent `/api/auth/refresh` endpoint β Simplified authentication flow β Reduced unnecessary API calls
- β’ **Critical:** Fixed React hooks compliance violations β Added proper `useCallback` wrappers in AuthContext β Fixed PhotoGallery dependencies β Corrected Calendar.tsx hook dependencies β Removed all `eslint-disable` comments for hooks
- β’ Removed 11 production console.log statements β Kept only PWA-related debug logs β Cleaner console output
β‘ Performance
- β’ **Added React.memo to 17 expensive components** β VehicleCard, PhotoGallery, ReminderCard, MaintenanceRecordItem β DocumentCard, FuelCard, FuelRecordList, MaintenanceRecordList β DocumentList, ReminderList, VehicleList, TabContent components β Analytics charts and reports components β Reduces unnecessary re-renders β Improved list/grid rendering performance
- β’ Optimized component re-rendering patterns
π Improved
- β’ **Code quality** - Better React patterns and hooks compliance
- β’ **Developer experience** - No more lint warnings
- β’ **Production logs** - Reduced noise, better signal
v2.2.0 2025-11-15
π Changed
- β’ **MAJOR:** Migrated from Uvicorn to Granian ASGI server β **+11% requests/sec** (45,000 β 50,000) β **-25% memory usage** (20MB β 15MB per worker) β More consistent latency (2.8x max/avg vs 6.8x) β Single worker mode for APScheduler compatibility
- β’ **MAJOR:** Removed deprecated libraries β Removed moment.js (~232KB), replaced with date-fns (~78KB) - **-154KB** β Removed unused chart.js and react-chartjs-2 - **-200KB** β Total bundle savings: **~350KB**
- β’ **MAJOR:** Implemented frontend code splitting β Route-based lazy loading for all pages β Manual chunk configuration (react-vendor, charts, calendar, ui, forms, utils) β **-78% initial bundle size** (~900KB β ~200KB) β **-60% time to interactive** (~2.5s β <1s)
- β’ **MAJOR:** Migrated to @vitejs/plugin-react-swc β Faster builds using SWC instead of Babel β Better development experience
- β’ Fixed Tailwind v4 PostCSS configuration β Created `postcss.config.js` with @tailwindcss/postcss plugin β Added autoprefixer support β Simplified tailwind.config.js (theme moved to CSS)
β¨ Added
- β’ Created `pyproject.toml` for modern Python packaging β Version management in single source of truth β Dev dependencies separated (pytest, ruff) β Better tooling support
- β’ **Health check logging filter** β Suppresses Docker health check logs from access logger β Reduces log noise while preserving API request visibility β Applied to Granian access logger
π Security
- β’ **bcrypt v5.0 password validation** β Added password length checks (max 72 bytes) β Prevents silent truncation vulnerability β Returns clear error for invalid passwords
π Updated
- β’ **Backend dependencies:** β FastAPI: 0.121.0 β 0.121.1 β APScheduler: 3.10.4 β 3.11.1 β Pydantic: 2.12.0 β 2.12.3 β Pillow: 11.0.0 β 12.0.0 (Python 3.14 support) β Added Granian: 2.5.7
- β’ **Frontend dependencies:** β lucide-react: 0.468.0 β 0.553.0 β react-router-dom: 7.1.1 β 7.9.6 β recharts: 3.3.0 β 3.4.1 β TypeScript: 5.6.2 β 5.9.3 β @types/react: 19.0.0 β 19.0.6 β @types/react-dom: 19.0.0 β 19.0.2 β Added date-fns: 4.1.0 β Added @tailwindcss/postcss: 4.1.17 β Added autoprefixer: 10.4.20
- β’ **v2.1.0:** Authentication UI redesign, dependency updates (Tailwind v4, Vite 7), security improvements, zero-config
- β’ **v2.0.0:** Backup system, service consolidation, enhanced features
- β’ **v1.x:** Initial development phases (7 major phases + 12 feature phases)
Key Features
Vehicle Profiles
Add vehicles by VIN and get automatic decoding via NHTSA. Stores make, model, year, engine, transmission, and more.
Service Records
Log oil changes, repairs, tire rotationsβanything. Attach receipts, set the mileage, track costs. Full history per vehicle.
Fuel Tracking
Log fill-ups and get automatic MPG calculations. Separate tracking for towing/hauling to see how loads affect efficiency.
Multi-Service Notifications
7 notification providers: ntfy, Gotify, Pushover, Slack, Discord, Telegram, and Email. Get alerts for maintenance, recalls, and expirations.
Recall Checking
Automatic NHTSA recall lookup by VIN. See active recalls, completion status, and links to CarComplaints for known issues.
OCR Receipt Scanning
Upload a photo of a receipt and Tesseract OCR extracts the vendor, date, amount, and line items automatically.
Analytics Dashboards
Garage analytics for spending trends across all vehicles. Individual dashboards show cost breakdown per car with charts.
Calendar View
See upcoming maintenance and past services on a calendar. Visual timeline of everything that's happened and what's coming.
OIDC/SSO Auth
Works with Authentik, Keycloak, or any OIDC provider. Multiple users with admin/regular roles. Or just use local accounts.
PDF & CSV Exports
Export service history, fuel logs, and analytics as PDF reports or CSV files. Good for insurance claims or selling a vehicle.
Address Book
Keep track of mechanics, dealerships, and parts stores. Link service records to providers for quick reference.
Light/Dark Theme
Toggle between light and dark themes. Your preference is saved and syncs across devices.
Why Self-Host?
Your data stays with you
No cloud accounts, no subscriptions, no third parties seeing your maintenance records or vehicle info.
Works offline
Once deployed, everything works on your local network. No internet needed to log a service or check your history.
Multiple users
Household members can each have their own account and vehicles. Admin users manage settings and user access.
Full backups
Built-in backup/restore. Download your entire database and uploads as a zip file whenever you want.
Screenshots
Login
Clean login page with support for local accounts and OIDC/SSO providers like Authentik or Keycloak.
Dashboard
Overview of all your vehicles with quick stats, recent activity, and upcoming maintenance reminders at a glance.
Analytics
Garage-wide analytics showing spending trends, fuel economy, and cost breakdowns across all vehicles with interactive charts.
Vehicle Overview
Individual vehicle page with VIN-decoded specs, photo gallery, and quick access to all maintenance records.
Service History
Complete service log with dates, mileage, costs, and vendors. Attach receipts and documents to any service record.
Fuel History
Track fill-ups with automatic MPG calculations. Separate tracking for normal driving vs. towing/hauling to see efficiency impact.
Odometer Tracking
Visual timeline of mileage over time with automatic syncing from service and fuel records.
Recall Checking
Automatic NHTSA recall lookup by VIN. See active recalls, descriptions, and remedies with links to CarComplaints for known issues.
Maintenance Reminders
Set reminders by date or mileage. Supports recurring schedules and push notifications when maintenance is due.