rp-source-sfcc
Guide technique pour lire une vitrine SFCC/SFRA publique. Il n'embarque aucun code de capture :
rp-discovery suit son chemin « aucun adaptateur n'existe → capturer manuellement, même contrat de sortie »,
et vous écrivez le code de capture pour chaque migration comme du code de projet généré sous
migrations/<project>/src/, avec ses sorties dans migrations/<project>/data/sfcc-discovery/.
⚠️ Rien de site-spécifique (code, ids, valeurs, fixtures) n'est jamais ajouté à cette skill.
Reconnaître la plateforme
- URLs Pipeline :
/on/demandware.store/Sites-<site>-Site/<locale>/<Controller>. L'og:urlde la page d'accueil utilise souvent l'une d'elles, ce qui vous donne l'id du site et la locale par défaut. - Ressources statiques :
/on/demandware.static/.... Rendus d'image :/dw/image/v2/<REALM>_<ENV>/.... - OCAPI (
/s/<site>/dw/shop/...,/s/-/dw/data/...) répond401sans credentials. Ne demandez pas de credentials Business Manager ou OCAPI dans ce flux ; enregistrez-les comme une phase ultérieure. UtilisezsourceMode=public_content.
Fichiers à lire en premier
robots.txt. Respectez-le pour chaque requête, et prenez l'index sitemap auprès de lui.- Sitemaps (index →
sitemap_N.xml). Ils listent les produits, catégories et<image:loc>originaux. ⚠️ Les sitemaps sont incomplets. Les produits de pré-commande et les SKUs variantes manquent souvent, certains produits listés ne sont pas cherchables, et certaines entrées*.htmlsont des assets de contenu ou malformées. Ne traitez jamais le sitemap comme le catalogue. - La page d'accueil, plus quelques pages de catégorie et produit. Lisez l'en-tête, la navigation,
le pied de page et les liens
hreflang. La page d'accueil peut n'avoir pas dehreflang, apprenez les routes de locale à partir de pages internes avant de crawler.
Points d'accès publics de la vitrine (SFRA)
| Besoin | Point d'accès / source | Remarques |
|---|---|---|
| Id catégorie | Markup page catégorie (cgid) |
Les liens le portent en percent-encoded : décodez-le une fois, puis encodez-le une fois quand vous construisez une requête |
| Membres catégorie | Search-ShowAjax?cgid=<id>&start=<n>&sz=<page> |
Paginez jusqu'à ce que resultCount soit atteint. Les tuiles sont div.product[data-pid] avec le lien PDP. Un listing à zéro résultat n'est pas une catégorie |
| Modèle produit complet | Product-Variation?pid=<id>&quantity=1 → JSON {product} |
La source principale : prix de vente et prix catalogue, variationAttributes avec chaque valeur, options, availability, quantité min/max de commande, descriptions, images avec texte alt, promotions, plus les champs personnalisés du magasin. C'est un contrôleur vitrine, pas une API contractée |
| Siblings variantes | Product-Variation?pid=<master>&dwvar_<master>_<attr>=<value> |
L'id master apparaît dans les URLs de valeur. Un master seul retourne 404. N'acceptez une valeur que si la réponse marque cette valeur selected ; les valeurs selectable: false peuvent ne pas être récupérables |
| Fallback | PDP JSON-LD schema.org (Product, BreadcrumbList) |
Il ne détient que le prix de vente et une availability aplatie, donc un enregistrement construit à partir de lui liste les champs manquants comme non observés |
| Source SEO et redirect | PDP/catégorie <title>, meta description, og:*, canonical |
Détectez le SEO généré par template versus SEO défini par item. Stockez les chemins décodés. Un chemin est une source redirect, jamais un slug Wix |
L'ensemble des produits est l'union des tuiles de grille de chaque catégorie (y compris les catégories liées uniquement depuis la navigation) et des URLs de produit du sitemap. Indexez les produits par l'id de produit SFCC, pas par l'URL : les rendus de locale ont leurs propres canonicals.
Signaux faciles à mal interpréter
- Types de produit. Les variationAttributes créent des SKUs (options de variant Wix). Les product options SFCC (ex. gravure) changent le prix, pas le SKU, donc ce sont des modifiers Wix. Gardez-les dans des champs séparés.
- Visibilité d'option. Une option peut être attachée à un produit mais cachée sur la vitrine : son markup est présent mais caché. SFRA n'a pas de flag de visibilité standard. Trouvez le champ personnalisé du magasin en comparant les produits où l'option est affichée et où elle ne l'est pas. Si vous ne pouvez pas en trouver un, enregistrez la visibilité comme inconnue et ne supprimez jamais l'option.
- Stock. Les valeurs sont
inStock,preorder(avecinStockDate, qui signifie seulement une date quand le statut estpreorder), et en rupture de stock (souvent pas de statut du tout, juste un message).lowStockCountetmaxOrderQuantitysont des indices, jamais des quantités faisant autorité. - Prix.
price.listest le prix de comparaison.promotions[]nomme les ids de promotion mais jamais leurs règles.callForPricecache le prix et l'ajout au panier : cela nécessite une décision humaine. - Images. L'original est le chemin statique : supprimez
/dw/image/v2/<REALM>_<ENV>et la query string. Les rendussw/shplus grands sont des upscales. - Ratings peuvent être un nombre agrégé sans avis derrière, qui ne peut pas être importé comme avis.
- Videos peuvent être des ids opaques dont l'hôte n'est pas exposé.
Parcourir les autres pages
Les pages de produit et catégorie sont couvertes par la capture ci-dessus. Tout le reste (à propos, expédition, retours, FAQ, légal, localisateur de magasin, formulaires, cartes-cadeaux, fidélité) est généralement lié uniquement depuis l'en-tête et le pied de page.
Seeds :
- la page d'accueil ;
- chaque lien moissonnés à partir des pages de produit et catégorie ;
- chaque URL sitemap locale par défaut que la capture de catalogue n'a pas revendiquée (les assets de contenu et les pages
Page-Shown'apparaissent souvent que là).
Règles :
- Restez sur le même hôte, suivez
robots.txt, et sautez les préfixes de locale alternative. - Admettez les routes de contenu :
Page-Show?cid=<id>(assets de contenu SFRA), pages Page Designer,Stores-Find(localisateur de magasin), et routes de contenu*.htmlordinaires ou sans extension. - Sautez uniquement ceux-ci : assets ; variantes de query d'une page déjà vue ; routes de catalogue que la capture possède (
Product-*,Search-*) ; et routes d'action ou AJAX (Cart-*,Checkout*,Account-*,Login-*,Order-*,Wishlist-*,*-Ajax*, ciblesPOSTde formulaire). ⚠️ Ne sautez jamais une famille de contrôleur entière qui n'est pas sur cette liste. Enregistrez-la pour examen. - Donnez à chaque URL une disposition (
captured,covered-by-catalog,skipped:<reason>oufailed:<status>) dansdata/sfcc-discovery/page-inventory.json. Les re-runs retentent lesfailed.
Pour chaque page capturée, lisez son contenu et proposez la destination Wix : une page statique, des items CMS, un formulaire, des localisations de retrait, un produit carte-cadeau, ou un item manuel ou supprimé. La prose de politique comme les seuils de livraison gratuite, les délais de livraison, le libellé TVA ou la fenêtre de retour est une preuve pour les paramètres Wix, pas des paramètres.
- Citez-le verbatim dans
data/sfcc-discovery/policy-rules.json, avecstatus: candidate. - Ne remplissez jamais une valeur que le texte n'énonce pas.
- Faites confirmer à l'utilisateur chaque règle, y compris les limites de seuil, les titres d'option d'expédition
et les estimations de livraison. Stockez sa réponse verbatim et mettez
status: confirmedavant que quelque chose soit écrit dans Wix.
Être courtois et repérable
- Gardez un throttle pour chaque requête (commencez autour de 60 par minute), utilisez un timeout borné,
et relancez
429/503en honorantRetry-After. - Faites des checkpoints au fur et à mesure, pour qu'un re-run reprenne et retente uniquement les échecs. Rafraîchissez les prix et le stock juste avant l'import.
- Décodez les URLs toléremment : un
%malformé ne doit pas avorter le run.
Remise (artifacts existants uniquement)
Chaque stage écrit uniquement sa propre partie, par les contrats qui existent déjà :
| Stage (producteur) | Écrit | Lu par |
|---|---|---|
Code de capture (migrations/<project>/src/) |
Données brutes, page-inventory.json, policy-rules.json sous data/sfcc-discovery/ |
rp-discovery |
rp-discovery |
source-schema.json (entités de catalogue, site_page, règles confirmées comme site_policy_rule, lacunes dans sourceMeta) et la section « Gaps » de source-profile.md, nommant chaque item de cutover ci-dessous |
rp-mapper |
rp-mapper |
mapping/mapping-plan.json, y compris la urlPolicy de chaque entité routée ; une ligne mapping/review/mapping-gaps.json par item de cutover |
rp-setup-discovery, rp-import-codegen |
rp-setup-discovery |
Une entrée setup/setup-requirements.json par item de cutover (automation: manual ou blocked, le requirementId ci-dessous, recommendedAction) |
La remise du site web (setupContract.manualBlockers) |
| Code d'import généré | État URL dans state/url-preservation/, par lib/url-preservation-state.js (ci-dessous) |
Reprise, planification de redirect, cutover |
État URL, chaque fichier dans son propre rôle :
base-paths.json: intention de route au niveau entité depuis laurlPolicyde mapping.url-ledger.ndjson: une ligne append-only par enregistrement public (URL source, cible planifiée et actuelle).redirects.ndjson: uniquement quand les deux URLs relatives sont connues et diffèrent.unresolved.ndjson: uniquement les URLs toujours en attente d'une décision de route, d'une lookup de cible ou d'un examen manuel.- Une URL préservée (même chemin relatif) ferme sans redirect.
Items de cutover :
requirementId |
Déclencheur | Owner → action | Se résout quand |
|---|---|---|---|
sfcc-redirects |
Les lignes redirects.ndjson planifiées existent |
Cutover Operator → les entrer dans Wix quand le domaine se déplace (il n'y a pas d'API redirect) | Chaque ancienne URL planifiée accède à sa cible après cutover |
sfcc-page-build:<path> |
Une page capturée sans destination automatique, ou une page manual_review dans unresolved.ndjson |
Cutover Operator → construire la page à partir de son contenu capturé, ou la marquer comme supprimée, avant le lancement | La page est publiée à son URL cible (puis sa ligne de ledger et redirect suivent), ou une décision de drop enregistrée existe |
sfcc-policy-unconfirmed:<domain> |
Une règle toujours candidate dans policy-rules.json |
Nécessite Import Operator → « Confirmer ou rejeter les règles candidates dans data/sfcc-discovery/policy-rules.json avec le marchand, puis relancer le mapping et setup pour site_policy_rule » |
Chaque règle est confirmed (avec le paramètre Wix relue) ou rejected, chacune avec la réponse verbatim du marchand |
sfcc-call-for-price |
Un produit qui cache son prix | Nécessite Import Operator → « Demander au marchand comment chaque produit call-for-price devrait se vendre sur Wix, enregistrer la réponse, et re-importer ces produits » | Une réponse enregistrée, et les produits relus dans cet état |
sfcc-option-visibility |
La visibilité d'option est inconnue | Nécessite Import Operator → « Confirmer quelles options add-on les acheteurs peuvent acheter, puis re-importer les produits affectés » | Une réponse enregistrée, et les options relues |
sfcc-partial-variants:<master> |
Valeurs de variant non résolues | Nécessite Import Operator → « Relancer la capture pour les retenter ; demander au marchand si des valeurs restantes sont retirées » | Chaque valeur est résolue ou enregistrée comme retirée |
sfcc-authenticated-data |
Toujours, sur un run public uniquement | Cutover Operator → dire au marchand que les règles de promotion, l'inventaire réel, les clients, les commandes, les soldes de carte-cadeau et les produits hors ligne nécessiteront un accès Business Manager plus tard | Un accusé réception marchand enregistré, ou le passage authentifié ultérieur est complet |
sfcc-alternate-locale:<locale> |
Rendus de locale vus mais non capturés | Cutover Operator → dire au marchand que la locale n'est pas encore migrée | Un accusé réception marchand enregistré, ou un passage de locale ultérieur est complet |
⚠️ Aucune UI de cutover ne lit ceux-ci encore. Ils sont préservés pour elle, pas câblés à elle.