Ajoute le resume instantane de consommation du parc attendu par le frontend (deja developpe contre ce contrat en mode mock). Nouveaux SiteRepository et ReadingRepository (derniere lecture par site via DISTINCT ON), StatsService pour l'agregation et les cas de repli (capacite nulle, absence de lecture, data_quality inconnue), et le endpoint lecteur-seul correspondant. Documentation des routes et du schema des couches mises a jour.
22 lines
734 B
Python
22 lines
734 B
Python
from collections.abc import Sequence
|
|
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.models.energy import Reading
|
|
|
|
|
|
class ReadingRepository:
|
|
def __init__(self, session: AsyncSession) -> None:
|
|
self._session = session
|
|
|
|
async def latest_by_site(self) -> Sequence[Reading]:
|
|
# `.distinct(site_id)` compile en `DISTINCT ON (site_id)` sous PostgreSQL : une seule
|
|
# ligne par site, la plus récente grâce à l'ordre composite qui suit.
|
|
requete = (
|
|
select(Reading)
|
|
.distinct(Reading.site_id)
|
|
.order_by(Reading.site_id, Reading.timestamp.desc())
|
|
)
|
|
return (await self._session.execute(requete)).scalars().all()
|