Ajoute la page de détail d'un site (fiche, mesure instantanée, jauge de
consommation, historique) en remplacement du placeholder. Les champs
null sont affichés explicitement avec leur raison plutôt que masqués.
Ajoute l'endpoint GET /sites/{id}/current côté backend, qui retourne la
dernière mesure connue d'un site sans filtre temporel, conformément au
contrat de l'issue.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012i5NteMLRZgfTAKB5GD37X
52 lines
1.7 KiB
Python
52 lines
1.7 KiB
Python
from collections.abc import Sequence
|
|
from datetime import datetime
|
|
|
|
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()
|
|
|
|
async def latest_for_site(self, site_id: str) -> Reading | None:
|
|
requete = (
|
|
select(Reading)
|
|
.where(Reading.site_id == site_id)
|
|
.order_by(Reading.timestamp.desc(), Reading.reading_id.desc())
|
|
.limit(1)
|
|
)
|
|
return (await self._session.scalars(requete)).first()
|
|
|
|
async def list_history(
|
|
self,
|
|
*,
|
|
start: datetime,
|
|
end: datetime,
|
|
site_id: str | None = None,
|
|
limit: int,
|
|
offset: int,
|
|
) -> Sequence[Reading]:
|
|
requete = (
|
|
select(Reading)
|
|
.where(Reading.timestamp >= start, Reading.timestamp < end)
|
|
.order_by(Reading.timestamp.desc(), Reading.reading_id.desc())
|
|
.limit(limit)
|
|
.offset(offset)
|
|
)
|
|
if site_id is not None:
|
|
requete = requete.where(Reading.site_id == site_id)
|
|
return (await self._session.scalars(requete)).all()
|