Restructure Web App into server/ + web/ (GsmNode parity)
Reorganize the Web App to match the GsmNode project layout: a Go backend-for-frontend in server/ that embeds the built SPA and reverse-proxies /api/* to the API Server, with the Vue 3 + Vite frontend moved into web/. - Move all frontend files into web/ (history preserved via renames) - Point vite build output at ../server/dist for Go embedding - Add server/ Go BFF (main.go, go.mod, .env.example, Run-WebApp.ps1) - Drop Docker/nginx deploy (Dockerfile, docker-compose.yml, nginx.conf.template, .dockerignore) in favor of the BFF, matching GsmNode - Update .claude/launch.json to run the dev server from web/ - Rewrite README.md for the new layout Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
ba3f227361
commit
75a2ccc226
47 files changed
+230
-161
No files matched your search
+60
-34
@@ -1,27 +1,78 @@
|
||||
# DriverVault — Web App
|
||||
|
||||
Vue 3 + Vite + Tailwind CSS v4 maintenance tracker. Talks **only** to the API
|
||||
Server (never to PocketBase directly). Built from `Car Service.xlsx`. Plain JS
|
||||
(not TS). Vue calls the central API Server directly — there is no separate web
|
||||
backend.
|
||||
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).
|
||||
|
||||
## Run
|
||||
```
|
||||
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
|
||||
.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
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
- Node 18+ and Go 1.26+
|
||||
- A running **API Server** (see `../API Server`)
|
||||
|
||||
## Develop
|
||||
|
||||
Two terminals:
|
||||
|
||||
```powershell
|
||||
npm install
|
||||
npm run dev # http://localhost:5173
|
||||
# terminal 1 — API Server (see ../API Server/README.md)
|
||||
cd "../API Server"; ./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. The **API Server must be running** — see `../API Server/README.md`.
|
||||
The dev server also listens on all interfaces (`host: true`) so it's reachable on
|
||||
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
|
||||
@@ -48,28 +99,3 @@ 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.
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
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.vue CarFormModal.vue ServiceFormModal.vue PartFormModal.vue ShareModal.vue
|
||||
└── views/
|
||||
├── Login.vue Dashboard.vue CarDetail.vue
|
||||
└── Settings.vue AdminUsers.vue
|
||||
```
|
||||
|
||||
## Build
|
||||
|
||||
```powershell
|
||||
npm run build # -> dist/
|
||||
```
|
||||
Reference in new issue
Block a user