Files
workshop-manager/openspec/changes/perf-data-optimization/design.md
Froidefond Julien 2d266f89f9 feat(perf): implement performance optimizations for session handling
- Introduced a new configuration file `config.yaml` for specifying project context and artifact rules.
- Added `.openspec.yaml` files for tracking changes related to performance improvements.
- Created design documents outlining the context, goals, decisions, and migration plans for optimizing session performance.
- Proposed changes include batching database queries, debouncing event refreshes, purging old events, and implementing loading states for better user experience.
- Added tasks and specifications to ensure proper implementation and validation of the new features.

These enhancements aim to improve the scalability and responsiveness of the application during collaborative sessions.
2026-03-10 08:06:47 +01:00

60 lines
3.9 KiB
Markdown

## Context
`src/services/weather.ts` utilise `findMany` sans `take` ni `orderBy`, chargeant potentiellement des centaines d'entrées pour calculer des tendances qui n'utilisent que les 30-90 derniers points. Les services de sessions utilisent `include: { items: true, shares: true, events: true }` pour construire les listes, alors que l'affichage carte n'a besoin que du titre, de la date, du comptage d'items et du statut de partage. `User.name` est filtré dans les recherches admin mais sans index SQLite. Les pages les plus visitées (`/sessions`, `/users`) recalculent leurs données à chaque requête.
## Goals / Non-Goals
**Goals:**
- Borner le chargement historique weather à une constante configurable
- Réduire la taille des objets retournés par les queries de liste (select vs include)
- Ajouter un index SQLite sur `User.name`
- Introduire un cache Next.js sur les queries de liste avec invalidation ciblée
**Non-Goals:**
- Changer la structure des modèles Prisma
- Modifier le rendu des pages (les sélections couvrent tous les champs affichés)
- Introduire un cache externe (Redis, Memcached)
- Optimiser les pages de détail session (hors scope)
## Decisions
### 1. Constante WEATHER_HISTORY_LIMIT dans lib/types.ts
**Décision** : Définir `WEATHER_HISTORY_LIMIT = 90` dans `src/lib/types.ts` (cohérent avec les autres constantes de config). La query devient : `findMany({ orderBy: { createdAt: 'desc' }, take: WEATHER_HISTORY_LIMIT })`.
**Alternatives** : Paramètre d'URL ou env var → sur-ingénierie pour un seuil rarement modifié.
### 2. Select minimal pour les listes — interface ListItem dédiée
**Décision** : Pour chaque service de liste, définir un type `XxxListItem` dans `types.ts` avec uniquement les champs de la carte (id, title, createdAt, _count.items, shares.length). Utiliser `select` Prisma pour matcher exactement ce type.
**Alternatives** : Garder `include` et filtrer côté TypeScript → charge DB identique, gain nul.
### 3. Index @@index([name]) sur User
**Décision** : Ajouter `@@index([name])` dans le modèle `User` de `schema.prisma`. Créer une migration nommée `add_user_name_index`. Impact : SQLite crée un B-tree index, recherches `LIKE 'x%'` bénéficient de l'index (prefix match).
**Note** : `LIKE '%x%'` (contains) n'utilise pas l'index en SQLite — acceptable, le use case principal est la recherche par préfixe.
### 4. unstable_cache avec tags sur requêtes de liste
**Décision** : Wrapper les fonctions de service de liste (ex: `getSessionsForUser`, `getUserStats`) avec `unstable_cache(fn, [cacheKey], { tags: ['sessions-list:userId'] })`. Les Server Actions appellent `revalidateTag` correspondant après mutation.
Durée de cache : `revalidate: 60` secondes en fallback, mais invalidation explicite prioritaire.
**Alternatives** : `React.cache` → par-requête uniquement, pas de persistance entre navigations ; `fetch` avec cache → ne s'applique pas aux queries Prisma.
## Risks / Trade-offs
- **select strict** → si un composant accède à un champ non sélectionné, erreur TypeScript au build (bonne chose — détecté tôt).
- **unstable_cache** → API Next.js marquée unstable. Mitigation : isoler dans les services, wrapper facilement remplaçable.
- **Index User.name** → légère augmentation de la taille du fichier SQLite et du temps d'écriture. Négligeable pour les volumes actuels.
- **WEATHER_HISTORY_LIMIT** → les calculs de tendance doivent fonctionner avec N entrées ou moins. Vérifier que l'algorithme est robuste avec un historique partiel.
## Migration Plan
1. Migration Prisma `add_user_name_index` (non-destructif, peut être appliqué à tout moment)
2. Ajout `WEATHER_HISTORY_LIMIT` + update query weather (indépendant)
3. Refactoring select par service (vérifier TypeScript au build à chaque service)
4. Ajout cache layer en dernier (dépend des tags définis en Phase 2 si applicable, sinon définir localement)