From 77fa091466d807172836c12680a760340379c2a1 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Aug 2026 12:00:44 +0000 Subject: [PATCH 1/4] Drop backend/.copier-answers.yml and correct the docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nothing reads the answers file: the sync job renders from answers hardcoded in its workflow, and this repo is consumed through GitHub's "Use this template", which copies files without any copier relationship — so there is nothing for `copier update` to update downstream. Running it against the embedded subdirectory is unsupported anyway (copier compares template tags against the recorded dev commit and refuses as a downgrade), and the recorded _src_path pointed at a private repo, which would be a dead end for anyone using a public template. This mirrors the python-template sync, which also drops the file. python-copier-template#41 is updated to match, so the first sync stays a no-op for this decision. Docs corrected accordingly: the render recipe is the source of truth for re-rendering, "Starting a project" no longer promises copier updates and points at python-copier-template for standalone services, and the Safety section now lists the Docker check alongside Backend and Contract. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011texLkDBELWbXsBf6San3M --- CLAUDE.md | 2 +- README.md | 14 +++++++----- backend/.copier-answers.yml | 12 ----------- docs/backend-sync.md | 43 ++++++++++++++++++++----------------- 4 files changed, 33 insertions(+), 38 deletions(-) delete mode 100644 backend/.copier-answers.yml diff --git a/CLAUDE.md b/CLAUDE.md index 5c7adf7..cd2ef5e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,7 +6,7 @@ Fullstack template: React frontend (`frontend/`) + FastAPI backend (`backend/`). - `backend/` is a **rendered mirror** of [python-copier-template](https://github.com/Komorebi-AI/python-copier-template) - (answers in `backend/.copier-answers.yml`). Do NOT edit files under + (render recipe in `docs/backend-sync.md`). Do NOT edit files under `backend/` in this repo: a sync job re-renders the template and replaces the whole directory, wiping local changes. Backend changes belong in python-copier-template. Exceptions applied by the sync itself: rendered diff --git a/README.md b/README.md index 342407f..a9b2d3d 100644 --- a/README.md +++ b/README.md @@ -76,9 +76,13 @@ endpoints, since the compose healthcheck and CI smoke tests rely on it. ## Starting a project from this template 1. Use GitHub's **"Use this template"** (or clone and re-init git). -2. Rename things: `frontend/package.json` name, `backend` answers if you re-render. +2. Rename things: `frontend/package.json` name, `backend/Makefile` image name. 3. Replace the example page and endpoints with your app. Keep the patterns: - typed API wrappers, useQuery/useMutation, the `/api` prefix convention. -4. The backend keeps its link to python-copier-template via - `backend/.copier-answers.yml` — run `copier update` inside `backend/` to pull - future template improvements into your (by then customized) backend. + typed API wrappers, useQuery/useMutation, the `/api` prefix convention, and the + `/health` endpoint the compose healthcheck and CI rely on. + +Your project is a plain copy from that point on — `backend/` is only a bot-owned mirror +in _this_ repo, so you own and edit it freely like any other file. To start a +**standalone** Python service instead, render +[python-copier-template](https://github.com/Komorebi-AI/python-copier-template) +directly; those projects keep a live copier link and can `copier update`. diff --git a/backend/.copier-answers.yml b/backend/.copier-answers.yml deleted file mode 100644 index 78a0c47..0000000 --- a/backend/.copier-answers.yml +++ /dev/null @@ -1,12 +0,0 @@ -# Changes here will be overwritten by Copier -_commit: d788f09 -_src_path: https://github.com/Komorebi-AI/python-copier-template.git -github_repo: react-template -include_api: true -include_cli: false -include_docker: true -package_name: app -project_description: FastAPI backend for react-template -project_name: React Template Backend -project_type: application -python_version: '3.14' diff --git a/docs/backend-sync.md b/docs/backend-sync.md index ac973ce..3d3a42d 100644 --- a/docs/backend-sync.md +++ b/docs/backend-sync.md @@ -9,8 +9,8 @@ edited in this repo. ## Deterministic render recipe -The sync renders with the answers recorded in `backend/.copier-answers.yml` and applies -three post-render adjustments: +The sync renders with the answers hardcoded in the workflow (mirrored in the render +recipe below) and applies three post-render adjustments: 1. **Drop the rendered `.github/`** — workflows are repo-owned here (`.github/workflows/backend.yml` + `contract.yml`), because the rendered ones assume @@ -18,20 +18,22 @@ three post-render adjustments: 2. **Set `[tool.setuptools_scm] root = ".."`** in `backend/pyproject.toml` — the backend's pyproject is not at the git root, so the version must be derived from this repo's metadata. (Cleaner long-term fix: an `scm_root` question in the template.) -3. **Point `_src_path`** in `.copier-answers.yml` at the template's GitHub URL and keep - the file — projects created from react-fastapi-template use it to run `copier update` on - their own backends. +3. **Drop `.copier-answers.yml`**, same as the python-template sync. Nothing reads it: + the sync renders from hardcoded answers, and this repo is consumed via GitHub's "Use + this template" — which copies files without any copier relationship, so there is + nothing for `copier update` to update. (Running it against the embedded + subdirectory is unsupported anyway.) To re-render deliberately, use the recipe below. Then `uv lock` (with `SETUPTOOLS_SCM_PRETEND_VERSION`) and `uvx sync-with-uv`, exactly like the python-template sync. ## Known temporary deviations (pending upstream fixes) -> **Status**: both fixes (plus the sync workflow below and a rendered `docker.yml` -> smoke-test workflow) are in -> [python-copier-template#41](https://github.com/Komorebi-AI/python-copier-template/pull/41). -> Merge order matters: land **this repo's PR first**, then #41 — its first sync run -> renders `backend/` against this repo's `main`, which must already contain it. +> **Status**: both fixes — plus the `/health` endpoint, the sync workflow below and a +> rendered `docker.yml` smoke-test workflow — are in +> [python-copier-template#41](https://github.com/Komorebi-AI/python-copier-template/pull/41), +> pending merge. Its first sync run normalizes the patches below away; nothing else in +> `backend/` changes (verified by diffing the render against this repo). Two bugs were found in the rendered output while building this repo; both are patched locally in `backend/` with `TEMPORARY` comments and must be fixed in @@ -49,10 +51,11 @@ local patches and break this repo): ## Safety -Auto-merge relies on branch protection requiring the **Backend** and **Contract** -checks. The Contract workflow boots the rendered backend and exercises the endpoints -the frontend depends on, so a template change that breaks the API contract produces a -red PR instead of a silent break. +Auto-merge relies on branch protection requiring the **Backend**, **Contract** and +**Docker** checks. Contract boots the rendered backend and exercises the endpoints the +frontend depends on; Docker builds both images and checks the same contract through +nginx. So a template change that breaks the API contract — or produces an image that +builds but cannot start — produces a red PR instead of a silent break. ## Workflow for python-copier-template @@ -99,17 +102,17 @@ jobs: . /tmp/rendered # backend/ is a subdirectory of react-fastapi-template, not a repo root: its - # workflows are owned by react-fastapi-template (rendered ones assume repo root) - # and its version must derive from react-fastapi-template's git metadata. - # Keep .copier-answers.yml (pointed at this repo's URL) so projects - # created from react-fastapi-template can `copier update` their backends. + # workflows are owned by react-fastapi-template (rendered ones assume repo + # root) and its version must derive from that repo's git metadata. + # .copier-answers.yml is dropped like in the python-template sync: this job + # renders from hardcoded answers, and projects created from the template + # (via "Use this template") have no copier relationship to update. - name: Adjust render for subdirectory embedding run: | rm -rf /tmp/rendered/.github + rm -f /tmp/rendered/.copier-answers.yml sed -i 's|^\[tool.setuptools_scm\]$|[tool.setuptools_scm]\n# Backend lives in a subdirectory of the react-fastapi-template repo; version comes\n# from the repo root git metadata (applied by the template sync job)\nroot = ".."|' \ /tmp/rendered/pyproject.toml - sed -i 's|^_src_path:.*|_src_path: https://github.com/Komorebi-AI/python-copier-template.git|' \ - /tmp/rendered/.copier-answers.yml - name: Generate lock file run: uv lock From 325e7de405e2c677ba2a4d3a2c3161d0b251b308 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Aug 2026 12:31:17 +0000 Subject: [PATCH 2/4] Keep the README user-facing: drop the sync/generation details People starting a project from this template do not need to know how backend/ is produced. Removed the ownership-model paragraph, the python-copier-template links and the copier-update guidance; the structure block now just describes both halves. Backend-only projects are pointed at python-template instead. The bot-ownership rules stay where maintainers (and Claude) look for them: docs/backend-sync.md and CLAUDE.md, with a one-line pointer at the bottom of the README so nobody hand-edits backend/ by accident. Also refreshed: the Checks section now lists the Docker workflow, and step 2 mentions the pyproject fields to rename. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011texLkDBELWbXsBf6San3M --- README.md | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index a9b2d3d..6163abb 100644 --- a/README.md +++ b/README.md @@ -2,22 +2,20 @@ Fullstack template at Komorebi AI: a **React frontend** (`frontend/`) paired with a **FastAPI backend** (`backend/`). Use it as the starting point for technical tests, -experiments and app frontends — delete `backend/` if you only need the frontend. +experiments and apps. + +Need only one half? Delete `frontend/` or `backend/` — or start from +[python-template](https://github.com/Komorebi-AI/python-template) for a backend-only +project. ## Structure ``` frontend/ React + TypeScript + Vite + MUI + TanStack Query → frontend/README.md -backend/ FastAPI example, rendered from python-copier-template (do not edit here!) -compose.yaml, Makefile, .github/ → repo-owned glue +backend/ FastAPI + uv, ruff, ty, pytest → backend/README.md +compose.yaml, Makefile, .github/ full-stack glue ``` -**Ownership model**: `backend/` is a rendered mirror of -[python-copier-template](https://github.com/Komorebi-AI/python-copier-template) and is -replaced wholesale by an automated sync — backend changes belong in that template, not -here. See [docs/backend-sync.md](docs/backend-sync.md). Everything else is owned and -edited in this repo. - ## Quickstart Requirements: [Node 24](https://nodejs.org/) (see `frontend/.nvmrc`) and @@ -53,10 +51,10 @@ make test # frontend Vitest + backend pytest make lint # ESLint/Prettier + ruff/ty ``` -CI runs three path-filtered workflows: **Frontend** (lint, format, test, build), -**Backend** (ruff, ty, pytest) and **Contract** — the latter boots the real backend and -exercises the endpoints the frontend uses, so a backend sync that breaks the API -contract fails visibly. +CI runs path-filtered workflows: **Frontend** (lint, format, test, build), **Backend** +(ruff, ty, pytest), **Contract** — boots the real backend and exercises the endpoints +the frontend calls, so frontend/backend drift fails visibly — and **Docker** (builds +both images and checks the same contract through nginx). ## API contract @@ -76,13 +74,13 @@ endpoints, since the compose healthcheck and CI smoke tests rely on it. ## Starting a project from this template 1. Use GitHub's **"Use this template"** (or clone and re-init git). -2. Rename things: `frontend/package.json` name, `backend/Makefile` image name. +2. Rename things: `frontend/package.json` name, `backend/Makefile` image name, + `backend/pyproject.toml` name and description. 3. Replace the example page and endpoints with your app. Keep the patterns: typed API wrappers, useQuery/useMutation, the `/api` prefix convention, and the `/health` endpoint the compose healthcheck and CI rely on. -Your project is a plain copy from that point on — `backend/` is only a bot-owned mirror -in _this_ repo, so you own and edit it freely like any other file. To start a -**standalone** Python service instead, render -[python-copier-template](https://github.com/Komorebi-AI/python-copier-template) -directly; those projects keep a live copier link and can `copier update`. +--- + +Maintaining this template itself: `backend/` is kept up to date automatically — read +[docs/backend-sync.md](docs/backend-sync.md) before editing anything under it. From cf66889bc23d41aa3b8f603781815d3ca27af2a0 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Aug 2026 12:36:32 +0000 Subject: [PATCH 3/4] Remove docs/backend-sync.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sync mechanism is python-copier-template's, and it now documents both render targets in its own README, next to the workflows. Keeping a copy here duplicated it (drift risk) and shipped it into every project created from this template, where it describes a sync that never runs. What this repo still needs — do not hand-edit backend/ — stays in CLAUDE.md, together with the two subdirectory adjustments worth knowing and a note telling downstream projects to delete the section. README keeps its one-line pointer, now self-contained. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011texLkDBELWbXsBf6San3M --- .github/workflows/backend.yml | 6 +- CLAUDE.md | 18 ++-- README.md | 4 +- docs/backend-sync.md | 175 ---------------------------------- 4 files changed, 15 insertions(+), 188 deletions(-) delete mode 100644 docs/backend-sync.md diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index 571fda5..af74f52 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -1,6 +1,6 @@ -# Checks for backend/, which is rendered from python-copier-template -# (see docs/backend-sync.md). Kept as a thin repo-owned workflow because the -# rendered workflows assume the project sits at the repository root. +# Checks for backend/, which is rendered from python-copier-template (see +# CLAUDE.md). Kept as a thin repo-owned workflow because the rendered workflows +# assume the project sits at the repository root. name: Backend on: diff --git a/CLAUDE.md b/CLAUDE.md index cd2ef5e..0b414ea 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -5,14 +5,16 @@ Fullstack template: React frontend (`frontend/`) + FastAPI backend (`backend/`). ## Ownership model — IMPORTANT - `backend/` is a **rendered mirror** of - [python-copier-template](https://github.com/Komorebi-AI/python-copier-template) - (render recipe in `docs/backend-sync.md`). Do NOT edit files under - `backend/` in this repo: a sync job re-renders the template and replaces the - whole directory, wiping local changes. Backend changes belong in - python-copier-template. Exceptions applied by the sync itself: rendered - `.github/` is dropped, and `[tool.setuptools_scm] root = ".."` is set in - `backend/pyproject.toml`. Files marked `TEMPORARY` carry patches for known - upstream bugs. See `docs/backend-sync.md`. + [python-copier-template](https://github.com/Komorebi-AI/python-copier-template). + Do NOT edit files under `backend/` in this repo: a sync job there re-renders + the template and replaces the whole directory, wiping local changes. Backend + changes belong in python-copier-template, which documents the sync (it drops + the rendered `.github/`, since workflows are repo-owned here, and sets + `[tool.setuptools_scm] root = ".."` because the pyproject is not at the git + root). Files marked `TEMPORARY` carry patches for known upstream bugs. +- Note for projects created from this template: the rule above applies to the + template repo only. Your `backend/` is a plain copy you own — delete this + section. - `frontend/` and everything at the repo root are owned by this repo and edited normally. diff --git a/README.md b/README.md index 6163abb..f042b82 100644 --- a/README.md +++ b/README.md @@ -82,5 +82,5 @@ endpoints, since the compose healthcheck and CI smoke tests rely on it. --- -Maintaining this template itself: `backend/` is kept up to date automatically — read -[docs/backend-sync.md](docs/backend-sync.md) before editing anything under it. +Maintaining this template itself: `backend/` is regenerated automatically, so changes +under it are overwritten — see `CLAUDE.md` before editing anything there. diff --git a/docs/backend-sync.md b/docs/backend-sync.md deleted file mode 100644 index 3d3a42d..0000000 --- a/docs/backend-sync.md +++ /dev/null @@ -1,175 +0,0 @@ -# Backend sync from python-copier-template - -`backend/` is not hand-written: it is rendered from -[python-copier-template](https://github.com/Komorebi-AI/python-copier-template), the -same way [python-template](https://github.com/Komorebi-AI/python-template) is. A CI job -in python-copier-template re-renders it and opens a PR here whenever the template -changes, replacing `backend/` **wholesale** — which is why backend files must never be -edited in this repo. - -## Deterministic render recipe - -The sync renders with the answers hardcoded in the workflow (mirrored in the render -recipe below) and applies three post-render adjustments: - -1. **Drop the rendered `.github/`** — workflows are repo-owned here - (`.github/workflows/backend.yml` + `contract.yml`), because the rendered ones assume - the project sits at the repository root. -2. **Set `[tool.setuptools_scm] root = ".."`** in `backend/pyproject.toml` — the - backend's pyproject is not at the git root, so the version must be derived from this - repo's metadata. (Cleaner long-term fix: an `scm_root` question in the template.) -3. **Drop `.copier-answers.yml`**, same as the python-template sync. Nothing reads it: - the sync renders from hardcoded answers, and this repo is consumed via GitHub's "Use - this template" — which copies files without any copier relationship, so there is - nothing for `copier update` to update. (Running it against the embedded - subdirectory is unsupported anyway.) To re-render deliberately, use the recipe below. - -Then `uv lock` (with `SETUPTOOLS_SCM_PRETEND_VERSION`) and `uvx sync-with-uv`, exactly -like the python-template sync. - -## Known temporary deviations (pending upstream fixes) - -> **Status**: both fixes — plus the `/health` endpoint, the sync workflow below and a -> rendered `docker.yml` smoke-test workflow — are in -> [python-copier-template#41](https://github.com/Komorebi-AI/python-copier-template/pull/41), -> pending merge. Its first sync run normalizes the patches below away; nothing else in -> `backend/` changes (verified by diffing the render against this repo). - -Two bugs were found in the rendered output while building this repo; both are patched -locally in `backend/` with `TEMPORARY` comments and must be fixed in -python-copier-template **before** the sync workflow is enabled (a sync would revert the -local patches and break this repo): - -1. **Dockerfile base images**: the pinned `uv:-python3.14-bookworm-slim` tag does - not exist upstream (Python 3.14 uv images ship on trixie). Patched to - `...-trixie-slim` (builder and runtime). Affects python-template as well — its - Docker image cannot build. -2. **PyYAML missing**: uvicorn needs PyYAML to load `log_conf.yaml` via `--log-config`, - but it is not in the rendered dependencies — the Docker CMD and the - `python app/api.py` dev entrypoint both crash. Patched by adding `pyyaml` to - dependencies (plus the deptry DEP002 ignore). Affects python-template as well. - -## Safety - -Auto-merge relies on branch protection requiring the **Backend**, **Contract** and -**Docker** checks. Contract boots the rendered backend and exercises the endpoints the -frontend depends on; Docker builds both images and checks the same contract through -nginx. So a template change that breaks the API contract — or produces an image that -builds but cannot start — produces a red PR instead of a silent break. - -## Workflow for python-copier-template - -Ready to drop in as `.github/workflows/sync-react-fastapi-template.yml` (mirrors the existing -`sync-template.yml`; requires the same `GH_TOKEN` secret): - -```yaml -name: sync-react-fastapi-template - -on: - push: - branches: [main] - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }} - cancel-in-progress: true - -jobs: - sync: - runs-on: ubuntu-latest - steps: - - name: Checkout copier template - uses: actions/checkout@v6 - - - name: Install uv - uses: astral-sh/setup-uv@v7 - - - name: Install copier - run: uv tool install copier - - - name: Render template - run: | - copier copy --defaults --vcs-ref=HEAD \ - --data project_name="React Template Backend" \ - --data project_description="FastAPI backend for react-fastapi-template" \ - --data package_name="app" \ - --data github_repo="react-fastapi-template" \ - --data project_type="application" \ - --data python_version="3.14" \ - --data include_api=true \ - --data include_cli=false \ - --data include_docker=true \ - . /tmp/rendered - - # backend/ is a subdirectory of react-fastapi-template, not a repo root: its - # workflows are owned by react-fastapi-template (rendered ones assume repo - # root) and its version must derive from that repo's git metadata. - # .copier-answers.yml is dropped like in the python-template sync: this job - # renders from hardcoded answers, and projects created from the template - # (via "Use this template") have no copier relationship to update. - - name: Adjust render for subdirectory embedding - run: | - rm -rf /tmp/rendered/.github - rm -f /tmp/rendered/.copier-answers.yml - sed -i 's|^\[tool.setuptools_scm\]$|[tool.setuptools_scm]\n# Backend lives in a subdirectory of the react-fastapi-template repo; version comes\n# from the repo root git metadata (applied by the template sync job)\nroot = ".."|' \ - /tmp/rendered/pyproject.toml - - - name: Generate lock file - run: uv lock - working-directory: /tmp/rendered - env: - SETUPTOOLS_SCM_PRETEND_VERSION: "0.0.0" - - - name: Sync pre-commit hook revs with uv.lock - run: uvx sync-with-uv - working-directory: /tmp/rendered - - - name: Checkout react-fastapi-template - uses: actions/checkout@v6 - with: - repository: Komorebi-AI/react-fastapi-template - token: ${{ secrets.GH_TOKEN }} - path: react-fastapi-template - - - name: Replace backend/ - run: | - rm -rf react-fastapi-template/backend - mkdir react-fastapi-template/backend - cp -r /tmp/rendered/. react-fastapi-template/backend/ - - - name: Check for changes - id: changes - working-directory: react-fastapi-template - run: | - git add -A - if git diff --cached --quiet; then - echo "has_changes=false" >> "$GITHUB_OUTPUT" - else - echo "has_changes=true" >> "$GITHUB_OUTPUT" - fi - - - name: Create pull request - if: steps.changes.outputs.has_changes == 'true' - working-directory: react-fastapi-template - env: - GH_TOKEN: ${{ secrets.GH_TOKEN }} - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - - BRANCH="sync/copier-template-backend" - git checkout -B "$BRANCH" - git commit -m "sync: update backend/ from python-copier-template" - - git push -u origin "$BRANCH" --force - - if ! gh pr list --head "$BRANCH" --json number --jq '.[0].number' | grep -q .; then - gh pr create \ - --title "sync: update backend/ from python-copier-template" \ - --body "Automated sync of backend/ from [python-copier-template](https://github.com/Komorebi-AI/python-copier-template)." - fi - - # Requires react-fastapi-template branch protection with the Backend and - # Contract checks required, and "Allow auto-merge" enabled. - gh pr merge "$BRANCH" --auto --squash -``` From c259020727fa7faab54b522e705bb616df8265f1 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Aug 2026 12:41:12 +0000 Subject: [PATCH 4/4] Trim CLAUDE.md to what a project built from this template needs Drop the ownership-model section entirely: the sync only concerns the template repo, and every project created from this template inherits this file, where those rules are false. What is left is commands for both halves and the two conventions worth preserving (the /api prefix contract and the /health endpoint CI depends on). Pointers that referenced it are now self-contained. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011texLkDBELWbXsBf6San3M --- .github/workflows/backend.yml | 5 ++--- CLAUDE.md | 37 ++++++++++------------------------- README.md | 2 +- 3 files changed, 13 insertions(+), 31 deletions(-) diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index af74f52..f2e0e48 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -1,6 +1,5 @@ -# Checks for backend/, which is rendered from python-copier-template (see -# CLAUDE.md). Kept as a thin repo-owned workflow because the rendered workflows -# assume the project sits at the repository root. +# Checks for backend/. Kept as a repo-owned workflow because the ones rendered +# from python-copier-template assume the project sits at the repository root. name: Backend on: diff --git a/CLAUDE.md b/CLAUDE.md index 0b414ea..b5a88ed 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,35 +1,18 @@ # CLAUDE.md -Fullstack template: React frontend (`frontend/`) + FastAPI backend (`backend/`). - -## Ownership model — IMPORTANT - -- `backend/` is a **rendered mirror** of - [python-copier-template](https://github.com/Komorebi-AI/python-copier-template). - Do NOT edit files under `backend/` in this repo: a sync job there re-renders - the template and replaces the whole directory, wiping local changes. Backend - changes belong in python-copier-template, which documents the sync (it drops - the rendered `.github/`, since workflows are repo-owned here, and sets - `[tool.setuptools_scm] root = ".."` because the pyproject is not at the git - root). Files marked `TEMPORARY` carry patches for known upstream bugs. -- Note for projects created from this template: the rule above applies to the - template repo only. Your `backend/` is a plain copy you own — delete this - section. -- `frontend/` and everything at the repo root are owned by this repo and - edited normally. +React frontend (`frontend/`) + FastAPI backend (`backend/`). ## Commands -- Frontend (`cd frontend`): npm. `npm run dev` (port 5173), `npm test`, +- Frontend (`cd frontend`): npm. `npm run dev` (5173), `npm test`, `npm run lint`, `npm run build`. -- Backend (`cd backend`): uv, never pip. `uv run python app/api.py` (port - 7000), `uv run pytest`, `uv run ruff check .`, `uv run ty check app tests`. -- Full stack: `docker compose up --build` (port 8080). Root `Makefile` has - delegating targets. +- Backend (`cd backend`): uv, never pip. `uv run python app/api.py` (7000), + `uv run pytest`, `uv run ruff check .`, `uv run ty check app tests`. +- Both: root `Makefile` delegates (`make test`, `make lint`, `make up`). -## API contract +## Conventions -The frontend example calls `GET /api/` (version) and `POST /api/predict`; -both proxies (Vite dev, nginx) strip the `/api` prefix before the backend. -If a template sync changes `backend/app/api.py`, update -`frontend/src/api/backend.ts` and its tests to match. +- The frontend calls `/api/*`; both proxies (Vite dev, nginx) strip the prefix + before the backend. Keep endpoint wrappers in `frontend/src/api/`, typed and + matching `backend/app/api.py`. +- Keep `GET /health`: the compose healthcheck and CI depend on it. diff --git a/README.md b/README.md index f042b82..7569e59 100644 --- a/README.md +++ b/README.md @@ -83,4 +83,4 @@ endpoints, since the compose healthcheck and CI smoke tests rely on it. --- Maintaining this template itself: `backend/` is regenerated automatically, so changes -under it are overwritten — see `CLAUDE.md` before editing anything there. +under it are overwritten — make them in our Python template instead.