Commerce électronique avec Next.js
Gérer les stocks et l’invalidation du cache dans une boutique Next.js
Empêchez les ventes au-delà du stock avec une gestion transactionnelle, des réservations, des webhooks idempotents, des tags de cache Next.js, une invalidation ciblée et des tests de concurrence.
Le stock relève d’une transaction, pas d’une valeur de cache. Le cache peut indiquer ce qui était disponible récemment ; seule l’écriture dans la source de vérité peut promettre la dernière unité.
Définir disponible, réservé et vendu
Trail Supply possède deux Alpine Shell bleus taille M. onHand est le stock physique, reserved correspond aux quantités temporairement prises par les paiements en cours et sold aux commandes confirmées. La disponibilité est calculée à partir de ces états durables plutôt que stockée comme un nombre indépendant susceptible de diverger.
Définissez le début d’une réservation, sa durée et l’événement qui la confirme ou la libère. Réserver à l’ajout au panier est généralement trop tôt ; réserver à Checkout peut convenir aux stocks limités ; réserver au paiement exige une politique pour les acheteurs simultanés.
Rendre le changement de stock atomique
Une séquence lecture puis écriture permet à deux requêtes de voir la même dernière unité. Utilisez une transaction en base, un verrou de ligne, une mise à jour conditionnelle ou une autre primitive atomique prise en charge. L’écriture ne réussit que s’il reste assez de stock non réservé.
Imposez si possible des quantités non négatives avec des contraintes en base. Enregistrez la réservation, la variante, la quantité, le propriétaire ou la commande en attente, l’heure de création, l’expiration et le statut dans la même transaction que le changement de disponibilité.
const reserved = await db.inventory.updateMany({
where: {
variantId,
available: { gte: quantity },
},
data: {
available: { decrement: quantity },
reserved: { increment: quantity },
},
});
if (reserved.count !== 1) {
return { error: "Insufficient stock" };
}Faire expirer les réservations délibérément
Enregistrez une expiration et lancez une tâche de reprise planifiée libérant les réservations actives dont la session Checkout ne peut plus aboutir. Rendez cette libération idempotente : modifier une réservation déjà confirmée ou libérée ne doit rien faire.
Les événements tardifs exigent une politique. Si le paiement se termine après l’expiration locale, rapprochez l’état du prestataire et du traitement de la commande au lieu de recréer aveuglément du stock ou d’annuler une commande payée. Certaines boutiques acceptent les commandes en attente de réapprovisionnement ; d’autres remboursent. Encodez cette décision produit.
Invalider le plus petit ensemble correct
Après une mutation de stock ou de prix, invalidez le produit et chaque page de catégorie qui affiche la valeur changée. updateTag permet à l’utilisateur d’une Server Action de voir sa propre écriture ; revalidateTag avec un profil adapté convient aux contenus pouvant servir des données périmées pendant leur rafraîchissement.
N’effacez pas toutes les pages en cache de la boutique parce qu’une veste bleue taille M a changé. Une invalidation large augmente la charge et complique la compréhension du cache. Centralisez la construction des tags pour que les publications, webhooks et actions d’administration ciblent les mêmes entrées.
Rapprocher les événements d’entrepôt et de paiement
Enregistrez les identifiants d’événement externes avant de changer le stock. Un ajustement d’entrepôt, une annulation, un remboursement et une finalisation de paiement peuvent se répéter ou arriver hors ordre. Normalisez chaque événement en transition de stock locale et rejetez celles qui ne suivent pas l’état actuel.
Gardez un registre de mouvements en ajout uniquement ou un historique d’audit suffisant pour expliquer le total. Une quantité actuelle sans historique de réservations et de commandes est difficile à corriger après une panne de prestataire ou un problème de déploiement.
Tester en charge la concurrence et la reprise
Envoyez de nombreuses réservations concurrentes sur les deux dernières unités et vérifiez que deux au maximum réussissent. Interrompez un worker, répétez un paiement, faites expirer une réservation, livrez une finalisation tardive et reconstruisez la vue produit en cache. Vérifiez les invariants en base et les résultats visibles des clients.
Exécutez ces tests sur la compilation de production dans un aperçu Adios. Les journaux d’exécution révèlent les contentions et erreurs de webhook, tandis que les dépendances de base et de secrets restent explicites dans le manifeste. Promouvez la version après la réussite du contrôle de santé et des tests de bon fonctionnement des stocks.