Le changement d'onglet déclenchait un router.push : la page serveur était rejouée et les 3 requêtes SQL relancées à chaque clic, alors que les données étaient déjà côté client. Sans aucun retour visuel, l'onglet semblait bloqué. Interface (stock-negatif/client.tsx) - Changement d'onglet purement client (useTransition + history.replaceState) : plus aucune requête SQL rejouée, l'URL reste partageable. - Modal de chargement pendant le changement de magasin (seule action qui interroge vraiment le serveur), pendant un changement d'onglet lent et pendant la génération de l'export Excel. Affichage différé de 120 ms pour éviter tout clignotement. - Pagination 50 lignes : l'onglet « Sans vente 6 mois » rendait jusqu'à 17 000 lignes d'un coup, ce qui figeait le navigateur. L'export Excel continue de reprendre l'intégralité des lignes filtrées. - Tri : ordre de la base conservé tant qu'aucune colonne n'est cliquée (le tri alphabétique sur codein écrasait le classement métier), collateur Intl réutilisé au lieu d'un localeCompare par comparaison, tri numérique robuste aux valeurs nulles. - Les 3 onglets partagent désormais un composant de tableau unique piloté par une configuration de colonnes, au lieu de 3 copies quasi identiques. - Select magasin et onglets désactivés pendant le chargement, aria-busy posé. Données (pg-ff-client.ts) - Un article n'est plus rattaché à son fournisseur principal mais au fournisseur de sa dernière entrée en stock : s'il est rentré chez un autre fournisseur, il n'apparaît plus sous le précédent. La colonne de mvtart qui porte ce lien est détectée une fois par process parmi une liste blanche (même principe que getNomenclatureParentCol), avec repli documenté sur artfou1.preference = 1 si la base ne porte pas l'information. - La jointure latérale sur la dernière entrée remplace la sous-requête corrélée MAX(datmvt) : même coût qu'avant pour une information de plus. - pgGetStockSansVente dédoublonne artfou1 via DISTINCT ON comme ses deux requêtes sœurs, et exclut les stocks nuls en SQL (HAVING) au lieu de les filtrer côté client : le compteur d'onglet correspond enfin aux lignes réellement transmises. Diagnostic - GET /api/diag/stock-fournisseur : colonne détectée, colonnes réelles de mvtart et échantillon comparant fournisseur principal et fournisseur de dernière entrée. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0174nm1nWPaypWBNHioSTJ8X
CollectFlow
CollectFlow est une application de révision d'assortiment et d'analyse de performances des produits en point de vente, conçue pour consolider les données issues de plusieurs fournisseurs et magasins.
Prérequis
- Node.js 18+ (pour le développement local)
- Docker et Docker Compose (pour le déploiement conteneurisé)
- PostgreSQL 16+
Lancer avec Docker
Le projet est configuré pour tourner dans un conteneur Docker optimisé (mode standalone de Next.js). Note : Vous devez disposer d'une base de données PostgreSQL séparée (le conteneur ne lance que l'application web).
1. Démarrer l'application
À la racine du projet, lancez :
npm run docker:build
# ou directement
docker-compose up -d --build
L'application sera accessible sur http://localhost:5643.
L'application sera attachée au réseau Docker externe nginx_default afin d'être exposée derrière votre reverse proxy Nginx. Assurez-vous que ce réseau existe (docker network create nginx_default).
2. Arrêter l'application
npm run docker:down
# ou directement
docker-compose down
Développement Local (Sans Docker)
Si vous préférez développer en local, vous devrez configurer votre propre base de données PostgreSQL.
- Installer les dépendances :
npm install
-
Configurer la connexion DB : Allez sur la page des Paramètres (
/settings) dans l'application pour configurer l'accès à votre PostgreSQL local. -
Lancer le serveur de développement :
npm run dev
Structure du Projet (BMAD)
Ce projet respecte l'architecture BMAD (Business, Model, Application/API, Data) :
src/features/*: Logique métier (Business) isolée par feature (ex:grid,snapshots)src/types/*: Interfaces TypeScript (Model)src/app/*: Routeurs Next.js UI et endpoints d'API (Application/API)src/db/*: Schémas Drizzle ORM et connexions (Data)