Refresh docs and fix Docker builds for current layout
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>
This commit is contained in:
1 parent
f9b1bcc520
commit
1e76c2b7f9
15 files changed
+301
-138
No files matched your search
@@ -0,0 +1,17 @@
|
||||
# Keep the build context small and avoid leaking local artifacts/secrets.
|
||||
.env
|
||||
*.log
|
||||
*.exe
|
||||
*.exe~
|
||||
|
||||
# Frontend deps + generated output — rebuilt inside the image.
|
||||
web/node_modules/
|
||||
web/dist/
|
||||
server/dist/
|
||||
|
||||
# VCS / editor / tooling noise
|
||||
.git/
|
||||
.gitignore
|
||||
.claude/
|
||||
.vscode/
|
||||
.idea/
|
||||
@@ -0,0 +1,51 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
#
|
||||
# Web App image: the Vue SPA is built and embedded into the Go backend-for-
|
||||
# frontend (BFF), which serves it and reverse-proxies /api/* to the API Server
|
||||
# (API_BASE). This mirrors the production Run-WebApp.ps1 flow, so the browser is
|
||||
# always same-origin and all data access still flows through the API Server.
|
||||
#
|
||||
# Build context is the "Web App" directory (see Docker/docker-compose.yml).
|
||||
|
||||
# --- Stage 1: build the Vue SPA ---------------------------------------------
|
||||
FROM node:22-alpine AS web-build
|
||||
WORKDIR /web
|
||||
COPY web/package.json web/package-lock.json ./
|
||||
RUN npm ci
|
||||
COPY web/index.html web/vite.config.js ./
|
||||
COPY web/src ./src
|
||||
COPY web/public ./public
|
||||
# Empty -> bundle uses same-origin "/api", which the BFF proxies to API_BASE.
|
||||
ARG VITE_API_BASE=""
|
||||
ENV VITE_API_BASE=${VITE_API_BASE}
|
||||
# vite.config writes to ../server/dist by default; emit into ./dist here so the
|
||||
# next stage can embed it.
|
||||
RUN npm run build -- --outDir dist --emptyOutDir
|
||||
|
||||
# --- Stage 2: build the Go BFF, embedding the SPA ---------------------------
|
||||
FROM golang:1.26-alpine AS server-build
|
||||
WORKDIR /src
|
||||
COPY server/go.mod ./
|
||||
# go.sum is optional (stdlib-only module today); copy it if present.
|
||||
COPY server/go.su[m] ./
|
||||
RUN go mod download
|
||||
COPY server/ ./
|
||||
# Embed the freshly built SPA (main.go uses //go:embed all:dist).
|
||||
COPY --from=web-build /web/dist ./dist
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-s -w" -o /out/web-bff .
|
||||
|
||||
# --- Runtime stage ----------------------------------------------------------
|
||||
FROM alpine:latest
|
||||
RUN apk add --no-cache ca-certificates tzdata \
|
||||
&& addgroup -S app && adduser -S -G app app
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=server-build /out/web-bff /app/web-bff
|
||||
|
||||
# Config comes from environment variables (see server/.env.example).
|
||||
ENV WEB_ADDR=:8090 \
|
||||
API_BASE=http://api-server:8080
|
||||
EXPOSE 8090
|
||||
|
||||
USER app
|
||||
ENTRYPOINT ["/app/web-bff"]
|
||||
+46
-25
@@ -15,20 +15,25 @@ Browser ─► Web App BFF (:8090) ──/api/*──► API Server (:8080) ─
|
||||
```
|
||||
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), /cars/:id, /settings, /admin
|
||||
api.js the only place that calls the API Server (base URL resolution)
|
||||
auth.js session/profile state, isAdmin
|
||||
prefs.js theme/locale/date/font preferences -> <html>
|
||||
lib/format.js date/km formatting + next-service status badges
|
||||
style.css Tailwind v4 entry (+ dark custom-variant)
|
||||
App.vue layout shell + nav (Admin link when admin)
|
||||
components/ Modal, CarFormModal, ServiceFormModal, PartFormModal, ShareModal, Logo
|
||||
views/ Login, Dashboard, CarDetail, Settings, AdminUsers
|
||||
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
|
||||
@@ -42,7 +47,7 @@ Two terminals:
|
||||
|
||||
```powershell
|
||||
# terminal 1 — API Server (see ../API Server/README.md)
|
||||
cd "../API Server"; ./api-server.exe
|
||||
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
|
||||
@@ -78,16 +83,30 @@ Config (`server/.env`, copy from `.env.example`):
|
||||
- **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** — full service history (date, km, computed next date/km, and the
|
||||
changed-parts flags) plus the per-car parts catalog and all car spec fields
|
||||
(engine / transmission / differential oil, brake fluid, coolant, VIN, …).
|
||||
Add/edit/delete service records, parts, and the car; **share** the car with
|
||||
other users (read/write, owner only). Edit/delete controls are hidden for
|
||||
read-only shares.
|
||||
- **Settings** — account (name / email verification / password), appearance
|
||||
(theme light/dark/system, locale, date format, font size), profile (avatar,
|
||||
bio), data **export/import**, active sessions with remote logout, and the
|
||||
account-deletion state machine.
|
||||
- **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`
|
||||
@@ -95,7 +114,9 @@ Config (`server/.env`, copy from `.env.example`):
|
||||
|
||||
## Auth & access
|
||||
|
||||
Login gets a JWT from the API Server (stored client-side) and creates a server
|
||||
session. `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.
|
||||
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.
|
||||
Reference in new issue
Block a user