Les tableaux d'analyse
« Combien d’œuvres, combien d’exemplaires, lesquelles ne sortent jamais » : la question revient dans tous les modules, avec la même forme d’écran. Une rangée de cartes, un tableau cliquable en dessous. Le noyau fournit l’écran ; votre module fournit les chiffres.
from kewos.insights import ( InsightCard, InsightColumn, InsightRow, InsightsState, has_insights_provider, register_insights_provider,)
class TitleInsights: def state(self, session, classes) -> InsightsState: title = classes["library_title"] titles = list(session.execute(select(title).order_by(title.name)).scalars()) return InsightsState( title="insights.library.title", cards=( InsightCard(key="titles", label="insights.library.titles", value=str(len(titles))), ), columns=(InsightColumn(key="name", label="library_title.name"),), rows=tuple( InsightRow(record_id=int(t.id), cells={"name": t.name}) for t in titles ), )
def register_library_insights() -> None: if not has_insights_provider("library_title"): # le boot réimporte register_insights_provider("library_title", TitleInsights())Un point d’entrée générique sert le tout :
GET /api/v1/insights/library_title
{"title":"insights.library.title", "cards":[{"key":"titles","value":"8"},{"key":"copies","value":"8"}, {"key":"orphans","value":"1","token":"destructive"}], "columns":[{"key":"name","label":"library_title.name","kind":"text"}, ...], "rows":[{"record_id":2,"cells":{"name":"A Brief History of Time","copies":1}}, ...]}Aucun écran n’est écrit. Les libellés sont des clés i18n, les colonnes ont un kind
(text, progress, badge) qui choisit le rendu de la cellule, et record_id fait de chaque
ligne un lien vers la fiche. Un modèle sans fournisseur répond 404 : la surface n’invente
rien.
Quatre modules du produit livrent un fournisseur d’analyse : la formation, le pipeline commercial, la signature électronique et le marketing.