Merge remote-tracking branch 'origin/dev' into feat/endpoint-recommandations

This commit is contained in:
Dorian PESCE
2026-09-16 14:03:24 +02:00
18 changed files with 649 additions and 22 deletions
+9
View File
@@ -23,6 +23,7 @@ from app.core.security import decode_access_token as decode_token
from app.db.session import get_session
from app.repositories.audit_log import AuditLogRepository
from app.repositories.login_attempt import LoginAttemptRepository
from app.repositories.reading import ReadingRepository
from app.repositories.recommendation import RecommendationRepository
from app.repositories.refresh_token import RefreshTokenRepository
from app.repositories.site import SiteRepository
@@ -30,6 +31,7 @@ from app.repositories.user import UserRepository
from app.services.auth import AuthService, LoginPolicy
from app.services.recommendation import RecommendationService
from app.services.site import SiteService
from app.services.stats import StatsService
from app.services.user import UserService
SessionDep = Annotated[AsyncSession, Depends(get_session)]
@@ -149,6 +151,13 @@ def get_recommendation_service(session: SessionDep) -> RecommendationService:
RecommendationServiceDep = Annotated[RecommendationService, Depends(get_recommendation_service)]
def get_stats_service(session: SessionDep) -> StatsService:
return StatsService(sites=SiteRepository(session), readings=ReadingRepository(session))
StatsServiceDep = Annotated[StatsService, Depends(get_stats_service)]
async def get_current_principal(
credentials: CredentialsDep,
session: SessionDep,
+5
View File
@@ -61,6 +61,11 @@ TAGS: Final[list[dict[str, Any]]] = [
"`lecteur`."
),
},
{
"name": "stats",
"description": "Statistiques agrégées de consommation. Accessible à partir du rôle "
"`lecteur`.",
},
]
cookie_de_rafraichissement = APIKeyCookie(
@@ -0,0 +1,16 @@
from fastapi import APIRouter
from app.api.deps import LecteurDep, StatsServiceDep
from app.schemas.stats import StatsSummaryResponse
router = APIRouter()
@router.get(
"/summary",
response_model=StatsSummaryResponse,
summary="Résume la consommation instantanée du parc",
)
async def get_summary(_: LecteurDep, service: StatsServiceDep) -> StatsSummaryResponse:
resume = await service.summary()
return StatsSummaryResponse.model_validate(resume)
+2 -1
View File
@@ -1,7 +1,7 @@
from fastapi import APIRouter
from app.api.openapi import REPONSE_SERVEUR, REPONSES_ADMIN, REPONSES_LECTEUR
from app.api.v1.endpoints import auth, health, recommendations, sites, users
from app.api.v1.endpoints import auth, health, recommendations, sites, stats, users
api_router = APIRouter(responses=REPONSE_SERVEUR)
api_router.include_router(health.router, prefix="/health", tags=["health"])
@@ -14,3 +14,4 @@ api_router.include_router(
tags=["recommendations"],
responses=REPONSES_LECTEUR,
)
api_router.include_router(stats.router, prefix="/stats", tags=["stats"], responses=REPONSES_LECTEUR)