Add user-scoped POST /api/sessions/:id/pause and /resume endpoints,
mirroring the stop handler's ownership/lookup and 401/404/409 guards.
Pause sets paused_at (status stays active); resume folds the open span
into paused_seconds and clears paused_at.
Change stop to fold any open pause span into paused_seconds, then set
duration_seconds = max(0, round((end-start)/1000) - paused_seconds) so
saved duration is worked time, and clear paused_at.
Add a "Paused Duration" column to /api/export (after "Total Duration")
using formatDuration(paused_seconds).
Products affected: SoleLog backend (apps/api)
Add `role: Role` to the shared `PublicUser` contract and return it from
`GET /api/me` (defaulting to 'worker' when the session user has no role).
This lets the planned admin app gate access by role.
Also add the admin dev origin `http://localhost:5174` to the default
`WEB_ORIGINS` (env.ts) and to `.env.example`, so the admin SPA on :5174 can
reach the API at :3000 cross-origin (drives both hono/cors and better-auth
trustedOrigins).
The Instellingen tab was activity management, which Phase 2 made admin-only —
workers saw add/edit/delete controls that all 403. Replace it with an Account
tab showing the signed-in name/email (via /api/me) and an Uitloggen button
(wires the existing AuthContext signOut). Activity management belongs to the
Phase 3 admin app, so the worker client drops the Settings screen and its
now-unused activity-mutation hooks (useActivities read stays).
Products affected: SoleLog worker client (apps/worker).
db:seed now also creates a ready-made dev account via better-auth (properly
hashed), idempotent, and SKIPPED when NODE_ENV=production so no known-password
account ships to prod. Credentials: worker@solelog.local / werkplaats123.
Documented in the worker README. API tests 37/37 green; verified live (sign-in
returns a bearer token; /api/me returns the user).
Phone/LAN testing previously required editing both app.ts (cors origin) and
auth.ts (better-auth trustedOrigins). Now both read env.WEB_ORIGINS, parsed from
a comma-separated CORS_ORIGINS env var (default http://localhost:5173). To test
from a phone, set CORS_ORIGINS to include the LAN origin and restart the API — no
code edit. Documented in .env.example. Also fixed the worker README (db:migrate
creates ./data/app.db, not ./.tmp; phone step now uses CORS_ORIGINS). API tests
36/36 green; typecheck clean.
A fresh local `yarn db:migrate`/`yarn dev` failed with SQLITE_CANTOPEN (14)
because libsql does not create the parent directory for a file: URL and the
gitignored apps/api/data/ does not exist on checkout. Added ensureDbDir() and
call it before createClient in both the client and the migrator. No-op for
non-file URLs and for the Docker /data volume. Verified: fresh db:migrate now
creates data/ and all tables; tests + typecheck still green; live round-trip
(/health, sign-up, sign-in, /api/me, 401) works.
Dropped @expo/ngrok (and its 40 platform binary packages) from apps/mobile.
It was only used by `expo start --tunnel` (public dev-server tunnel) — never
imported in app code and unrelated to token storage (that is expo-secure-store).
Removed per IT request; no functional impact on the app or auth.
The guard compared import.meta.url against `file://${process.argv[1]}`, which
never matches on Windows (argv[1] is a drive-letter/backslash path), so
`yarn db:migrate` silently no-opped for local non-Docker dev. Use
pathToFileURL(process.argv[1]).href instead, which is correct on Windows and
Linux alike. Verified `yarn db:migrate` now creates all tables on Windows; the
Docker start path is unaffected.
The Task 3 schema drifted from what better-auth@1.6.18's CLI generates: it used
mode:'timestamp' (epoch seconds) instead of 'timestamp_ms', left verification
timestamps nullable, and omitted the default expressions and helper indexes.
Regenerated src/db/schema.ts from `@better-auth/cli generate` (authoritative per
the plan's version-drift rule) and rebuilt migration 0000 from scratch (no data
exists yet). Converted the index callbacks from the CLI's array form to the
object form required by drizzle-orm@0.36.4's types. Adds session_userId_idx,
account_userId_idx, verification_identifier_idx and the unixepoch defaults.
Tests (health, db, auth sign-up/sign-in, /api/me round-trip) all pass; typecheck
clean; db:generate reports no pending changes.
No migration shipped in the export. Recreates production_tasks and
time_logs (columns derived from the API queries) so the backend can run
against a fresh self-hosted Postgres.
- .gitignore: the bare 'logs' rule was matching the api/logs/ source
dir, so the route was never committed. Anchor it to /logs/ and repair
two log globs where '*' had been mangled to '_'.
- route.ts: add the missing 'import sql' — the file used sql but never
imported it, so every GET/POST /api/logs threw ReferenceError and 500'd.
Insole-production time tracker exported from the Create/Anything AI
platform. Baseline snapshot before any reverse-engineering or cleanup.
- apps/mobile: Expo Router app (iOS/Android/web), the only workspace
- publisher/: standalone OpenNext/AWS deploy tooling for the web side
- Backend (/api/tasks, /api/logs + DB) lives remotely, not in this repo