Files
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

3.9 KiB

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)