Files
DriverVault/README.md
T
tajniak81andClaude Opus 5 9487de84b0 Docker AIO: a folder name without a space in it
The all-in-one folder is now Docker-AIO, so -f Docker-AIO/Dockerfile
resolves without quoting. Every path that pointed at the old name
follows it: the compose build stanza, the documented build commands,
and the links from the two READMEs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 20:01:19 +02:00

140 lines
7.6 KiB
Markdown

# DriverVault
A car control & service-tracking system (originally "Car Control Project").
Built incrementally — starting with a **car maintenance tracker** (modeled on
`Car Service.xlsx`) and growing toward live integration with the car via a
cellular ESP32 device and third-party services (Toyota Connected, EV chargers).
## Architecture
All clients communicate with the database **only through the API Server**
nothing talks to PocketBase directly.
```
┌──────────────────┐
Web App (Vue) ─────▶│ │
Phone App (Flutter)▶│ API Server │────▶ PocketBase
Home Assistant ────▶│ (Go, stdlib) │ (10.2.1.10:8027)
Car Agent (ESP32) ─▶│ │
└──────────────────┘
```
| Component | Stack | Status | Docs |
|---|---|---|---|
| **API Server** | Go (stdlib) | ✅ built, running, verified | [API Server/README.md](API%20Server/README.md) |
| **Database** | PocketBase | ✅ running, schema + seed done | — |
| **Web App** | Vue 3 + Vite + Tailwind v4 | ✅ full feature set (below) | [Web App/README.md](Web%20App/README.md) |
| **Phone App** | Flutter (Android) | ✅ web parity + biometric login | [Phone App/README.md](Phone%20App/README.md) |
| **Docker** | Compose (multi-container / all-in-one) | ✅ deployment configs | [Docker/README.md](Docker/README.md) · [Docker-AIO/README.md](Docker-AIO/README.md) |
| **Car Agent Device** | ESP32 + SIM7600 (LILYGO TTGO) | 🚧 firmware in progress | [Car Agent Device](Car%20Agent%20Device) |
| **Home Assistant Plugin** | — | ⬜ later | — |
The Web and Phone apps are at feature parity (the phone omits only data
export/import).
## Features
- **Maintenance tracking** — cars, service history (date/odometer + which parts
were changed), and a per-car parts catalog, with next-due date/km status from
the spreadsheet formulas.
- **Technical checks** — the mandatory roadworthiness inspections (przegląd
techniczny / MOT / TÜV): result, cost, station and the certificate's
valid-until, which overrides the car's interval and drives the next-due date.
- **Maintenance log** — workshop visits and repairs outside the routine schedule:
type/status, workshop, parts used, labour + parts cost, invoice, warranty-until.
- **Fuel tracking** — refills with derived efficiency (average / best / worst
consumption, cost per km, price per litre). Consumption is measured between
full tanks, so partial fills roll into the next full one.
- **Documents** — insurance, registration, road tax and the rest, each with a
server-computed renewal/expiry state.
- **Reminders** — date- and/or odometer-triggered, one-off or recurring, plus
read-only reminders the server derives from documents and service records.
- **Attachments** — one optional file (PDF or image) per service record,
technical check, maintenance entry, refill, document and part; fetched back
through the API Server, never a public URL.
- **Accounts** — PocketBase-token login, profile + appearance preferences
(theme/locale/date format/currency/font), avatar, email verification, data
export/import, and an account-deletion state machine.
- **Organizations & roles** — multi-tenant `user` / `admin` / `superadmin`
roles; admins manage users within their own organization, superadmins span all.
Any user without an organization can create one and becomes its admin.
- **Per-user ownership & sharing** — each car has an owner and can be shared with
other users as read or write; the UI mirrors the server's access checks.
- **Integrations** — per-user connectors under a superadmin → org-admin → user
cascade. Built-in today: **Toyota Connected** (read-only vehicle data) and the
**Anker Solix** V1 EV charger.
- **Cars from the manufacturer's own service** — import a car straight off a
connected account (MyToyota today), choosing what to pull in, and read everything
that service knows about it from a dedicated first tab on the car. Generic over
providers: the next manufacturer is one adapter in the API Server.
- **EV charging control** — for Anker Solix chargers the API Server runs an
**OCPP 1.6J Central System**; in own/proxy mode the charger dials back in and
the owner can start/stop and set limits from the Charging screen.
- **Translated UI** — the interface reads its text from per-language files
(English, Polish, Danish today), with English as the fallback for any
untranslated string. See [TRANSLATIONS.md](TRANSLATIONS.md).
- **Phone biometric login & app lock** — fingerprint / face sign-in with an
app-lock that requires an unlock on relaunch. See the Phone App README.
## Auth model
All apps share one auth model: **authentication is PocketBase's own.**
`POST /api/auth/login` is proxied to the PocketBase users collection and the
client keeps the token PocketBase minted — the API Server does **not** issue its
own JWT. Every protected request carries `Authorization: <token>` (both
`Bearer <token>` and a raw token are accepted) and the server re-resolves it
against PocketBase on each call, so a role change or a deletion takes effect
immediately. Tokens are stateless, so there is no per-device session list;
changing an account's password rotates its token key and invalidates every token
already issued. Access to cars/records is gated by per-user ownership and shares;
user management requires the admin or superadmin role. Creating an organization
is the one management action open to a plain user — it promotes them to admin of
the organization they just created.
## Domain (from `Car Service.xlsx`)
- **Cars** — one per vehicle (was: one spreadsheet sheet), with spec fields
(engine / transmission / differential oil, brake fluid, coolant, VIN, fuel
type, build / first-registration dates, …) and configurable service intervals.
- **Service records** — date + odometer per service, plus which parts were
changed (oil & oil filter, engine air filter, cabin air filter).
- **Parts** — per-car catalog of part numbers.
Key spreadsheet formulas, reproduced by the API Server on read:
```
Next Service Date = service date + serviceIntervalDays (default 365; Excel: =A+365)
Next Service Km = service km + serviceIntervalKm (default 15 000; Excel: =B+15000)
```
Intervals are configurable per car.
## Getting started
Bring up the stack in this order — each app's README has the details:
1. **[API Server](API%20Server/README.md)** — configure `.env`, run
`setup-pocketbase.mjs`, start the server. This must be running for either app.
2. **[Web App](Web%20App/README.md)** — `npm install && npm run dev`
(proxies `/api` to the server).
3. **[Phone App](Phone%20App/README.md)** — `flutter build apk` /
`flutter run` with `--dart-define=API_BASE=http://<server-ip>:8080/api`.
Or skip all of that and bring the whole stack up with **Docker**, which runs the
schema setup itself — see [Docker](Docker/README.md) (PocketBase + API Server +
Web App as three containers) or [Docker-AIO](Docker-AIO/README.md) (all three
in a single image).
## Layout
```
DriverVault/
├── API Server/ # Go gateway to PocketBase (the only DB client)
├── Web App/ # Vue 3 + Vite + Tailwind v4 SPA + Go BFF
├── Phone App/ # Flutter (Android)
├── Car Agent Device/ # ESP32 + SIM7600 firmware (LILYGO TTGO T-SIM7600)
├── Home Assistant Plugin/ # later phase
├── Docker/ # Compose deployment (API Server + Web App)
└── Docker-AIO/ # single all-in-one image
```