Skip to content

Commit a92b5a7

Browse files
Centralize API base path and introduce /api/v1 versioning (#78)
1 parent ccc3e2c commit a92b5a7

26 files changed

+289
-100
lines changed

.envs/dev/backend.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ GITHUB_CLIENT_SECRET=your_github_oauth_app_client_secret
5151

5252
# Must match the callback URL in your GitHub App configuration
5353
# This is the backend OAuth callback endpoint that GitHub calls with the authorization code.
54-
GITHUB_REDIRECT_URL=https://127.0.0.1/auth/github/callback
54+
GITHUB_REDIRECT_URL=https://127.0.0.1/api/v1/auth/github/callback
5555

5656
# Secret used to sign OAuth "state" parameter (prevents CSRF)
5757
# Generate securely with:

.envs/dev/frontend.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
# Backend configuration
66
# -------------------------------------------------------------------
7-
VITE_API_BASE_URL=https://127.0.0.1:8000/api
7+
VITE_API_BASE_URL=https://127.0.0.1:8000/api/v1

.envs/dev_docker/backend.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ GITHUB_CLIENT_SECRET=your_github_oauth_app_client_secret
5151

5252
# Must match the callback URL in your GitHub App configuration
5353
# This is the backend OAuth callback endpoint that GitHub calls with the authorization code.
54-
GITHUB_REDIRECT_URL=https://127.0.0.1/auth/github/callback
54+
GITHUB_REDIRECT_URL=https://127.0.0.1/api/v1/auth/github/callback
5555

5656
# Secret used to sign OAuth "state" parameter (prevents CSRF)
5757
# Generate securely with:

.envs/dev_docker/frontend.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
# Backend configuration
66
# -------------------------------------------------------------------
7-
VITE_API_BASE_URL=https://127.0.0.1:8000/api
7+
VITE_API_BASE_URL=https://127.0.0.1:8000/api/v1

.envs/prod/backend.env.example

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ GITHUB_CLIENT_SECRET=your_github_oauth_app_client_secret
5151

5252
# Must match the callback URL in your GitHub App configuration
5353
# This is the backend OAuth callback endpoint that GitHub calls with the authorization code.
54-
GITHUB_REDIRECT_URL=https://127.0.0.1/auth/github/callback
54+
GITHUB_REDIRECT_URL=https://127.0.0.1/api/v1/auth/github/callback
5555
# For production, this must also point to the backend's OAuth callback endpoint
56-
# GITHUB_REDIRECT_URL=https://app.${DOMAIN}/auth/callback
56+
# GITHUB_REDIRECT_URL=https://app.${DOMAIN}/api/v1/auth/callback
5757

5858
# Secret used to sign OAuth "state" parameter (prevents CSRF)
5959
# Generate securely with:

.envs/prod/frontend.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
# Backend configuration
66
# -------------------------------------------------------------------
7-
VITE_API_BASE_URL=https://127.0.0.1:8000/api
7+
VITE_API_BASE_URL=https://127.0.0.1:8000/api/v1
Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
1-
name: CI
1+
name: Backend CI
22

33
on:
44
pull_request:
55
branches: [main]
6+
paths:
7+
- backend/**
8+
- .pre-commit-config.yaml
9+
- .github/workflows/backend-ci.yml
610
push:
711
branches: [main]
12+
paths:
13+
- backend/**
14+
- .pre-commit-config.yaml
15+
- .github/workflows/backend-ci.yml
816
workflow_dispatch: {}
917

1018
jobs:
1119
backend:
1220
name: Backend checks
1321
runs-on: ubuntu-latest
22+
timeout-minutes: 15
1423

1524
services:
1625
postgres:
@@ -60,7 +69,7 @@ jobs:
6069
# --------------------------------------------------
6170
GITHUB_CLIENT_ID: dummy
6271
GITHUB_CLIENT_SECRET: dummy
63-
GITHUB_REDIRECT_URL: http://localhost/api/auth/github/callback
72+
GITHUB_REDIRECT_URL: http://localhost/api/v1/auth/github/callback
6473
GITHUB_STATE_SECRET_KEY: dummy
6574

6675
# --------------------------------------------------
@@ -108,15 +117,13 @@ jobs:
108117
# -------------------------
109118
# Cache uv + dependencies
110119
# -------------------------
111-
- name: Cache uv
120+
- name: Cache uv cache
112121
uses: actions/cache@v4
113122
with:
114-
path: |
115-
~/.cache/uv
116-
backend/.venv
117-
key: uv-${{ runner.os }}-${{ hashFiles('backend/uv.lock') }}
123+
path: ~/.cache/uv
124+
key: uv-cache-${{ runner.os }}-${{ hashFiles('backend/uv.lock') }}
118125
restore-keys: |
119-
uv-${{ runner.os }}-
126+
uv-cache-${{ runner.os }}-
120127
121128
# -------------------------
122129
# Install backend deps
@@ -135,21 +142,24 @@ jobs:
135142
with:
136143
path: ~/.cache/pre-commit
137144
key: pre-commit-${{ runner.os }}-${{ hashFiles('.pre-commit-config.yaml') }}
138-
restore-keys: |
139-
pre-commit-${{ runner.os }}-
140145

141146
# -------------------------
142147
# Run pre-commit
143148
# -------------------------
144-
- name: Run pre-commit
145-
working-directory: backend
149+
- name: Run pre-commit (backend only)
150+
env:
151+
SKIP: frontend-eslint,frontend-prettier
146152
run: |
147-
uv run pre-commit run --all-files
153+
uv run --project backend pre-commit run --all-files
148154
149155
# -------------------------
150156
# Run pytest
151157
# -------------------------
152158
- name: Run pytest
159+
# NOTE:
160+
# Pytest (and Alembic) must run from the backend directory so relative paths
161+
# like alembic.ini and script_location resolve correctly. `--project` only
162+
# selects the virtualenv; it does not change the working directory.
153163
working-directory: backend
154164
run: |
155-
uv run pytest
165+
uv run pytest --strict-markers

.pre-commit-config.yaml

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ repos:
33
# General sanity checks
44
# ------------------------
55
- repo: https://github.com/pre-commit/pre-commit-hooks
6-
rev: v4.6.0
6+
rev: v6.0.0
77
hooks:
88
- id: trailing-whitespace
99
- id: end-of-file-fixer
@@ -17,16 +17,26 @@ repos:
1717
rev: v0.14.10
1818
hooks:
1919
- id: ruff-check
20-
args: [--fix]
21-
files: ^backend/
20+
name: ruff (lint)
21+
args:
22+
- --config=backend/pyproject.toml
23+
- --fix
24+
files: ^backend/.*\.py$
25+
2226
- id: ruff-format
23-
files: ^backend/
27+
name: ruff (format)
28+
args:
29+
- --config=backend/pyproject.toml
30+
files: ^backend/.*\.py$
31+
2432

2533
- repo: https://github.com/pre-commit/mirrors-mypy
26-
rev: v1.18.2
34+
rev: v1.19.1
2735
hooks:
2836
- id: mypy
2937
name: mypy (type checking)
38+
args:
39+
- --config-file=backend/pyproject.toml
3040
files: ^backend/.*\.py$
3141
additional_dependencies:
3242
- fastapi

README.md

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -251,19 +251,49 @@ Pre-commit runs automatically on `git commit` and will block commits if checks f
251251

252252
---
253253

254+
### ⚠️ Important: Where to run pre-commit
255+
256+
**Pre-commit must always be run from the repository root.**
257+
258+
Some hooks (notably `mypy`) reference configuration files using paths relative to the repo root (for example, `backend/pyproject.toml`). Running pre-commit from a subdirectory such as `backend/` can cause those configurations to be missed, leading to inconsistent or misleading results.
259+
260+
✅ Correct:
261+
262+
```bash
263+
pre-commit run --all-files
264+
```
265+
266+
❌ Incorrect:
267+
268+
```bash
269+
cd backend
270+
pre-commit run --all-files
271+
```
272+
273+
In CI, pre-commit is also executed from the repository root for this reason.
274+
275+
> **Note:** When using `uv`, CI runs pre-commit via
276+
> `uv run --project backend pre-commit run --all-files`.
277+
> The `--project` flag selects the backend virtual environment, but **does not change the working directory**. Pre-commit itself must still be invoked from the repo root so configuration paths resolve correctly.
278+
279+
---
280+
254281
### What pre-commit checks
255282

256283
- **Backend**
284+
257285
- Ruff linting and formatting
258-
- Python style and correctness checks
286+
- Python style and correctness checks (mypy)
287+
259288
- **Frontend**
289+
260290
- ESLint (auto-fix on staged files)
261291
- Prettier formatting (staged files only)
262292

263293
All hooks are configured in the root `.pre-commit-config.yaml`.
264294

265-
> **Note:** Git hooks run in a non-interactive shell
266-
> Make sure that Node.js tools (such as `pnpm`) are available in your system `PATH` so pre-commit hooks can execute successfully.
295+
> **Note:** Git hooks run in a non-interactive shell.
296+
> Make sure that Node.js tools (such as `pnpm`) are available in your system `PATH` so frontend hooks can execute successfully.
267297
268298
---
269299

@@ -293,7 +323,7 @@ make pre-commit-install
293323

294324
### Running pre-commit manually
295325

296-
To run all hooks against all files:
326+
To run all hooks against all files (from the repo root):
297327

298328
```bash
299329
make pre-commit-run
@@ -302,12 +332,9 @@ make pre-commit-run
302332
Or directly:
303333

304334
```bash
305-
cd backend
306335
uv run pre-commit run --all-files
307336
```
308337

309-
You can also run pre-commit from **any directory inside the repo**; it always resolves the repo root configuration.
310-
311338
---
312339

313340
### Notes & expectations

backend/app/api/health.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from fastapi import APIRouter
2+
3+
router = APIRouter(tags=["health"])
4+
5+
6+
@router.get("/health")
7+
async def health():
8+
return {"status": "ok"}

0 commit comments

Comments
 (0)