Lot 4 : Grille servie depuis l'instantané et requêtes allégées

- Grille : lecture de l'instantané grid_rows (gamme INIT et dernières gammes
  enregistrées reportées), recalcul en arrière-plan au-delà de 20 h, version de
  format dans chaque ligne pour écarter les anciens instantanés.
- Navigateur : lignes réutilisées au retour sur la Grille (< 10 min), Grille
  conservée pendant un changement de magasin ou une actualisation, React.memo
  sur la Grille, les filtres et la barre du bas, en-tête mémorisé.
- Fiche produit : toutes les lectures en parallèle.
- Ventes par mois et stock sans vente : plages de dates au lieu de TO_CHAR.
- Accueil : vagues de 12 appels, cache de 30 min.
- API v1 : comptage et page en parallèle, last_used_at au plus une fois par
  minute, version interne non exposée.
- Plan : suivi du lot 4, avec ce qui reste à valider sur la base réelle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AcA129WzGTH6zxPHFBGWmn
This commit is contained in:
Claude committed 2026-10-03 21:15:33 +00:00
1 parent 220ca2263a
commit b7ee413d67
13 files changed
+393 -119

No files matched your search

@@ -24,6 +24,13 @@ interface GridState {
*/
refreshRequest: number;
requestRefresh: () => void;
/**
* Ce que contiennent `rows` (fournisseur:magasin) et quand elles ont été
* chargées. Non persisté : sert à ne pas retélécharger la Grille quand on y
* revient, et à changer de magasin sans vider l'écran.
*/
rowsMeta: { key: string; loadedAt: number } | null;
setRowsMeta: (meta: { key: string; loadedAt: number } | null) => void;
/** Persisted column visibility state */
columnVisibility: Record<string, boolean>;
/** Persisted column sizing state */
@@ -135,6 +142,7 @@ export const useGridStore = create<GridState>()(
displayDensity: "normal",
activeGridQuery: "",
refreshRequest: 0,
rowsMeta: null,
columnVisibility: {},
columnSizing: {},
showMonthlySales: true,
@@ -222,6 +230,7 @@ export const useGridStore = create<GridState>()(
setDisplayDensity: (density) => set({ displayDensity: density }),
setActiveGridQuery: (query) => set({ activeGridQuery: sansParamRefresh(query) }),
requestRefresh: () => set((state) => ({ refreshRequest: state.refreshRequest + 1 })),
setRowsMeta: (meta) => set({ rowsMeta: meta }),
restoreSnapshot: (changes) => {
set({ draftChanges: changes, summary: computeSummary(get().rows, changes, get().activeMagasin) });
},