mirror of
https://github.com/temetro/temetro.git
synced 2026-07-26 11:58:14 +00:00
7846dacd42
Bump version to 0.13.0 across root/backend/frontend, add the 0.13.0 CHANGELOG entry, and refresh stale CLAUDE.md docs (the AI chat is real and @ai-sdk/react is installed; the signing/approval flow is built). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
167 lines
10 KiB
Markdown
167 lines
10 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project
|
|
|
|
`temetro` — an **open-source** clinical tool that acts as an **AI middleman** between clinicians and
|
|
patient data. Clinicians use a natural-language AI chat to retrieve and organize patient information,
|
|
displayed as rich record cards.
|
|
|
|
The distinguishing idea is a **patient-owned data model**. Instead of (or alongside) living in a
|
|
doctor's own database, a patient's record can be stored on the **patient's own device**. When a
|
|
clinician adds or changes data, they **sign** it (blockchain-style); the change is written to the
|
|
patient's record and **cannot be modified until the patient approves it** through a companion app.
|
|
temetro can also **read existing patient databases** and present them in the same organized card UI.
|
|
|
|
This repository is a **monorepo**: the `frontend/` and `backend/` apps live side by side in one git
|
|
repository (published as `temetro`).
|
|
|
|
> **Status:** the **backend is built**. `backend/` is a TypeScript + Express + Postgres API
|
|
> (Drizzle ORM) with authentication and multi-tenant clinics via **Better Auth**, plus an
|
|
> **org-scoped patient records API**. The `frontend/` chat is **wired to it**: real auth
|
|
> (login/signup/reset/onboarding), route protection, clinic switching, and patient data fetched
|
|
> over the API — the old in-memory fixture is gone (`frontend/lib/patients.ts` now calls the backend).
|
|
>
|
|
> **Now built (thin slice):** a **patient wallet app** (`~/Desktop/temetro-app`, sibling repo — see
|
|
> "Patient wallet app" below) and an end-to-end **encrypted share / patient-approval** flow:
|
|
> clinics hold a real **Ed25519 signing key** (Settings → Signing, `backend/src/services/signing.ts`),
|
|
> and "Import from a patient app" on the Patients page relays an encrypted request to the wallet over
|
|
> the **Temetro Network** relay (see below), the patient approves on their phone, and the sealed record
|
|
> is imported (with optional **temporary share + auto-delete**). Clinic→wallet **record-update push**
|
|
> and **QR pairing** are built too. See `backend/src/routes/{signing,patients-wallet}.ts`.
|
|
>
|
|
> **Also built:** the **AI chat is real** — the frontend streams from the backend's tool-using
|
|
> agent (`POST /api/chat`), not mock replies (see `frontend/CLAUDE.md`).
|
|
>
|
|
> **Still vision, not built:** in-app record editing and cryptographic time-boxing of temporary
|
|
> shares. Email verification is wired but currently **not enforced** at sign-in (see
|
|
> `backend/CLAUDE.md`).
|
|
|
|
## Patient wallet app (sibling repo `~/Desktop/temetro-app`)
|
|
|
|
The **patient companion app** is its own git repo on the Desktop (not in this monorepo): an **Expo
|
|
SDK 56** app whose UI **must be built with HeroUI Native** (`heroui-native` + Uniwind/Tailwind) — a
|
|
hard requirement; the one exception is the native tab bar, which uses expo-router `NativeTabs`. See
|
|
its `CLAUDE.md`. It stores the patient's record **encrypted on-device**,
|
|
the patient's identity is an **Ed25519 keypair** whose public key (base58check, `tmw_…`) is their
|
|
**wallet number**, and it shares records by sealing them to a clinic's ephemeral key over the
|
|
backend relay. The crypto wire format mirrors `backend/src/lib/wallet-crypto.ts` exactly. "Decentralization"
|
|
here means keys + data live on the patient's device and the relay only ever forwards ciphertext — it
|
|
is **not** a literal blockchain (records are off-chain, which is also what lets a temporary share be
|
|
deleted). Commit/push that app inside its own repo, separately from this one.
|
|
|
|
## Temetro Network (sibling repo/folder `~/Desktop/Temetro-network`)
|
|
|
|
The **relay** that connects this backend to patient wallet apps. It is its **own git repo** on the
|
|
Desktop (folder `~/Desktop/Temetro-network`, pushed to `github.com/temetro/temetro-network`), **not**
|
|
in this monorepo — a standalone **Rust + Axum + socketioxide** service meant to run always-on (e.g.
|
|
on **Railway**). It replaces the old flaky Cloudflare quick-tunnel that used to expose the backend's
|
|
embedded `/wallet` Socket.io namespace to phones.
|
|
|
|
It is a **dumb, stateless pipe**: two Socket.io namespaces — `/wallet` for devices
|
|
(challenge/Ed25519-signature auth, room keyed by wallet number) and `/hub` for this backend
|
|
(`RELAY_TOKEN`-authenticated). Devices and the backend both connect to it; it **forwards sealed
|
|
ciphertext verbatim** and never opens bundles or touches a database. Its only crypto is verifying a
|
|
device's auth signature (mirrors `backend/src/lib/wallet-crypto.ts`). The backend connects to it as a
|
|
`/hub` client via `backend/src/services/relay-client.ts` (its `sendToWallet` is what `emitToWallet`
|
|
now calls); configure with `RELAY_URL` + `RELAY_TOKEN`. Commit/push that service inside its own repo,
|
|
separately from this one.
|
|
|
|
> **Note:** in this sandbox the `~/Desktop/Temetro-network` folder blocks directory enumeration
|
|
> (`ls`/`getcwd`/git inside it return EPERM) though plain file writes work. Develop/build/commit it
|
|
> in an accessible copy and mirror the tree in with `tar`; drive git there via
|
|
> `GIT_DIR`/`GIT_WORK_TREE` from an accessible cwd.
|
|
|
|
## Layout
|
|
|
|
`frontend/` and `backend/` were previously separate per-folder git repos; they have been **merged
|
|
into this single monorepo with full history of both preserved**.
|
|
|
|
The marketing **landing page is not in this monorepo** — it lives in the sibling Desktop folder
|
|
`../temetro/landing-page` (`/Users/khalidabdi/Desktop/temetro/landing-page`), right next to the
|
|
`../temetro/docs` site. It is **its own git repository** (a Next.js app with the marketing
|
|
`components/landing/`); edit and commit it there, separately from this repo.
|
|
|
|
- **`frontend/`** — the Next.js product app (the AI chat UI). This is where almost all current work
|
|
happens. **It has its own `CLAUDE.md`** — read `frontend/CLAUDE.md` for the stack, commands,
|
|
architecture, and gotchas.
|
|
- **`backend/`** — the TypeScript + Express + Postgres API (Drizzle ORM + Better Auth). Built and
|
|
Dockerised. **Has its own `CLAUDE.md`** (and `README.md`) — read it for the auth/schema workflow
|
|
and gotchas.
|
|
|
|
`frontend/` and `backend/` are **independent apps**, each with its own `package.json` /
|
|
`node_modules`. Run `npm` commands from inside the relevant app directory, not from this root.
|
|
|
|
## Documentation (very important)
|
|
|
|
The **project documentation lives outside this repo**, in the sibling Desktop folder
|
|
`../temetro/docs` (`/Users/khalidabdi/Desktop/temetro/docs`) — a Fumadocs (Next.js) site with
|
|
user guides (`content/docs/guides/`), an API reference (`content/docs/api/`), admin docs, and a
|
|
roadmap (`content/docs/roadmap.mdx`). It is its own git repository.
|
|
|
|
**Whenever you make a significant change here — a new feature, endpoint, page, or behavior
|
|
change — update the affected docs pages in the same work session** so the documentation stays
|
|
accurate (e.g. a new backend route needs an `content/docs/api/*.mdx` entry; a UI feature belongs
|
|
in the matching guide; status changes belong in the roadmap). Commit docs changes inside that
|
|
repo, separately from this one.
|
|
|
|
**Every release must also get a dated entry in the docs changelog**
|
|
(`content/docs/changelog.mdx`, newest first) — not just the monorepo `CHANGELOG.md`. When you cut a
|
|
version (see "Always release after pushing"), add a matching, user-facing section to that page in the
|
|
same session so `../temetro/docs` never falls behind the shipped version.
|
|
|
|
## Running the stack
|
|
|
|
From `backend/`: ensure a `.env` exists (`cp .env.example .env`, then set `BETTER_AUTH_SECRET` via
|
|
`openssl rand -base64 32`), then `docker compose up --build` → frontend :3000, backend :4000,
|
|
Postgres. Compose builds the sibling `../frontend` app, which works because they remain siblings in
|
|
the monorepo. See `backend/README.md`.
|
|
|
|
> **Port note:** if another Postgres already holds host port 5432, set `POSTGRES_PORT` (e.g. `5433`)
|
|
> in `backend/.env` — the app still talks to Postgres internally on `db:5432`; only the published
|
|
> host port changes.
|
|
|
|
For local dev without Docker, run `npm run dev` in `backend/` and `frontend/` separately (the
|
|
frontend reads `NEXT_PUBLIC_API_URL`, default `http://localhost:4000`).
|
|
|
|
## Version control (single monorepo)
|
|
|
|
This root is **one git repository** (`temetro`). The old per-folder `.git` repos are gone —
|
|
`frontend/` and `backend/` are plain subdirectories now.
|
|
|
|
**Commit after every change.** When you finish a task, commit from the repo root
|
|
(`git add -A && git commit`). Keep each commit focused on one logical change, and prefix the subject
|
|
with the area when useful (e.g. `frontend:` / `backend:`). End commit messages with the
|
|
`Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>` trailer.
|
|
|
|
`.env` files are git-ignored (only `.env.example` is tracked) — never commit real secrets.
|
|
|
|
### Always release after pushing
|
|
|
|
When you finish a unit of work and **push to `main`**, you must **also cut a release** — temetro
|
|
ships as prebuilt Docker images, so an un-released change never reaches a self-hosted clinic. After
|
|
the push:
|
|
|
|
1. **Bump the version** to the new `X.Y.Z` in **all three** `package.json` files (root,
|
|
`backend/`, `frontend/`) — they must stay in sync (`GET /api/version` reports it).
|
|
2. **Update `CHANGELOG.md`** (move `Unreleased` notes under a dated `## [X.Y.Z]` heading).
|
|
3. **Publish the images to Docker Hub** as `khalidxv/temetro-backend` and
|
|
`khalidxv/temetro-frontend`, tagged `X.Y.Z` **and** `latest`. The tag-triggered
|
|
`release` workflow does this automatically (`git tag vX.Y.Z && git push origin main --tags`).
|
|
|
|
See [`RELEASING.md`](./RELEASING.md) for the full checklist. **Never** consider work "done and
|
|
pushed" without the version bump + image publish.
|
|
|
|
## Customized Next.js (frontend)
|
|
|
|
The `frontend/` app runs a **customized Next.js 16** whose APIs/conventions differ from public docs.
|
|
Before writing Next.js code, read the relevant guide under
|
|
`frontend/node_modules/next/dist/docs/01-app/`.
|
|
|
|
## Root tooling
|
|
|
|
- `.mcp.json` registers the **shadcn MCP server**, and the root `package.json` pins the `shadcn`
|
|
CLI — used to browse/add registry components into the apps. There is nothing to build or run at
|
|
this root level.
|