Files
solelog/docs/roadmap.md

208 lines
10 KiB
Markdown

# Insole Production Time Tracker — Rebuild Roadmap & Project Overview
- **Created:** 2026-06-17
- **Status:** Approved — living project doc; Phase 0 plan written (`docs/plans/phase-0-foundation.md`)
- **Type:** Greenfield rebuild of an inherited app
- **Tracked in git** under `docs/` (the project's documentation source of truth).
> **2026-06-17 — Legacy code removed.** The inherited Create/Anything export
> (`apps/mobile`, `apps/web`, `publisher/`) was deleted in a full cleanup. The repo is now
> a single-service backend (`apps/api`) plus `packages/shared`. Reference for the old code
> is preserved in `docs/reference/` and in git history. The sections below describe the
> codebase *as inherited* and the rebuild plan; treat references to the legacy apps as
> historical.
---
## 1. Context
The codebase was inherited as an export from the **Create / Anything AI** platform — a
working time-tracking app for **insole (orthotic) production**, originally built by a
friend through a chat-driven workflow. It arrived with no history, no documentation, and
no clarity on what was complete or where the backend/data lived.
Reverse-engineering established:
- It is a **two-app monorepo**: `apps/mobile` (Expo/React Native) + `apps/web`
(Next.js 16 backend on Neon Postgres). Plus `publisher/` (deploy tooling).
- It is **heavily coupled to the Create platform**: "do-not-edit" platform files,
patched dependencies, a web-sandbox iframe layer, and ~80 dependencies for what is
functionally a stopwatch.
- **Auth** is `better-auth` (email+password, argon2 hashes, bearer tokens for mobile,
cookies for web), but the core flow does not actually require login.
- **The data and accounts are not ours.** Users, password hashes, and all task/time
data live in the platform's managed Neon Postgres, bound to the friend's Create
account/organization. This repo contains only the *code* and an
`ANYTHING_PROJECT_TOKEN` — no database credentials. Nothing runs locally and no
database is reachable from this code.
Work already done this session (committed):
- Git repository initialised; baseline + doc corrections committed.
- Found and fixed `/api/logs` — it was both git-ignored (an over-broad `logs` rule) and
broken at runtime (missing its `import sql`). That route is History + Stop&Save.
- Wrote a reverse-engineered `schema.sql` (no migration shipped).
- Installed dependencies (~1.7 GiB) and confirmed Docker is available.
> The existing code is treated as a **working reference / seed**, not the foundation.
## 2. Vision
A **multi-user, backend-driven shop-floor time-tracking system**. The phone is one of
several clients, not the source of truth.
A worker, on **their own phone with their own account**, logs in → goes to a workbench →
**scans it (QR) or selects manually** → picks the activity → times the work → ends it →
it is saved → repeats. Because the **backend is the source of truth**:
- An active session lives **server-side**, so if the phone dies the worker can **end or
log the work from a computer** instead.
- There is a **manual-entry fallback** wherever something can fail.
- An **admin panel** shows live who-is-working-on-what, generates reports, and manages
users and activities.
Goals: it must **genuinely work in the workshop** (reliability, no data loss) *and* serve
as a **learning vehicle** the owner extends himself.
## 3. Decisions (resolved during brainstorming)
| # | Decision | Choice |
|---|---|---|
| 1 | Purpose | Real workshop tool **and** a learning vehicle |
| 2 | Platform relationship | **Clean break** from Create/Anything |
| 3 | Hosting | **Dockerized** stack; runs locally now, portable to any cloud later |
| 4 | Build strategy | **Greenfield rebuild**, porting only the good parts |
| 5 | Backend topology | **Dedicated backend service** (Option A): single owner of auth + DB; UIs are interchangeable clients |
| 6 | Auth | **better-auth** (don't hand-roll security for real use) |
| 7 | Database | **SQLite** (small userbase; one file, easy backup/Docker) |
| 8 | Language | **TypeScript everywhere** so types flow end-to-end |
## 4. Architecture
```
┌─────────────┐ ┌─────────────┐
│ Mobile app │ │ Admin web │ clients — UI only, no DB access
│ (Expo/RN) │ │ (React SPA) │
└──────┬──────┘ └──────┬──────┘
│ HTTP (Bearer) │ HTTP (cookie/Bearer)
└─────────┬─────────┘
┌──────────────────┐
│ Backend service │ the ONLY thing that touches auth + DB
│ better-auth + │
│ business logic │
└────────┬─────────┘
┌─────────┐
│ SQLite │ single file on a Docker volume
└─────────┘
```
**Auth flow**
- **Mobile** — native email+password screen → `POST /api/auth/sign-in/email` → backend
returns a bearer **token** → stored in Expo SecureStore → sent as
`Authorization: Bearer <token>` on every request. (Drops the current app's embedded
login WebView.)
- **Admin** — standard better-auth **session cookies**.
- **Backend** — mounts better-auth, owns all DB access, enforces roles.
## 5. Tech stack (recommended picks, approved)
| Layer | Pick | Notable alternative |
|---|---|---|
| Backend framework | **Hono** | Fastify |
| Auth | **better-auth** | — |
| DB access + migrations | **Drizzle ORM** | Kysely / Prisma |
| Database | **SQLite** | libsql/Turso (if cloud later) |
| Admin UI | **Vite + React** (SPA) | Next.js (if SSR wanted) |
| Mobile | **Expo / React Native** | — |
| Shared contracts | **`packages/shared`** (TS types + zod) | — |
## 6. Monorepo shape
```
apps/
mobile/ Expo worker app (client)
admin/ Vite + React panel (client)
api/ Hono + better-auth + Drizzle + SQLite (backend service)
packages/
shared/ TS types + zod schemas (API contracts)
docker-compose.yml + Dockerfiles
```
## 7. Data model
Server-authoritative; an open session (`end_time` null) is "active work".
- **users** — id, email, name, password hash (better-auth managed), **role** (`worker` | `admin`)
- **workbenches** — id, name, `qr_code` (seeded / hardcoded for now)
- **activities** — id, name, `insole_types[]` (subset of `Kurk` | `Berk` | `3D`)
- **sessions** — id, `user_id`, `activity_id`, `workbench_id`, `insole_type`,
`pair_count`, `start_time`, `end_time` (null = running),
`status` (`active` | `completed` | `discarded`),
`source` (`app` | `manual`), `notes`, `created_at`
(better-auth also creates its own `session`/`account`/`verification` tables; those are
distinct from the domain `sessions` table above — naming to be disambiguated in Phase 0,
e.g. `work_sessions`.)
## 8. Port vs. leave behind
**Port (the good parts):** the data model, the API route logic, the screen flows/UX, the
CSV export logic, the Dutch UI strings, and the lessons captured in the current code's
comments (Android font/freeze fixes, SecureStore quirks).
**Leave behind:** the `__create` plumbing, the web-sandbox iframe layer, analytics /
Sentry / anything-menu, the patched dependencies, and the ~60 unused libraries (ads, IAP,
maps, 3D, audio, calendar, contacts, sensors, …).
## 9. Phased roadmap
Each phase keeps the system working and is its own spec → plan → build cycle.
- **Phase 0 — Foundation.** Greenfield monorepo; dockerized Hono backend with better-auth
+ Drizzle + SQLite; `docker compose up` brings it up; health check + one auth
round-trip proven end-to-end. *Done when:* a client can sign in against the
containerised backend and the token authorises a protected call.
- **Phase 1 — Worker timing.** Activities + server-authoritative work-sessions
(open/close) + history + CSV export in the backend; mobile app rebuilt to use it.
*Done when:* a worker can pick an activity, start/stop a server-side session, and see
history; CSV exports.
- **Phase 2 — Accounts & roles.** Worker/admin roles, admin-creates-users, per-user data
scoping. *Done when:* workers see only their own sessions; an admin account exists.
- **Phase 3 — Admin panel.** The React admin app: live active-work view, reports/export,
user management, **manual entry/edit (the fallback)**. *Done when:* an admin can see
who's working now, manage users, and hand-correct a session.
- **Phase 4 — Workbench scanning.** QR at the bench → select workbench/activity, with
manual selection fallback. *Done when:* scanning a bench QR pre-fills the session.
- **Phase 5 — Polish & deploy.** Reporting niceties, dependency slimming, push the
container to a chosen cloud host.
## 10. Open questions & assumptions (confirm as we go)
- **Scanning = QR codes** on benches, read by the phone camera (no special hardware),
always with manual fallback. *(Assumption.)*
- **Start fresh, no data migration.** Assumes no live workshop data/users worth
preserving in the friend's platform instance. If there are, they must be **exported
from the friend's Create account** — unreachable from this repo.
- **Workbench↔activity mapping** is hardcoded/seeded for now; real mapping TBD with the
friend.
- **Deployment host** is deferred (Phase 5); the dockerized stack keeps options open.
- **Domain term:** "insole" / orthotic; Dutch UI (`Type zool`, `handeling`, `aantal
zolen`, etc.).
## 11. Risks
- **Greenfield is more work than evolving in place** — mitigated by porting proven logic
and keeping the old code as a running reference.
- **SQLite is single-writer / single-instance** — fine at this scale; swap to
Postgres/libsql is a config change via Drizzle/better-auth if ever needed.
- **Offline on the shop floor** — the friend hit connectivity issues. Backend-as-source-
of-truth assumes reachable network; true offline-first is explicitly out of scope for
now (revisit if it bites).
## 12. Next step
Brainstorm **Phase 0** in detail, then hand it to the writing-plans skill for an
implementation plan. No code before that plan exists.