Nouveau module `backend/app/solver/` (mêmes conventions que
`validation/` : models purs, engine pur testé, loader seul lien avec la
base). Pour chaque créneau encore sous son effectif idéal, calcule une
liste ordonnée de bénévoles candidats — c'est la coordination qui
affecte, dans l'écran habituel ; le solveur fait juste remonter ces
candidats en tête de liste (voir le câblage frontend à suivre).
- Seule contrainte dure : aucun chevauchement de créneaux pour un même
bénévole (règle SHIFT_OVERLAP), à la fois contre l'existant et entre
deux suggestions du même calcul. L'effectif idéal est un plafond dur.
- Tout le reste est un terme de l'objectif, pas un blocage : priorité
forte aux créneaux sous l'effectif minimal, bonus vœu de poste, malus
disponibilité manquante (réutilise `validation.engine.uncovered_minutes`),
cumul de 8 h et repos (contre les affectations déjà décidées),
répartition de la charge.
- `POST /editions/{id}/solver/suggestions` (COORDINATION/référent) :
recalcule à la demande, ne persiste jamais d'affectation.
Dépendance `ortools`. 18 nouveaux tests (moteur + API), 172 tests au
vert, `ruff` et `alembic check` verts. Testé sur le jeu de démo (120
bénévoles, 100 créneaux) : ~0,3 s.
CLAUDE.md : nouvelle section 4 (solveur), renumérotation 5-10,
compétences retirées de « hors périmètre », journal étape 15.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017uUsRg7XzopkCPWimwg9ZM
51 lines
1.8 KiB
Python
51 lines
1.8 KiB
Python
from fastapi import FastAPI
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
|
|
from app.api.accounts import router as account_router
|
|
from app.api.artists import router as artist_router
|
|
from app.api.assignments import router as assignment_router
|
|
from app.api.auth import router as auth_router
|
|
from app.api.availability import router as availability_router
|
|
from app.api.day_parts import router as day_part_router
|
|
from app.api.editions import router as edition_router
|
|
from app.api.health import router as health_router
|
|
from app.api.imports import router as import_router
|
|
from app.api.matrix import router as matrix_router
|
|
from app.api.notifications import router as notification_router
|
|
from app.api.positions import router as position_router
|
|
from app.api.shifts import router as shift_router
|
|
from app.api.solver import router as solver_router
|
|
from app.api.volunteers import router as volunteer_router
|
|
from app.config import get_settings
|
|
from app.logging_config import configure_logging
|
|
|
|
configure_logging()
|
|
|
|
settings = get_settings()
|
|
|
|
app = FastAPI(title="Gestion des bénévoles", version="0.1.0")
|
|
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=settings.cors_origins,
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
app.include_router(health_router)
|
|
app.include_router(auth_router)
|
|
app.include_router(edition_router)
|
|
app.include_router(day_part_router)
|
|
app.include_router(account_router)
|
|
app.include_router(import_router)
|
|
app.include_router(artist_router)
|
|
app.include_router(volunteer_router)
|
|
app.include_router(availability_router)
|
|
app.include_router(position_router)
|
|
app.include_router(shift_router)
|
|
app.include_router(assignment_router)
|
|
app.include_router(solver_router)
|
|
app.include_router(matrix_router)
|
|
app.include_router(notification_router)
|