Files
Classeo/Makefile
Mathias STRASSER f19d0ae3ef feat: Gestion des périodes scolaires
L'administration d'un établissement nécessite de découper l'année
scolaire en trimestres ou semestres avant de pouvoir saisir les notes
et générer les bulletins.

Ce module permet de configurer les périodes par année scolaire
(current/previous/next résolus en UUID v5 déterministes), de modifier
les dates individuelles avec validation anti-chevauchement, et de
consulter la période en cours avec le décompte des jours restants.

Les dates par défaut de février s'adaptent aux années bissextiles.
Le repository utilise UPSERT transactionnel pour garantir l'intégrité
lors du changement de mode (trimestres ↔ semestres). Les domain events
de Subject sont étendus pour couvrir toutes les mutations (code,
couleur, description) en plus du renommage.
2026-02-06 14:27:55 +01:00

295 lines
13 KiB
Makefile

.DEFAULT_GOAL := help
# =============================================================================
# Docker
# =============================================================================
# Fichiers compose - ajouter monitoring si MONITORING=1
COMPOSE_FILES := -f compose.yaml
ifdef MONITORING
COMPOSE_FILES += -f compose.monitoring.yaml
endif
.PHONY: up
up: ## Lancer les services (ajouter MONITORING=1 pour inclure observabilité)
docker compose $(COMPOSE_FILES) up -d
.PHONY: up-full
up-full: ## Lancer TOUS les services (app + monitoring)
docker compose -f compose.yaml -f compose.monitoring.yaml up -d
.PHONY: down
down: ## Arrêter tous les services (app + monitoring)
docker compose -f compose.yaml -f compose.monitoring.yaml down --remove-orphans
.PHONY: restart
restart: ## Redémarrer les services
docker compose $(COMPOSE_FILES) down
docker compose $(COMPOSE_FILES) up -d
.PHONY: rebuild
rebuild: ## Reconstruire et relancer les services (sans cache)
docker compose $(COMPOSE_FILES) down
docker compose $(COMPOSE_FILES) build --no-cache
docker compose $(COMPOSE_FILES) up -d
.PHONY: build
build: ## Reconstruire les images Docker (sans cache)
docker compose $(COMPOSE_FILES) build --no-cache
.PHONY: logs
logs: ## Voir les logs de tous les services (Ctrl+C pour quitter)
docker compose $(COMPOSE_FILES) logs -f
.PHONY: ps
ps: ## Afficher le statut des services
docker compose $(COMPOSE_FILES) ps
.PHONY: clean
clean: ## Supprimer volumes et images locales
docker compose -f compose.yaml -f compose.monitoring.yaml down -v --rmi local
# =============================================================================
# Monitoring
# =============================================================================
.PHONY: monitoring-up
monitoring-up: ## Lancer uniquement les services de monitoring
docker compose -f compose.monitoring.yaml up -d
.PHONY: monitoring-down
monitoring-down: ## Arrêter les services de monitoring
docker compose -f compose.monitoring.yaml down
.PHONY: monitoring-logs
monitoring-logs: ## Voir les logs du monitoring
docker compose -f compose.monitoring.yaml logs -f
.PHONY: grafana
grafana: ## Ouvrir Grafana dans le navigateur (http://localhost:3001)
@echo "Grafana: http://localhost:3001 (admin/admin)"
@command -v xdg-open >/dev/null && xdg-open http://localhost:3001 || echo "Ouvrir manuellement: http://localhost:3001"
.PHONY: prometheus
prometheus: ## Ouvrir Prometheus dans le navigateur (http://localhost:9090)
@echo "Prometheus: http://localhost:9090"
@command -v xdg-open >/dev/null && xdg-open http://localhost:9090 || echo "Ouvrir manuellement: http://localhost:9090"
.PHONY: glitchtip
glitchtip: ## Ouvrir GlitchTip dans le navigateur (http://localhost:8081)
@echo "GlitchTip: http://localhost:8081"
@command -v xdg-open >/dev/null && xdg-open http://localhost:8081 || echo "Ouvrir manuellement: http://localhost:8081"
# =============================================================================
# Shell
# =============================================================================
.PHONY: shell
shell: ## Ouvrir un shell dans le container PHP
docker compose exec php sh
.PHONY: bash
bash: shell ## Alias pour 'make shell'
.PHONY: console
console: ## Exécuter une commande Symfony (ex: make console c='debug:router')
docker compose exec php php bin/console $(c)
.PHONY: shell-frontend
shell-frontend: ## Ouvrir un shell dans le container frontend
docker compose exec frontend sh
# =============================================================================
# Backend - Qualité
# =============================================================================
.PHONY: phpstan
phpstan: ## Analyse statique PHPStan (level 9)
docker compose exec php composer phpstan
.PHONY: arch
arch: ## Tests d'architecture PHPat
docker compose exec php composer arch
.PHONY: cs-fix
cs-fix: ## Corriger le code style PHP (PHP-CS-Fixer)
docker compose exec php composer cs-fix
.PHONY: cs-check
cs-check: ## Vérifier le code style PHP sans corriger
docker compose exec php composer cs-check
.PHONY: test-php
test-php: ## Lancer les tests PHPUnit
docker compose exec -e APP_ENV=test php composer test
.PHONY: warmup
warmup: ## Préchauffer le cache Symfony
docker compose exec php php bin/console cache:warmup
# =============================================================================
# Frontend - Qualité
# =============================================================================
.PHONY: lint
lint: ## Lancer ESLint sur le frontend
docker compose exec frontend pnpm run lint
.PHONY: check-types
check-types: ## Vérifier les types TypeScript (svelte-check)
docker compose exec frontend pnpm run check
.PHONY: test-js
test-js: ## Lancer les tests Vitest
docker compose exec frontend pnpm run test
.PHONY: e2e
e2e: e2e-ci e2e-ratelimit ## Lancer tous les tests E2E (CI + rate limiting)
.PHONY: e2e-ci
e2e-ci: ## Lancer les tests E2E sans rate limiting (rapide, parallèle)
docker compose exec php php bin/console cache:pool:clear cache.rate_limiter --env=dev
cd frontend && CI=true PLAYWRIGHT_BASE_URL=http://ecole-alpha.classeo.local:5174 npx playwright test
.PHONY: e2e-ratelimit
e2e-ratelimit: ## Lancer les tests de rate limiting (lent, séquentiel)
docker compose exec php php bin/console cache:pool:clear cache.rate_limiter --env=dev
cd frontend && PLAYWRIGHT_BASE_URL=http://ecole-alpha.classeo.local:5174 npx playwright test --workers=1 --grep="Rate Limiting|CAPTCHA"
# =============================================================================
# Tout-en-un
# =============================================================================
.PHONY: test
test: test-php test-js ## Lancer tous les tests (PHPUnit + Vitest)
.PHONY: check
check: phpstan cs-check lint check-types ## Lancer tous les linters et checks
.PHONY: ci
ci: ## Lancer TOUS les tests et checks (comme en CI)
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@echo " Code Style PHP (PHP-CS-Fixer)"
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@$(MAKE) cs-check
@echo ""
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@echo " Analyse statique PHP (PHPStan level 9)"
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@$(MAKE) phpstan
@echo ""
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@echo " Tests d'architecture (PHPat)"
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@$(MAKE) arch
@echo ""
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@echo " Tests PHP (PHPUnit)"
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@$(MAKE) test-php
@echo ""
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@echo " Lint Frontend (ESLint)"
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@$(MAKE) lint
@echo ""
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@echo " Types Frontend (svelte-check)"
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@$(MAKE) check-types
@echo ""
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@echo " Tests Frontend (Vitest)"
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@$(MAKE) test-js
@echo ""
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@echo " ✅ Tous les checks sont passés !"
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@echo ""
@echo " Note: Tests E2E (make e2e) à lancer séparément depuis l'hôte"
# =============================================================================
# Scripts
# =============================================================================
.PHONY: setup-hooks
setup-hooks: ## Installer les git hooks (pre-push: make ci)
@echo "Installation des git hooks..."
@cp scripts/hooks/pre-push .git/hooks/pre-push
@chmod +x .git/hooks/pre-push
@echo "✅ Git hooks installés (pre-push)"
.PHONY: check-bc
check-bc: ## Vérifier l'isolation des Bounded Contexts
./scripts/check-bc-isolation.sh
.PHONY: check-naming
check-naming: ## Vérifier les conventions de nommage
./scripts/check-naming.sh
.PHONY: check-tenants
check-tenants: ## Vérifier que les tenants répondent
./scripts/check-tenants.sh
# =============================================================================
# Setup initial
# =============================================================================
.PHONY: install
install: up jwt-keys setup-hooks migrate warmup ## Installation complète après clone
.PHONY: migrate
migrate: ## Exécuter les migrations Doctrine
docker compose exec php php bin/console doctrine:database:create --if-not-exists
docker compose exec php php bin/console doctrine:migrations:migrate --no-interaction
.PHONY: jwt-keys
jwt-keys: ## Générer les clés JWT (requis après clone)
@echo "Génération des clés JWT..."
@docker compose exec php mkdir -p config/jwt
@docker compose exec php openssl genpkey -out config/jwt/private.pem -aes256 -algorithm rsa -pkeyopt rsa_keygen_bits:4096 -pass pass:$${JWT_PASSPHRASE:-classeo_jwt_passphrase_change_me}
@docker compose exec php openssl pkey -in config/jwt/private.pem -out config/jwt/public.pem -pubout -passin pass:$${JWT_PASSPHRASE:-classeo_jwt_passphrase_change_me}
@echo "Clés JWT générées dans backend/config/jwt/"
# =============================================================================
# Dev helpers
# =============================================================================
.PHONY: token
token: ## Créer un token d'activation (interactif). Options: email=, role=, tenant=, minor=1
docker compose exec php php bin/console app:dev:create-test-activation-token \
$(if $(email),--email=$(email),) \
$(if $(role),--role=$(role),) \
$(if $(tenant),--tenant=$(tenant),) \
$(if $(minor),--minor,) \
--base-url=http://localhost:5174
.PHONY: token-alpha
token-alpha: ## Créer un token sur ecole-alpha. Options: email=, role=, minor=1
docker compose exec -T php php bin/console app:dev:create-test-activation-token -n \
--tenant=ecole-alpha --base-url=http://ecole-alpha.classeo.local:5174 \
$(if $(email),--email=$(email),--email=alpha@test.com) \
$(if $(role),--role=$(role),) \
$(if $(minor),--minor,)
.PHONY: token-beta
token-beta: ## Créer un token sur ecole-beta. Options: email=, role=, minor=1
docker compose exec -T php php bin/console app:dev:create-test-activation-token -n \
--tenant=ecole-beta --base-url=http://ecole-beta.classeo.local:5174 \
$(if $(email),--email=$(email),--email=beta@test.com) \
$(if $(role),--role=$(role),) \
$(if $(minor),--minor,)
# =============================================================================
# Help
# =============================================================================
.PHONY: help
help: ## Afficher cette aide
@echo ""
@echo " Classeo - Commandes disponibles"
@echo ""
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}'
@echo ""