.PHONY: dev api web sandbox migrate seed ingest test lint build deploy stage PY=backend/.venv/bin/python COURSE?=imm1033 PATH_IN?=content/$(COURSE) dev: ## docker compose (api :8190, web :5173, sandbox :8191) docker compose up --build api: ## API locale (venv) cd backend && .venv/bin/python -m uvicorn app.main:app --reload --port 8190 sandbox: ## sandbox-runner local cd sandbox-runner && .venv/bin/python -m uvicorn server:app --port 8191 --reload web: ## frontend Vite avec proxy /api cd frontend && npm run dev setup: ## venvs + npm install cd backend && uv venv --python 3.12 .venv && uv pip install --python .venv/bin/python -e ".[dev]" cd sandbox-runner && uv venv --python 3.12 .venv && uv pip install --python .venv/bin/python -r requirements.txt cd frontend && npm install migrate: ## crée/actualise le schéma (create_all ; Alembic à venir) cd backend && .venv/bin/python -c "import asyncio; from app.db import init_db; asyncio.run(init_db())" seed: ## cours IMM1003/IMM1033 (+ PROF=email pour un compte professeur) cd backend && .venv/bin/python -m scripts.seed $(if $(PROF),--professor $(PROF),) ingest: ## make ingest COURSE=imm1033 SITE= | PATH_IN= cd backend && .venv/bin/python -m scripts.ingest --course $(COURSE) $(if $(SITE),--site $(SITE),) $(if $(wildcard ../$(PATH_IN)),--path ../$(PATH_IN),) test: ## tests backend + frontend cd backend && .venv/bin/pytest -q cd frontend && npx tsc --noEmit lint: cd backend && .venv/bin/ruff check app scripts tests cd frontend && npx tsc --noEmit build: ## build frontend (dist servi par l'API) cd frontend && npm run build stage: build ## laptop → passerelle M1M32 ~/Desktop/cluster-skill/mld stage $(CURDIR) uqo-chat deploy: stage ## déploiement mld (nœud choisi par score ; NODE=X pour forcer) ~/Desktop/cluster-skill/mld deploy uqo-chat $(if $(NODE),--node $(NODE),)