@solelog/worker
The SoleLog Worker timing client: a lean Vite + React + TypeScript single-page app,
installable as a PWA. It logs a worker in (email + password → bearer token in localStorage),
attaches Authorization: Bearer <token> to every API call, and reproduces the three Dutch screens
Stopwatch / Geschiedenis / Instellingen against the @solelog/api backend.
No Expo, no React Native, no ngrok / tunnelling. This is a plain web app. It runs in any browser at
http://localhost:5173, and on a phone on the same LAN via the PC's IP — no tunnel.
Prerequisites
-
Node + Corepack (Yarn 4.12.0 is pinned in the repo).
-
From the repo root, install everything once:
yarn install
Run it
Two processes: the API on :3000 and the worker SPA on :5173.
1. Backend API (:3000)
From the repo root:
yarn workspace @solelog/api db:migrate # apply migrations (creates ./data/app.db on first run)
yarn workspace @solelog/api db:seed # idempotent: seeds the reference activities
yarn workspace @solelog/api start # Hono server on http://localhost:3000
2. Worker SPA (:5173)
From the repo root:
yarn workspace @solelog/worker dev # Vite dev server on http://localhost:5173
Open http://localhost:5173 in any browser. db:seed creates a ready-made dev login:
worker@solelog.local / werkplaats123 (dev-only — skipped when NODE_ENV=production).
Or use the sign-up affordance on the login screen to create your own account. After signing in you
land on the Stopwatch tab.
The API base URL comes from VITE_API_URL (default http://localhost:3000).
Testing from a phone on the same LAN (no tunnel)
Vite is configured with server.host: true, so the dev server is reachable on the LAN. On a phone
connected to the same Wi-Fi:
-
Find the PC's LAN IPv4 address (e.g.
192.168.1.50). -
On the phone, open
http://<PC-LAN-IP>:5173. -
Point the SPA at the API on the LAN by setting
VITE_API_URLwhen starting the worker:VITE_API_URL=http://<PC-LAN-IP>:3000 yarn workspace @solelog/worker dev(On Windows PowerShell:
$env:VITE_API_URL='http://<PC-LAN-IP>:3000'; yarn workspace @solelog/worker dev.) -
Allow that origin on the API by setting
CORS_ORIGINSwhen you start it — no code edit:CORS_ORIGINS=http://localhost:5173,http://<PC-LAN-IP>:5173 yarn workspace @solelog/api start(PowerShell:
$env:CORS_ORIGINS='http://localhost:5173,http://<PC-LAN-IP>:5173'; yarn workspace @solelog/api start.) Otherwise the cross-origin sign-in is blocked and the SPA cannot read theset-auth-tokenheader.
No firewall punch-through, VPN, or tunnel is involved — just the LAN.
Install as a PWA
The app ships a web app manifest (public/manifest.webmanifest) and icons
(public/icon-192.png, public/icon-512.png), linked from index.html. Use the browser's
Install / Add to Home Screen action to install it. Offline support (service worker) is
intentionally out of scope for Phase 1.
Scripts
yarn workspace @solelog/worker dev # dev server (:5173, LAN-exposed)
yarn workspace @solelog/worker build # tsc -b && vite build → dist/
yarn workspace @solelog/worker preview # preview the production build
yarn workspace @solelog/worker typecheck # tsc --noEmit
yarn workspace @solelog/worker test # vitest run
Architecture (Phase 1)
- Server-authoritative timing. Start / stop / discard are API calls
(
POST /api/sessions/start,/:id/stop,/:id/discard); the live timer only displays elapsed time computed from the serverstart_time. An open session therefore survives a browser/phone restart and is recovered on load viaGET /api/sessions/active. - Shared contracts. Request/response shapes are zod schemas in
@solelog/shared, imported here for a typed client. - Auth. Sign-in reads the bearer token from the
set-auth-tokenresponse header and stores it inlocalStorage;apiFetchattachesAuthorization: Bearer <token>to every request.