Commit Graph
3 Commits
Author SHA1 Message Date
nilsandClaude Opus 5.5 51e6f6fd48 Server: rewrite in Go as an API-only service
Same endpoints, request formats, validation rules and InfluxDB layout as
the Next.js server, so the car needs no change: POST /v1/telemetry,
PUT /v1/consumption/daily, PUT /v1/charging-sessions/{id}, GET
/v1/consumption/history/{id}, GET /v1/health. The dashboard, login and
the /v1/history reads are gone; Grafana takes over the dashboards.

- Go 1.26 standard library (net/http routing, log/slog) plus the
  official InfluxDB 2 client. Fails closed at startup on a missing
  InfluxDB setting or an ingest token under 24 characters.
- ABRP forwarder ported: newest fresh sample, rate limited, never
  queued, credentials only in the form body.
- 22 tests: validation, aggregation, forwarding, config, and the
  handlers through a fake store. govulncheck clean (x/net 0.60.0,
  toolchain go1.26.9).
- Image: static binary on distroless, about 11 MB, UID 65532, port
  8080; the build runs vet and the tests.
- Dev shell: Go, gopls and govulncheck instead of Node.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
2026-10-17 15:17:42 +02:00
TCFDONMEZandClaude Opus 5 8242797ece Replace the Express service with a Next.js app on Vercel
The standalone service in server/ was never deployed anywhere, and keeping it
alongside a Vercel app would mean maintaining two implementations of the same
validation rules. It is deleted; web/ is the only ingest path now. Its routes
live at /v1/... rather than under /api, so the Android client's URL building is
unchanged and CONSUMPTION_API_URL stays a bare origin.

Credentials are split in two. INGEST_TOKEN is baked into the published APK and
must be assumed extractable — anyone can unzip an APK and read its strings — so
it opens the PUT endpoints and nothing else. Reading the history needs the
dashboard password, which is never compiled into anything and reaches the
browser as an HMAC-signed httpOnly cookie. The MongoDB URI stays a server-side
environment variable; the car has never held one and still does not.

The dashboard is a phone-shaped reader for the same data: totals for energy
taken and paid, a daily energy chart, an efficiency trend, and every DC session
with its power/SOC curve. It reuses the head unit's OLED palette so the two read
as one app. Every page is a server component and the charts are hand-rolled SVG,
so the whole thing renders without shipping client JavaScript.

MongoClient is cached on globalThis: a fresh client per request means a fresh
pool per request, and Atlas starts refusing connections long before the traffic
would justify it. Index creation moved to the first write of each warm lambda,
since a serverless deployment has no boot step to hang it on.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-08 14:21:37 +03:00
TCFDONMEZ 9a6c121d09 Rename app and persist all-time consumption to MongoDB 2026-10-08 13:23:00 +03:00