Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0ec3ebc
Auto-merge main back to dev after PR #47
actions-user Jun 23, 2026
80ae737
chore(deps)(deps): bump node in the docker-major group
dependabot[bot] Jun 26, 2026
f9d4e03
chore(deps)(deps): bump the actions-minor-patch group with 2 updates
dependabot[bot] Jun 26, 2026
111d4ef
chore(deps)(deps): bump the npm-major group in /frontend with 8 updates
dependabot[bot] Jun 26, 2026
50508f2
Fix github action debconf interactive mode warning #patch
vanalmsick Jun 28, 2026
891bb75
Optimise LLM instructions to enchance code and reduce token usage #patch
vanalmsick Jun 28, 2026
347c13f
Merge pull request #52 from vanalmsick/dependabot/github_actions/dev/…
vanalmsick Jun 28, 2026
06c4894
Merge pull request #51 from vanalmsick/dependabot/docker/dev/docker-m…
vanalmsick Jun 28, 2026
ac87b02
fix(frontend): restore lint and build compatibility for eslint 10 and…
Copilot Jun 28, 2026
a1550d7
Merge pull request #53 from vanalmsick/dependabot/npm_and_yarn/fronte…
vanalmsick Jun 28, 2026
a4f9d34
Enhance dependabot PRs #patch
vanalmsick Jun 28, 2026
abf3a1e
Migrate tailwindcss to v4 #patch
vanalmsick Jun 28, 2026
ee09f6d
Enhance football-data.org match syncing; add football-data.org group …
vanalmsick Jun 28, 2026
e90362a
Fix github workflows to use correct branch #patch
vanalmsick Jun 28, 2026
8edd77d
Minor change to trigger github workflows #patch
vanalmsick Jun 28, 2026
4060400
Fixing wrong branches in github deploy workflows #patch
vanalmsick Jun 28, 2026
364bff1
Minor change to test github deploy workflow #patch
vanalmsick Jun 28, 2026
d67c595
Fixing deploy workflows #patch
vanalmsick Jun 28, 2026
e5ac4e1
Minor code change to trigger github workflows #patch
vanalmsick Jun 28, 2026
15d728b
Hard code branch names to fix github workflows #patch
vanalmsick Jun 28, 2026
5a83511
Minor code change to trigger workflow #patch
vanalmsick Jun 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 18 additions & 47 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,51 +1,22 @@
# Repository Instructions

## Stack
- **Backend** (`backend/`): FastAPI + SQLModel + Alembic + pytest
- **Frontend** (`frontend/`): React + TypeScript + Vite + Redux Toolkit + RTK Query + Tailwind CSS
- **Deployment**: Two services — `db` (PostgreSQL) and `app` (nginx + gunicorn + React, managed by supervisord)

## Core Rules
- Make narrow, focused changes. Do not refactor adjacent code, add docstrings, or introduce unused abstractions.
- Reuse existing patterns, naming, and file layout. No new dependencies without clear justification.
- After changes, run the narrowest relevant check (see Validation).

## Backend
- Domain modules: `models.py`, `crud.py`, `routers.py` per feature area.
- **API docs live in `routers.py` only.** Keep endpoint docstrings and field `description=` params up to date when changing behavior. Do not duplicate these descriptions in `crud.py`, `models.py`, or elsewhere.
- Use async DB access. Preserve `Depends(get_db)` and existing auth dependencies.
- **Auth: JWT via HttpOnly cookies** (no Authorization headers). Endpoints use `Depends(verify_access_token)` → extract `token_payload["uid"]`. Never redesign auth flow.
- **Models:** Keep `table=True` SQLModel classes separate from Pydantic request/response schemas (`XCreate`, `XRead`).
- **Model changes — cascade review:** Whenever a `models.py` file is changed (fields added/removed/renamed, types changed, relationships altered), always review the corresponding `crud.py` and `routers.py` in that same domain module and update them as needed (e.g. read/write the new fields, adjust response schemas, update `XCreate`/`XRead` schemas). Also update the frontend TypeScript types and RTK Query endpoints (see Frontend section). Do not leave any layer inconsistent with the model.
- **CRUD:** Use `selectinload` for relationships (avoid N+1). Call `db.flush()` before accessing auto-generated IDs. Encapsulate reusable filters in a `_query_x()` helper.
- **Never hand-write Alembic migrations.** Change SQLModel definitions instead — the startup workflow autogenerates and applies migrations via the volume at `/app/data/db_migrations`.
- All runtime config lives in `backend/src/config.py`. Env vars match the uppercase field name (e.g. `SECRET_KEY`, `DATABASE_URL`). Add new behavior there, not as hardcoded values.

## Frontend
- Functional components, typed Redux hooks (`useAppSelector`/`useAppDispatch`), RTK Query for all server data — never use raw `fetch()`.
- RTK Query base URL comes from `VITE_API_BASE_URL` env var (`frontend/src/api/baseApi.ts`). 401s auto-refresh via that file — do not duplicate retry logic.
- Reuse existing tag types for cache invalidation; do not invent new tag strings.
- **Type sync with backend models:** Whenever backend models or API schemas change, update the corresponding TypeScript types and RTK Query endpoint definitions in `frontend/src/` to match. Keep request/response types in sync; do not leave stale field names or missing fields in the frontend types.
- Tailwind-only styling. Respect OS light/dark mode — no custom theme toggle unless explicitly requested.
- **Icons:** Always use `lucide-react` for icons. Never write inline SVG or hardcode `<path>` elements.
- Fully responsive: iPhone 12 portrait → 4K landscape. Cap content width on wide screens.

## Deployment
- nginx serves the SPA, proxies `/api/` → `127.0.0.1:8888` (gunicorn). FastAPI requires `ROOT_PATH=/api`.
- Multi-stage Docker build: Node stage builds frontend assets; Python deps install into `/venv`; runtime image stays slim.
- All environment differences (dev / compose / prod) belong in env vars, not in application code.

## Testing
- Fixtures in `backend/tests/conftest.py`: use `client_user_1` (auth bypassed via dependency override) for fast unit tests; use `client_unauth` only when testing the actual cookie/JWT auth flow.
- Do not hand-write auth tokens or override dependencies inside individual test files — use the existing fixtures.
- **Test coverage for model changes:** After any change to `models.py` (new fields, removed fields, type changes, new relationships), verify that existing tests still pass and add or update tests to cover the changed behaviour. At minimum: assert new fields are returned in API responses, accepted in create/update requests, and validated correctly. Run `pytest backend/tests/<touched_area>/` before declaring done.

## Documentation
- **README.md env var table:** When adding or removing a config setting in `backend/src/config.py`, add or update the corresponding row in the `README.md` environment variables table.
- **FastAPI docs:** Endpoint docstrings and field `description=` params in `routers.py` are the source of truth for the interactive API docs. Keep them accurate when changing behavior. Do not add docs anywhere else.

## Validation
- Backend: FastAPI + SQLModel + Alembic + pytest
- Frontend: React + TypeScript + Vite + RTK Query + Tailwind
- Deploy: `db` (PostgreSQL) + `app` (nginx + gunicorn + React)

## Global Rules
- Keep changes narrow and in-pattern.
- Reuse existing naming/layout; avoid new dependencies unless clearly needed.
- Follow scoped instruction files; do not restate defaults from `general.instructions.md`.
- Run the smallest relevant validation and report only commands actually run.

## Scoped Files
- Backend rules: `.github/instructions/backend.instructions.md`
- Frontend rules: `.github/instructions/frontend.instructions.md`
- Test rules: `.github/instructions/tests.instructions.md`

## Validation Commands
- Backend: `pytest backend/tests/<touched_area>/`
- Frontend: `npm run lint && npm run build` from `frontend/`
- Deployment config: `docker compose config`; full check: `docker compose up --build`
- Do not claim a command was run if it was not.
- Frontend: `cd frontend && npm run lint && npm run build`
- Deploy config: `docker compose config` (or full `docker compose up --build`)
8 changes: 4 additions & 4 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ updates:
update-types:
- "major"
commit-message:
prefix: "chore(deps)"
prefix: "dependabot chore "
include: "scope"
labels:
- "dependencies"
Expand Down Expand Up @@ -60,7 +60,7 @@ updates:
update-types:
- "major"
commit-message:
prefix: "chore(deps)"
prefix: "dependabot chore "
include: "scope"
labels:
- "dependencies"
Expand Down Expand Up @@ -88,7 +88,7 @@ updates:
update-types:
- "major"
commit-message:
prefix: "chore(deps)"
prefix: "dependabot chore "
include: "scope"
labels:
- "dependencies"
Expand All @@ -115,7 +115,7 @@ updates:
update-types:
- "major"
commit-message:
prefix: "chore(deps)"
prefix: "dependabot chore "
include: "scope"
labels:
- "dependencies"
Expand Down
34 changes: 10 additions & 24 deletions .github/instructions/backend.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,13 @@ applyTo: "backend/**"

## Backend — FastAPI + SQLModel

**Structure:** One domain module = `models.py` + `crud.py` + `routers.py`. All domain areas live under `backend/src/<domain>/`.

**API docs:** Live in `routers.py` only — endpoint docstrings and field `description=` params. Do not duplicate in `crud.py` or `models.py`.

**Auth:** JWT via HttpOnly cookies. Endpoints use `Depends(verify_access_token)` → `token_payload["uid"]`. Never use Authorization headers. Never redesign the auth flow.

**DB access:** Always async. Preserve `Depends(get_db)`. Use `selectinload` for relationships (no N+1). Call `db.flush()` before reading auto-generated IDs. Encapsulate reusable filters in a `_query_x()` helper.

**Models:** Keep `table=True` SQLModel classes separate from Pydantic schemas (`XCreate`, `XRead`, `XUpdate`).

**Migrations:** Never hand-write Alembic migrations. Change SQLModel field definitions — migrations are auto-generated at startup from `/app/data/db_migrations`.

**Config:** All runtime config in `backend/src/config.py`. Settings are loaded (in priority order) from: environment variables → `data/.env.local` → `data/.env` → `data/settings.yaml`. Env var names match the uppercase field name (e.g. `SECRET_KEY`, `DATABASE_URL`). No hardcoded values in application code. When adding a new setting, also add a row to the **README.md environment variables table**.

**OpenAPI tags:** Router tag names are declared in `main.py`'s `tags_metadata`. Use only the existing tags: `auth`, `tournament`, `team`, `group`, `match`, `stage`, `predictions`, `stats`, `general`. Do not invent new tag strings.

**Model changes — cascade rule:** When any `models.py` field is added, removed, renamed, or retyped, audit every layer in order:

1. **`crud.py`** — Are any field names used that no longer exist? Are `selectinload` calls still referencing valid relationships? Are new required fields handled in create/update logic?
2. **`routers.py`** — Do `response_model` annotations match current `XRead` schemas? Are any field `description=` params stale? Do any endpoints still accept removed fields?
3. **Frontend `frontend/src/types/`** — Are any TypeScript fields stale (renamed/removed)? Are new fields present? Do optional/required markers match the backend schema?
4. **Frontend `frontend/src/api/`** — Do RTK Query request body types reference removed fields? Do response types match the updated `XRead`? Are cache tag types still valid?

Do not leave any layer inconsistent with the model.
- Domain layout MUST be `backend/src/<domain>/{models.py,crud.py,routers.py}`.
- API docs MUST live only in `routers.py` (endpoint docstrings + field `description=`).
- Auth MUST use HttpOnly cookie JWT with `Depends(verify_access_token)` and `token_payload["uid"]`; NEVER use Authorization headers or redesign auth.
- DB access MUST stay async with `Depends(get_db)`; use `selectinload`, call `db.flush()` before generated IDs, and prefer reusable `_query_x()` filters.
- Keep SQLModel `table=True` models separate from `XCreate`/`XRead`/`XUpdate` schemas.
- NEVER hand-write Alembic migrations; edit SQLModel definitions and rely on startup autogen from `/app/data/db_migrations`.
- Runtime config MUST be in `backend/src/config.py` with load order env -> `data/.env.local` -> `data/.env` -> `data/settings.yaml`; env names MUST match uppercase fields; no hardcoded runtime config.
- If config fields change, update the README env-var table.
- Router tags MUST be from `main.py` `tags_metadata` only: `auth`, `tournament`, `team`, `group`, `match`, `stage`, `predictions`, `stats`, `general`.
- Model cascade (required): when `models.py` fields/types/relationships change, update `crud.py`, `routers.py`, `frontend/src/types/`, then `frontend/src/api/`.
24 changes: 9 additions & 15 deletions .github/instructions/frontend.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,12 @@ applyTo: "frontend/**"

## Frontend — React + TypeScript + Vite + RTK Query

**Components:** Functional components only. Typed Redux hooks: `useAppSelector` / `useAppDispatch`.

**Data fetching:** RTK Query for all server data — never use raw `fetch()`. Base URL from `VITE_API_BASE_URL` env var (`frontend/src/api/baseApi.ts`). 401 auto-refresh logic lives in that file — do not duplicate it.

**RTK Query mutation pattern:** For mutations that update list or detail caches, use `onQueryStarted` + `updateQueryData` for optimistic updates (see any existing `*Api.ts` for the pattern). Use `providesTags` / `invalidatesTags` only where optimistic update is not feasible.

**Cache tags:** Reuse existing tag types for cache invalidation. Do not invent new tag strings.

**Store layout:** Redux store (`frontend/src/store/`) has two slices — `authSlice` (auth state) and `apiErrorSlice` (API error queue). Surface API errors via `addApiError` from `store/apiErrorSlice`; the `ApiErrorNotification` component handles display. Do not create custom error UI.

**Type sync with backend:** When backend models or API schemas change, update the corresponding TypeScript interfaces and RTK Query endpoint definitions in `frontend/src/` to match. Keep request/response types in sync — no stale field names or missing fields.

**Styling:** Tailwind CSS only. Respect OS light/dark mode — no custom theme toggle unless explicitly requested. Fully responsive from iPhone 12 portrait to 4K landscape; cap content width on wide screens.

**Icons:** Always use `lucide-react`. Never write inline SVG or hardcode `<path>` elements.
- Components MUST be functional and use `useAppSelector` / `useAppDispatch`.
- Server data MUST use RTK Query only; NEVER use raw `fetch`.
- Keep base URL and 401 refresh logic centralized in `frontend/src/api/baseApi.ts`.
- For list/detail cache updates, prefer optimistic `onQueryStarted` + `updateQueryData`; use `providesTags` / `invalidatesTags` when optimistic updates are not feasible.
- Reuse existing cache tag strings; do not invent new ones.
- Store conventions: use `authSlice` and `apiErrorSlice` in `frontend/src/store/`; route API errors via `addApiError`; use `ApiErrorNotification` for display.
- If backend schemas/models change, update matching types and RTK Query endpoint typings in `frontend/src/`.
- Styling MUST be Tailwind only, responsive from iPhone 12 portrait to 4K, and respect OS light/dark mode.
- Icons MUST use `lucide-react`; no inline SVG paths.
17 changes: 6 additions & 11 deletions .github/instructions/tests.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,9 @@ applyTo: "backend/tests/**"

## Testing — pytest + FastAPI TestClient

**Fixtures:** Defined in `backend/tests/conftest.py`.
- Use `client_user_1` (auth bypassed via dependency override) for unit tests.
- Use `client_unauth` only when testing the actual cookie/JWT auth flow.
- Do not hand-write auth tokens or override dependencies inside individual test files.

**Model changes:** After any `models.py` change (new/removed/renamed fields, type changes, new relationships), verify existing tests still pass and add or update tests to cover the new behaviour. At minimum assert:
- New fields are returned in API responses.
- New fields are accepted in create/update requests.
- Validation behaves correctly.

**Run scope:** `pytest backend/tests/<touched_area>/` — always run the narrowest relevant test scope.
- Use fixtures from `backend/tests/conftest.py`.
- Prefer `client_user_1` for unit tests.
- Use `client_unauth` only for real cookie/JWT auth-flow tests.
- NEVER hand-write tokens or override dependencies in individual test files.
- After any `models.py` change, verify existing tests and cover: response fields, create/update acceptance, and validation behavior.
- Run the narrowest scope: `pytest backend/tests/<touched_area>/`.
10 changes: 8 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ jobs:
working-directory: backend
steps:
- uses: actions/checkout@v6.0.3
with:
ref: ${{ github.head_ref || github.ref }}

- name: Read Python version from Dockerfile
id: versions
run: echo "python=$(grep -m1 '^FROM python:' ../Dockerfile | sed 's/FROM python:\([0-9.]*\).*/\1/')" >> $GITHUB_OUTPUT

- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@v6.2.0
with:
python-version: ${{ steps.versions.outputs.python }}
cache: pip
Expand All @@ -41,7 +43,7 @@ jobs:

- name: Publish test results
if: always()
uses: EnricoMi/publish-unit-test-result-action@v2
uses: EnricoMi/publish-unit-test-result-action@v2.23.0
with:
files: backend/test-results.xml

Expand All @@ -53,6 +55,8 @@ jobs:
working-directory: frontend
steps:
- uses: actions/checkout@v6.0.3
with:
ref: ${{ github.head_ref || github.ref }}

- name: Read Node version from Dockerfile
id: versions
Expand Down Expand Up @@ -125,6 +129,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.3
with:
ref: ${{ github.head_ref || github.ref }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/dev-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.3
with:
ref: dev

- name: Set up QEMU
uses: docker/setup-qemu-action@v4
Expand Down
3 changes: 1 addition & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,7 @@
"type": "debugpy",
"request": "launch",
"python": "${workspaceFolder}/backend/.venv/bin/python",
"program": "${workspaceFolder}/backend/src/api_football_data_org/update_tournament.py",
"args": ["2000"],
"program": "${workspaceFolder}/backend/src/api_football_data/football_data_org.py",
"cwd": "${workspaceFolder}/backend",
"env": {
"PYTHONPATH": "${workspaceFolder}/backend",
Expand Down
Loading
Loading