READMEs: correct the auth model (PocketBase token relay, not JWT/sessions), document the full feature set (technical checks, fuel, maintenance, documents, reminders, attachments, integrations, OCPP charging control), the shipping built-in connectors (toyota, anker-solix), and the current endpoint surface. Docker: build against the current repo layout — Go 1.26, cmd/server entry point, Web App source under web/. Add the missing Web App Dockerfile (Go BFF) and .dockerignore, drop the obsolete AUTH_SECRET, modernise CORS var naming, and standardise on drivervault-* naming. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
123 lines
5.6 KiB
Markdown
123 lines
5.6 KiB
Markdown
# DriverVault — Web App
|
|
|
|
Maintenance tracker for your cars: a **Vue 3 + Vite + Tailwind CSS v4** SPA served
|
|
by a small **Go backend-for-frontend (BFF)**. The BFF serves the built SPA and
|
|
reverse-proxies `/api/*` to the API Server, so the browser is always same-origin
|
|
and all data access still flows through the API Server (never PocketBase directly).
|
|
|
|
```
|
|
Browser ─► Web App BFF (:8090) ──/api/*──► API Server (:8080) ─► PocketBase
|
|
└── serves embedded Vue SPA
|
|
```
|
|
|
|
## Layout
|
|
|
|
```
|
|
server/ Go BFF: embeds web/dist, proxies /api -> API_BASE
|
|
main.go
|
|
Run-WebApp.ps1 build frontend, then serve
|
|
.env.example
|
|
dist/ built SPA (generated; embedded at compile time)
|
|
web/ Vue 3 + Vite + Tailwind v4 source
|
|
src/
|
|
main.js app bootstrap
|
|
router.js /login, / (dashboard), /charging, /cars/:id, /settings, /admin
|
|
api.js the only place that calls the API Server (base URL resolution)
|
|
auth.js token/profile state, isAdmin
|
|
prefs.js theme/locale/date/font preferences -> <html>
|
|
i18n/ en / pl / da translation files + loader
|
|
lib/format.js date/km formatting + next-service status badges
|
|
lib/attachment.js upload / fetch / open a record's attached file
|
|
style.css Tailwind v4 entry (+ dark custom-variant)
|
|
App.vue layout shell + nav (Charging + Admin links when relevant)
|
|
components/ Modal, AttachmentField, CarFormModal, ServiceFormModal,
|
|
TechnicalCheckFormModal, MaintenanceFormModal, FuelFormModal,
|
|
DocumentFormModal, ReminderFormModal, PartFormModal, ShareModal, Logo
|
|
views/ Login, Dashboard, CarDetail, Charging, Settings, AdminUsers
|
|
```
|
|
|
|
## Requirements
|
|
|
|
- Node 18+ and Go 1.26+
|
|
- A running **API Server** (see `../API Server`)
|
|
|
|
## Develop
|
|
|
|
Two terminals:
|
|
|
|
```powershell
|
|
# terminal 1 — API Server (see ../API Server/README.md)
|
|
cd "../API Server"; .\bin\api-server.exe
|
|
|
|
# terminal 2 — Vite dev server with hot reload (proxies /api -> :8080)
|
|
cd web; npm install; npm run dev # http://localhost:5173
|
|
```
|
|
|
|
The dev server proxies `/api/*` to the API Server (default `http://localhost:8080`,
|
|
override with `VITE_API_TARGET`), so the client uses same-origin relative URLs and
|
|
avoids CORS. It also listens on all interfaces (`host: true`) so it's reachable on
|
|
the LAN (e.g. `http://10.2.1.101:5173`).
|
|
|
|
At runtime, users can override the API base URL from the login screen's **Server
|
|
settings** (persisted in `localStorage` as `cc_server_url`); resolution order is
|
|
that override → `VITE_API_BASE` → `/api`.
|
|
|
|
## Build & run (production-style)
|
|
|
|
```powershell
|
|
./server/Run-WebApp.ps1 # builds frontend, then serves on :8090
|
|
# or manually:
|
|
cd web; npm run build # outputs to ../server/dist
|
|
cd ../server; go run . # http://localhost:8090
|
|
```
|
|
|
|
Config (`server/.env`, copy from `.env.example`):
|
|
|
|
| Variable | Purpose | Default |
|
|
|---|---|---|
|
|
| `WEB_ADDR` | Listen address | `:8090` |
|
|
| `API_BASE` | API Server base URL | `http://localhost:8080` |
|
|
|
|
## Features
|
|
|
|
- **Dashboard** — one card per car: last service, odometer, next-due date/km, and
|
|
a status badge (OK / due soon ≤30d / overdue) from the Excel formulas. Add a
|
|
car; shared cars are labelled and gated by your access level.
|
|
- **Car detail** — all car spec fields (engine / transmission / differential oil,
|
|
brake fluid, coolant, VIN, fuel type, …) plus tabbed histories, each with an
|
|
optional file attachment and add/edit/delete gated by your access level:
|
|
- **Service history** — date, km, computed next date/km, and changed-parts flags.
|
|
- **Technical checks** — roadworthiness inspections; result, cost, station and
|
|
the certificate's valid-until, which drives the next-due date.
|
|
- **Maintenance** — workshop visits and repairs (type/status, workshop, parts,
|
|
labour + parts cost, invoice, warranty-until).
|
|
- **Fuel** — refills with a summary panel (average / best / worst consumption,
|
|
cost per km, price per litre), measured between full tanks.
|
|
- **Documents** — insurance, registration, road tax, … with a renewal badge.
|
|
- **Parts** — the per-car parts catalog.
|
|
- **Reminders** — date/odometer, one-off or recurring; server-derived ones are
|
|
read-only.
|
|
|
|
Also **share** the car with other users (read/write, owner only); edit/delete
|
|
controls are hidden for read-only shares.
|
|
- **Charging** — the EV charging screen for connected Anker Solix chargers:
|
|
live status and, in own/proxy control mode, start/stop and charge-limit
|
|
controls driven by the API Server's OCPP Central System.
|
|
- **Settings** — split into tabs: account (name / email verification / password),
|
|
appearance (theme light/dark/system, locale, date format, currency, font size),
|
|
profile (avatar, bio), **integrations** (Toyota, Anker Solix), data
|
|
**export/import**, and the account-deletion state machine.
|
|
- **Admin** — `/admin` user management (list / create / role / reset password /
|
|
delete), gated by the admin role via a router guard + nav link.
|
|
- **Theming** — light/dark/system app-wide (Tailwind v4 class strategy); `prefs.js`
|
|
toggles `.dark` on `<html>` and applies the saved theme/locale/date/font.
|
|
|
|
## Auth & access
|
|
|
|
Login proxies to the API Server, which relays PocketBase's own token — there is
|
|
no JWT the server mints and no server-side session list. The token is stored
|
|
client-side and sent as `Authorization` on every call. `auth.js` exposes
|
|
`isAdmin` and the current profile; the router guards `public` / `admin` routes.
|
|
Cars are per-user (owned + shared), and the UI mirrors the server's read / write
|
|
/ owner access levels.
|