mirror of
https://github.com/temetro/temetro.git
synced 2026-07-26 11:58:14 +00:00
infra/docs: Docker Hub release pipeline, versioning, README overhaul
Reference prebuilt temetro/temetro-{backend,frontend} images in docker-compose
(with a build fallback) and stop baking the frontend API URL. Add a
tag-triggered GitHub Actions release workflow that pushes both images and cuts
a GitHub Release, plus RELEASING.md, CHANGELOG.md, and a root version. Overhaul
the root and frontend READMEs (screenshot, features, prebuilt-image quickstart,
LAN access, updating).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 216 KiB |
@@ -0,0 +1,67 @@
|
||||
# Builds and publishes the temetro Docker images and cuts a GitHub Release.
|
||||
#
|
||||
# Trigger: push a semver tag, e.g.
|
||||
# git tag v0.1.0 && git push origin v0.1.0
|
||||
#
|
||||
# The frontend image bakes NO API URL — it resolves the backend from the host
|
||||
# the browser uses at runtime — so one published image works for every clinic.
|
||||
#
|
||||
# Required repository secrets (Settings → Secrets and variables → Actions):
|
||||
# DOCKERHUB_USERNAME — a Docker Hub account with push access to `temetro`
|
||||
# DOCKERHUB_TOKEN — a Docker Hub access token for that account
|
||||
# Without them the build/login step fails; the workflow is otherwise inert.
|
||||
name: release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*.*.*"
|
||||
|
||||
permissions:
|
||||
contents: write # create the GitHub Release (the update check reads this)
|
||||
|
||||
env:
|
||||
REGISTRY_NAMESPACE: temetro
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Derive version from tag
|
||||
id: meta
|
||||
run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set up Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build & push backend
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: ./backend
|
||||
push: true
|
||||
tags: |
|
||||
${{ env.REGISTRY_NAMESPACE }}/temetro-backend:${{ steps.meta.outputs.version }}
|
||||
${{ env.REGISTRY_NAMESPACE }}/temetro-backend:latest
|
||||
|
||||
- name: Build & push frontend
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: ./frontend
|
||||
push: true
|
||||
tags: |
|
||||
${{ env.REGISTRY_NAMESPACE }}/temetro-frontend:${{ steps.meta.outputs.version }}
|
||||
${{ env.REGISTRY_NAMESPACE }}/temetro-frontend:latest
|
||||
|
||||
- name: Create GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
generate_release_notes: true
|
||||
@@ -0,0 +1,32 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to temetro are recorded here. The format is loosely based on
|
||||
[Keep a Changelog](https://keepachangelog.com/), and the project follows
|
||||
[Semantic Versioning](https://semver.org/). See [RELEASING.md](./RELEASING.md)
|
||||
for how releases are cut and published.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- **Version & update awareness.** `GET /api/version` reports the running version
|
||||
and checks GitHub Releases for a newer one; Settings → **About & updates** shows
|
||||
the current/latest version, and an optional, dismissible banner appears when an
|
||||
update is available.
|
||||
- **LAN access.** The frontend now resolves the backend URL from the host the
|
||||
browser is using, so other departments can reach temetro at
|
||||
`http://<server-LAN-IP>:3000` with no rebuild. A Settings panel surfaces the
|
||||
shareable network address. `GET /api/network` reports detected LAN addresses.
|
||||
- **Prebuilt Docker images** published to Docker Hub (`temetro/temetro-backend`,
|
||||
`temetro/temetro-frontend`) via a tag-triggered GitHub Actions release workflow.
|
||||
- **Voice dictation** on the AI chat input (Web Speech API), with graceful
|
||||
fallback where the browser doesn't support it.
|
||||
|
||||
### Changed
|
||||
- `docker-compose.yml` references the published images (with a build fallback) and
|
||||
no longer bakes a fixed API URL into the frontend.
|
||||
|
||||
## [0.1.0] — 2026-06-26
|
||||
|
||||
Initial baseline: clinician AI-chat UI wired to the TypeScript/Express/Postgres
|
||||
API (Better Auth, multi-tenant clinics, org-scoped patient records), the patient
|
||||
wallet encrypted-share flow, and Dockerised local run.
|
||||
@@ -1,97 +1,141 @@
|
||||
<div align="center">
|
||||
|
||||
# temetro
|
||||
|
||||
**temetro** is 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.
|
||||
**An open-source AI middleman between clinicians and patient data.**
|
||||
|
||||
Its 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.
|
||||
Clinicians ask in plain language; temetro retrieves and organizes patient
|
||||
information as rich record cards — backed by a **patient-owned data model**.
|
||||
|
||||
> **Status.** The **backend is built** — a TypeScript + Express + Postgres API (Drizzle ORM) with
|
||||
> authentication and multi-tenant clinics via [Better Auth](https://better-auth.com), an org-scoped
|
||||
> patient records API, plus appointments, prescriptions, tasks, doctor's notes, analytics, an
|
||||
> activity audit log, real-time staff messaging (Socket.io), and notifications. The **frontend chat
|
||||
> is wired to it** (real auth, route protection, clinic switching, live patient data).
|
||||
>
|
||||
> **Still vision, not built:** the patient companion app and the blockchain-style
|
||||
> **signing / patient-owned storage / approval** flow, and the AI chat replies themselves (currently
|
||||
> mock — no LLM call yet; a `/chat` endpoint is the next planned step).
|
||||
[](./LICENSE)
|
||||
[](https://hub.docker.com/u/temetro)
|
||||
[](./CHANGELOG.md)
|
||||
|
||||
## Monorepo layout
|
||||

|
||||
|
||||
This repository is a **monorepo** containing two independent apps that live side by side (each with
|
||||
its own `package.json` / `node_modules` and its own `CLAUDE.md`):
|
||||
</div>
|
||||
|
||||
- **[`frontend/`](./frontend)** — the Next.js 16 product app (the clinician-facing AI chat UI).
|
||||
See [`frontend/CLAUDE.md`](./frontend/CLAUDE.md).
|
||||
- **[`backend/`](./backend)** — the Express 5 + Postgres API (Drizzle ORM + Better Auth).
|
||||
See [`backend/CLAUDE.md`](./backend/CLAUDE.md) and [`backend/README.md`](./backend/README.md).
|
||||
## What is temetro?
|
||||
|
||||
The marketing **landing page lives in its own separate repository** (`temetro-landing`), not here.
|
||||
temetro is a clinical tool that puts a **natural-language AI chat** between
|
||||
clinicians and patient records. Instead of clicking through tabs, a clinician
|
||||
asks for what they need and temetro returns organized **record cards** —
|
||||
vitals, labs, medications, problems, encounters — with trend sparklines and
|
||||
detail views.
|
||||
|
||||
## Run locally with Docker (recommended)
|
||||
Its distinguishing idea is a **patient-owned data model**. Instead of (or
|
||||
alongside) living only in a doctor's database, a patient's record can live 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
|
||||
wallet app. temetro can also **read existing patient databases** and present
|
||||
them in the same card UI.
|
||||
|
||||
Docker Compose builds and runs Postgres, the backend, and the frontend together. From the
|
||||
**`backend/`** directory (the Compose file builds the sibling `../frontend`):
|
||||
> "Decentralization" here means keys and 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 what lets a temporary share be deleted.
|
||||
|
||||
## Features
|
||||
|
||||
- 🗂️ **AI chat over patient records** — `/patient <file#>` (or natural language)
|
||||
renders the record as cards with sparklines and detail dialogs.
|
||||
- 🔐 **Auth & multi-tenant clinics** — email/password + staff usernames,
|
||||
organizations, and role-based access (owner / admin / doctor / reception /
|
||||
pharmacy / lab) via [Better Auth](https://better-auth.com).
|
||||
- 🩺 **Full clinical surface** — patients, appointments, prescriptions, tasks,
|
||||
doctor's notes, pharmacy inventory, analytics, an activity audit log,
|
||||
real-time staff messaging, and notifications.
|
||||
- 📲 **Patient wallet & encrypted share** — a companion app holds the record
|
||||
encrypted on-device; clinics import records over an end-to-end encrypted,
|
||||
patient-approved relay (with optional auto-deleting temporary shares).
|
||||
- 🌐 **Works across the clinic LAN** — open it on the server or from any
|
||||
department's computer at `http://<server-IP>:3000`; no per-machine config.
|
||||
- 🔄 **Self-update awareness** — the app tells admins when a newer release is
|
||||
out and how to update.
|
||||
|
||||
## Quick start (Docker)
|
||||
|
||||
The fastest path uses the **prebuilt images** published to Docker Hub. From the
|
||||
[`backend/`](./backend) directory (it holds the Compose file):
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
cp .env.example .env
|
||||
|
||||
# generate a strong auth secret and paste it into BETTER_AUTH_SECRET in .env:
|
||||
openssl rand -base64 32
|
||||
|
||||
docker compose up --build
|
||||
docker compose pull # fetch the latest published images
|
||||
docker compose up -d # start Postgres + backend + frontend
|
||||
```
|
||||
|
||||
Then open:
|
||||
No `.env` or secret setup is required — the backend generates and persists any
|
||||
missing secrets on first start. Then open:
|
||||
|
||||
- Frontend → http://localhost:3000
|
||||
- Backend → http://localhost:4000 (health check: `GET /health`)
|
||||
- Postgres → localhost:5432
|
||||
- **Frontend** → http://localhost:3000
|
||||
- **Backend** → http://localhost:4000 (health: `GET /health`)
|
||||
|
||||
Database migrations are applied automatically on backend container start.
|
||||
Prefer to **build from source** (for development)? Use `docker compose up
|
||||
--build` instead. Migrations apply automatically on backend start.
|
||||
|
||||
**Port conflict?** 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.
|
||||
> **Port conflict?** If another Postgres 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.
|
||||
|
||||
Run just the API + database with `docker compose up db backend`. To browse the database with
|
||||
Adminer: `docker compose --profile tools up adminer` → http://localhost:8080.
|
||||
### Access from other computers (hospital LAN)
|
||||
|
||||
## Run locally without Docker
|
||||
temetro figures out the backend address from the host you open it on, so other
|
||||
departments can simply visit **`http://<server-LAN-IP>:3000`** — no rebuild
|
||||
needed. Settings → **About & updates** shows the exact shareable address. The
|
||||
server's firewall must allow ports `3000`/`4000`.
|
||||
|
||||
Run each app in its own terminal (you'll need a local Postgres reachable from `DATABASE_URL`):
|
||||
### Updating
|
||||
|
||||
```bash
|
||||
docker compose pull && docker compose up -d
|
||||
```
|
||||
|
||||
The app surfaces a notification when a newer release exists. See
|
||||
[`CHANGELOG.md`](./CHANGELOG.md) for what changed and [`RELEASING.md`](./RELEASING.md)
|
||||
for how releases are built and published.
|
||||
|
||||
## Run without Docker
|
||||
|
||||
Each app runs independently (you'll need a local Postgres in `DATABASE_URL`):
|
||||
|
||||
```bash
|
||||
# backend
|
||||
cd backend
|
||||
npm install
|
||||
cp .env.example .env # point DATABASE_URL at your local Postgres
|
||||
npm run db:migrate # apply migrations
|
||||
npm run dev # http://localhost:4000
|
||||
cd backend && npm install && cp .env.example .env
|
||||
npm run db:migrate && npm run dev # http://localhost:4000
|
||||
|
||||
# frontend (second terminal)
|
||||
cd frontend
|
||||
npm install
|
||||
npm run dev # http://localhost:3000
|
||||
cd frontend && npm install && npm run dev # http://localhost:3000
|
||||
```
|
||||
|
||||
The frontend reads `NEXT_PUBLIC_API_URL` (default `http://localhost:4000`) to reach the backend.
|
||||
> With `SMTP_HOST` unset, verification / reset / invitation emails are **printed
|
||||
> to the backend console** — no email setup needed for local development.
|
||||
|
||||
> If `SMTP_HOST` is unset, verification / reset / invitation emails are **printed to the backend
|
||||
> console** instead of being sent — no email setup is needed for local development.
|
||||
## Monorepo layout
|
||||
|
||||
Two independent apps live side by side, each with its own `package.json` and
|
||||
`CLAUDE.md`:
|
||||
|
||||
- **[`frontend/`](./frontend)** — Next.js 16 product app (the AI chat UI).
|
||||
- **[`backend/`](./backend)** — Express 5 + Postgres API (Drizzle ORM + Better
|
||||
Auth). See [`backend/README.md`](./backend/README.md) for the API reference.
|
||||
|
||||
The **patient wallet app** and the **marketing landing page** live in their own
|
||||
separate repositories.
|
||||
|
||||
## Tech stack
|
||||
|
||||
- **Frontend:** Next.js 16 (App Router) · React 19 · TypeScript · Tailwind CSS v4 · i18next ·
|
||||
Socket.io client.
|
||||
- **Backend:** Node ≥ 20 · TypeScript (ESM) · Express 5 · Postgres · Drizzle ORM · Better Auth
|
||||
(email/password + organizations/RBAC) · Socket.io.
|
||||
- **Frontend:** Next.js 16 (App Router) · React 19 · TypeScript · Tailwind CSS v4
|
||||
· i18next · Socket.io client.
|
||||
- **Backend:** Node ≥ 20 · TypeScript (ESM) · Express 5 · Postgres · Drizzle ORM
|
||||
· Better Auth (email/password + organizations/RBAC) · Socket.io · AI SDK.
|
||||
|
||||
## Contributing
|
||||
|
||||
Issues and pull requests are welcome. Please keep each PR focused on one logical
|
||||
change and run the type checks (`npm run typecheck` in `backend/`, `npx tsc
|
||||
--noEmit` in `frontend/`) before opening it. Bug reports and feature requests
|
||||
have [issue templates](./.github/ISSUE_TEMPLATE).
|
||||
|
||||
## License
|
||||
|
||||
MIT.
|
||||
[MIT](./LICENSE).
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
# Releasing temetro
|
||||
|
||||
temetro is self-hosted: clinics run it with Docker and update by pulling new
|
||||
images. Each release publishes prebuilt images to Docker Hub and cuts a GitHub
|
||||
Release; the running app checks that release feed to tell admins an update is
|
||||
available. This document is the checklist for cutting one.
|
||||
|
||||
## Versioning
|
||||
|
||||
We follow [Semantic Versioning](https://semver.org/) — `MAJOR.MINOR.PATCH`,
|
||||
starting at **0.1.0**. The canonical version lives in the root
|
||||
[`package.json`](./package.json); `backend/package.json` and
|
||||
`frontend/package.json` track the same number. `GET /api/version` reports it.
|
||||
|
||||
## One-time setup
|
||||
|
||||
Add these repository secrets (GitHub → Settings → Secrets and variables →
|
||||
Actions) so the release workflow can publish:
|
||||
|
||||
| Secret | What |
|
||||
| --- | --- |
|
||||
| `DOCKERHUB_USERNAME` | Docker Hub account with push access to the `temetro` namespace |
|
||||
| `DOCKERHUB_TOKEN` | A Docker Hub access token for that account |
|
||||
|
||||
Images are published as `temetro/temetro-backend` and `temetro/temetro-frontend`.
|
||||
|
||||
## Cutting a release
|
||||
|
||||
1. **Bump the version** in `package.json`, `backend/package.json`, and
|
||||
`frontend/package.json` to the new `X.Y.Z`.
|
||||
2. **Update [`CHANGELOG.md`](./CHANGELOG.md)**: move the `Unreleased` notes under a
|
||||
new `## [X.Y.Z] — <date>` heading.
|
||||
3. **Commit** the bump (`chore(release): vX.Y.Z`).
|
||||
4. **Tag and push**:
|
||||
```bash
|
||||
git tag vX.Y.Z
|
||||
git push origin main --tags
|
||||
```
|
||||
5. The **`release` workflow** (`.github/workflows/release.yml`) then:
|
||||
- builds and pushes both images tagged `X.Y.Z` **and** `latest`, and
|
||||
- creates a **GitHub Release** with auto-generated notes.
|
||||
|
||||
That GitHub Release is what the in-app update check compares against, so update
|
||||
notifications light up for everyone on an older version once it's published.
|
||||
|
||||
## How clinics update
|
||||
|
||||
On the server machine, from the directory holding `docker-compose.yml`:
|
||||
|
||||
```bash
|
||||
docker compose pull && docker compose up -d
|
||||
```
|
||||
|
||||
This pulls the new `latest` images and restarts. Pin a specific version with
|
||||
`TEMETRO_VERSION=X.Y.Z docker compose up -d`. Updating is optional — the in-app
|
||||
banner just makes it discoverable.
|
||||
+10
-1
@@ -9,9 +9,16 @@ shape exactly.
|
||||
## Quick start (Docker)
|
||||
|
||||
```bash
|
||||
docker compose up # db + backend + frontend — no setup needed
|
||||
docker compose pull # fetch prebuilt images from Docker Hub (fast)
|
||||
docker compose up -d # db + backend + frontend — no setup needed
|
||||
```
|
||||
|
||||
`docker compose up --build` instead builds from source (for development). The
|
||||
Compose file references the published `temetro/temetro-backend` and
|
||||
`temetro/temetro-frontend` images with a build fallback, so the same file serves
|
||||
both clinics and developers. Update with `docker compose pull && docker compose
|
||||
up -d` (see [`../RELEASING.md`](../RELEASING.md)).
|
||||
|
||||
No `.env` or manual secret generation is required: on first start the backend
|
||||
generates any missing secrets (`BETTER_AUTH_SECRET`, `AI_CREDENTIALS_KEY`) and
|
||||
persists them to a Docker volume, so they stay stable across restarts. Create a
|
||||
@@ -72,6 +79,8 @@ Other org-scoped resources follow the same pattern (CRUD, role-gated):
|
||||
| Analytics | `GET /api/analytics` | — (any member) | computed clinic aggregates |
|
||||
| Conversations | `/api/conversations` | — (participant-scoped) | staff messaging; real-time over Socket.io |
|
||||
| Notifications | `/api/notifications` | — (per-recipient) | auto-generated; `read-all` + per-id read |
|
||||
| Version | `GET /api/version` | — (public) | running version + GitHub-release update check |
|
||||
| Network | `GET /api/network` | — (public) | detected LAN addresses for sharing the app |
|
||||
|
||||
Real-time messaging and live notifications are delivered over **Socket.io**, attached to the same
|
||||
HTTP server; the handshake is authenticated with the Better Auth session cookie.
|
||||
|
||||
@@ -1,15 +1,25 @@
|
||||
# Full-stack dev/run orchestration for temetro.
|
||||
#
|
||||
# docker compose up # db + backend + frontend — that's it.
|
||||
# docker compose up -d # run prebuilt images (clinics — fast)
|
||||
# docker compose up --build # build from source (developers)
|
||||
# docker compose pull && docker compose up -d # update to the latest release
|
||||
#
|
||||
# Each service has both `image:` (published on Docker Hub) and `build:` (the
|
||||
# source), so the same file serves clinics pulling releases and developers
|
||||
# building locally. `TEMETRO_VERSION` (default `latest`) pins the image tag.
|
||||
#
|
||||
# No .env or secret setup is required: the backend generates any missing
|
||||
# secrets on first start and persists them (see docker-entrypoint.sh). Create a
|
||||
# .env only if you want to override something (SMTP, a real auth secret, etc.).
|
||||
#
|
||||
# Frontend -> http://localhost:3000
|
||||
# Frontend -> http://localhost:3000 (also reachable at http://<this-host-LAN-IP>:3000)
|
||||
# Backend -> http://localhost:4000
|
||||
# Postgres -> localhost:5432
|
||||
#
|
||||
# LAN access: the frontend finds the backend from the address you open it on, so
|
||||
# other departments can just visit http://<server-LAN-IP>:3000 — no rebuild. The
|
||||
# in-app Settings → "About & updates" page shows the shareable network address.
|
||||
#
|
||||
# The frontend service builds the sibling ../frontend app. Run just the API
|
||||
# with: docker compose up db backend
|
||||
#
|
||||
@@ -36,6 +46,7 @@ services:
|
||||
retries: 10
|
||||
|
||||
backend:
|
||||
image: temetro/temetro-backend:${TEMETRO_VERSION:-latest}
|
||||
build:
|
||||
context: .
|
||||
restart: unless-stopped
|
||||
@@ -68,15 +79,16 @@ services:
|
||||
- "4000:4000"
|
||||
|
||||
frontend:
|
||||
image: temetro/temetro-frontend:${TEMETRO_VERSION:-latest}
|
||||
build:
|
||||
context: ../frontend
|
||||
args:
|
||||
NEXT_PUBLIC_API_URL: http://localhost:4000
|
||||
# Empty by default -> the app derives the backend URL from the host the
|
||||
# browser uses (localhost or a LAN IP). Set to pin a fixed/proxied URL.
|
||||
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-}
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- backend
|
||||
environment:
|
||||
NEXT_PUBLIC_API_URL: http://localhost:4000
|
||||
ports:
|
||||
- "3000:3000"
|
||||
|
||||
|
||||
+40
-23
@@ -1,36 +1,53 @@
|
||||
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
||||
# temetro frontend
|
||||
|
||||
## Getting Started
|
||||
The clinician-facing **AI chat UI** for [temetro](../) — a Next.js 16 app where
|
||||
clinicians retrieve and organize patient data in natural language, rendered as
|
||||
rich record cards. It's wired to the [`../backend`](../backend) for real auth,
|
||||
multi-tenant clinics, and live patient data.
|
||||
|
||||
First, run the development server:
|
||||

|
||||
|
||||
## Stack
|
||||
|
||||
Next.js 16 (App Router) · React 19 · TypeScript · Tailwind CSS v4 ·
|
||||
[COSS](https://coss.dev) UI components (Base UI) · i18next · Socket.io client.
|
||||
|
||||
> This app runs a **customized Next.js 16** whose conventions differ from the
|
||||
> public docs (e.g. route protection lives in `proxy.ts`, not `middleware.ts`).
|
||||
> See [`CLAUDE.md`](./CLAUDE.md) and `node_modules/next/dist/docs/` before
|
||||
> writing Next.js code.
|
||||
|
||||
## Develop
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
# or
|
||||
pnpm dev
|
||||
# or
|
||||
bun dev
|
||||
npm install
|
||||
npm run dev # Next dev server (Turbopack) on http://localhost:3000
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
Other scripts: `npm run build` (production build), `npm run start` (serve the
|
||||
build), `npm run lint`. There is no test runner — verify changes by running the
|
||||
dev server.
|
||||
|
||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||
### Talking to the backend
|
||||
|
||||
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
||||
The frontend needs the API running (see [`../backend`](../backend)). It resolves
|
||||
the backend URL **from the host you open the app on** — so it works on
|
||||
`localhost` and across the clinic LAN (`http://<server-IP>:3000`) without a
|
||||
rebuild. Set `NEXT_PUBLIC_API_URL` only to pin a fixed or reverse-proxied URL;
|
||||
see [`lib/backend-url.ts`](./lib/backend-url.ts).
|
||||
|
||||
## Learn More
|
||||
## Architecture
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
- **`app/`** — App Router. `app/(app)/` is the authenticated product shell;
|
||||
`app/(auth)/` holds the login / signup / onboarding pages.
|
||||
- **`components/chat/`** — the chat UI (input, message state, patient cards).
|
||||
- **`components/settings/`** — settings panels, including **About & updates**
|
||||
(version + LAN access).
|
||||
- **`components/ui/`** — COSS primitives (Base UI, added via the shadcn CLI).
|
||||
- **`lib/`** — API + auth clients, i18n, and data helpers.
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
See [`CLAUDE.md`](./CLAUDE.md) for the full architecture, theming, and gotchas.
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
||||
## License
|
||||
|
||||
## Deploy on Vercel
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
||||
[MIT](./LICENSE).
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
{
|
||||
"name": "temetro",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"shadcn": "^4.11.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"xcodebuildmcp": "^2.6.2"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user