rp-import-codegen
Générer des lecteurs de source, des transformations et des writers Wix à partir des artefacts de migration approuvés.
Purpose
Cette skill transforme le schéma, le mapping et les décisions de configuration en fichiers d'implémentation sous le projet de migration actif.
Required inputs
migrations/<project>/source-schema.jsonmigrations/<project>/mapping-plan.mdmigrations/<project>/setup-requirements.mdlorsque la configuration affecte les chemins d'écriture
Source read contract
La génération d'un lecteur correct nécessite des connaissances spécifiques à la plateforme — modèle d'authentification, pagination, limites de débit et particularités REST. Ces connaissances résident dans la source adapter skill correspondante, pas ici ; cette skill ne nomme jamais une plateforme. Résolvez l'adapter à partir du champ platform dans source-schema.json via la convention de nommage rp-source-<platform> (par exemple platform: "wordpress" → rp-source-wordpress) et lisez sa section "Read contract". Les faits opérationnels doivent déjà être enregistrés dans source-profile.md ; utilisez l'adapter pour combler les lacunes plutôt que de deviner. rp-execute-import exécute le lecteur que vous générez et reste agnostique à la plateforme — donc les spécificités de la plateforme doivent être intégrées dans ce code généré, pas reportées à l'exécution.
L'ajout d'une nouvelle plateforme source ne nécessite donc aucune modification de cette skill : un nouvel adapter rp-source-<platform> suffit.
Target write contract
Symétriquement, ne re-dérivez pas la surface d'écriture Wix ici. Elle est identique pour chaque migration et est pré-vérifiée dans l'adapter rp-target-wix (skill sœur ; voir CONVENTIONS.md), qui distribue lib/wix-writers.js — générateurs et exécuteurs de requêtes vérifiés une fois pour l'import de médias, le convertisseur HTML→rich-content Ricos, les catégories/tags/brouillons de Blog, les éléments Wix Data et les Membres. Vendez une copie de rp-target-wix/lib/wix-writers.js dans le projet (comme le transport source) et générez des writers qui appellent ses primitives, en fournissant uniquement les mappages de champs par projet. Ne générez jamais les endpoints/corps Wix en ligne — cette voie a répétées fois livré des formes incorrectes (énums de plugin Ricos en minuscules, corps de tags {tag:{…}}, images vedettes media.wixMedia.image.id) qui n'ont échoué qu'à l'exécution.
Validez par un appel réel, pas par un exemple de documentation. Les vérifications de documentation MCP confirment qu'un endpoint existe ; elles ne confirment pas que la forme de requête fonctionne — les exemples publics ont été erronés (FR-007). Fiez-vous à une forme de requête Wix uniquement après qu'un appel réel (ou rp-target-wix/scripts/contract-test.js en mode live, exécuté depuis le répertoire de la skill rp-target-wix) ait réussi. Traitez les formes // VERIFIED: de l'adapter comme la source de vérité plutôt que tout exemple de documentation.
L'ajout d'une nouvelle plateforme source ne nécessite aucune modification ici, et le changement de surface Wix pour toutes les migrations est une édition en un seul endroit dans rp-target-wix (capturée par son test de contrat), pas une régénération par projet.
Workflow
- Lisez les artefacts de découverte, mapping et configuration, plus le read contract de l'source adapter et le write contract de
rp-target-wix. - Générez le code du lecteur source qui peut énumérer et récupérer les entités source. Si l'adapter distribue un module de transport partagé (auth, pagination, throttling, retries), vendez une copie de celui-ci dans le projet (par exemple
migrations/<project>/src/lib/) et importez à partir de celui-ci au lieu de réémettre cette plomberie — le lecteur ne doit contenir que l'orchestration par projet. Le lecteur doit extraire les enregistrements source dans des fichiers durables sur disque ; il ne doit pas exiger que l'ensemble du dataset source réside en mémoire avant le début de l'import. - Générez le code de transformation qui mappe les enregistrements source dans les payloads Wix.
- Générez le code writer qui écrit dans les entités ou collections Wix — vendez
rp-target-wix/lib/wix-writers.jsdanssrc/lib/et appelez ses primitives ; le writer généré ne contient que les mappages de champs par projet + ordonnancement, pas la plomberie API Wix. - Générez les points d'entrée d'extraction/import exécutables (voir ci-dessous) — les artefacts que
rp-execute-importexécute réellement. Ceci est requis, pas optionnel. - Générez un plan d'exécution si le batching, le checkpointing ou les retries sont nécessaires.
- Documentez tout suivi de code manuel encore requis.
Runnable extraction/import entrypoints — les artefacts sont le chemin d'exécution (requis)
rp-execute-import exécute l'import en exécutant cet artefact, jamais en ayant l'agent émettant des appels Wix MCP manuellement (voir la section "Execute the generated scripts — never an agentic MCP flow" de cette skill). Donc la codegen doit émettre des points d'entrée réels et exécutables :
src/extract-source.jsou point d'entrée lecteur équivalent — lit les API source et écrit des fichiers extraits durables sous le projet. L'extraction est une étape séparée des écritures de destination, donc les grandes migrations peuvent être reprises ou réimportées sans relire la source entière.src/run-import.jsou point d'entrée import équivalent — lit les fichiers extraits, applique les transformations et écrit sur Wix dans l'ordre de dépendance via le transportwix-writersvendus (fetch+ credentials injectées, ou le SDK Wix). Il doit :- charger les fichiers config locaux au projet, puis traiter env, pour toutes les valeurs attendues de style env (jamais codées en dur ; échouer rapidement si absent — ne pas se rabattre sur aucune auth agent/MCP),
- consommer les fichiers source extraits du disque plutôt que de matérialiser la source entière en mémoire,
- appliquer la dédupe idempotente indexée par l'ID source, en utilisant soit un champ source-id contrôlé par le client sur la cible, soit une crosswalk
sourceId -> targetIddurable pour les entités Wix natives avec IDs assignés par le serveur, - honorer un flag
--dry-run/--samplepour la passe de validation sûre.
- Le dry-run est le même chemin de code import avec écritures désactivées — pas un driver séparé. Un dry-run autonome qui construit des enveloppes de requête mais n'exerce jamais le chemin réel
fetch/auth/async-polling valide un code qui ne sera pas livré.
Extraction format requirements:
- écrivez les données extraites dans des fichiers locaux au projet, pas la mémoire de processus
- fragmentez par entité et page/batch afin qu'une grande source ne devienne pas un seul fichier géant
- écrivez un manifest qui permet à l'étape import de découvrir quels fichiers d'entités existent et dans quel ordre les consommer
- rendez les fichiers extraits déterministes suffisamment pour la reprise, la relecture et le débogage
Project-local config files
Le code généré doit traiter migrations/<project>/config/ comme la maison canonique pour toutes les valeurs sinon attendues comme variables d'environnement. Utilisez une syntaxe simple .env et chargez ces fichiers avant de lire la configuration :
-
config/wix.envexiste toujours :WIX_SITE_ID= WIX_AUTH_TOKEN= -
config/source.<platform>.envexiste après que la plateforme source soit connue. Pour WordPress :WP_BASE_URL= WP_USERNAME= WP_APPLICATION_PASSWORD= WP_MEDIA_URL_REWRITE_FROM= WP_MEDIA_URL_REWRITE_TO= WC_CONSUMER_KEY= WC_CONSUMER_SECRET=
Codegen rules:
- Générez un petit chargeur de configuration indépendant des dépendances dans le point d'entrée exécutable ou
src/lib/. - Chargez
config/wix.envet la config source sélectionnée avant de construire les clients source/Wix. - Les variables de processus réelles peuvent remplacer les valeurs de fichier.
- Les valeurs vides dans les fichiers config ne doivent pas remplacer les valeurs de processus env non vides.
- Si une clé requise est encore manquante après chargement fichier + env, échouez rapidement avec le nom de la clé, pas un 401 en aval.
- Ne loguez jamais les valeurs secrètes. Il est acceptable de logger qu'une clé est présente/absente.
- Ne générez pas de sortie de débogage qui déverse le contenu des fichiers config, des snapshots d'environnement ou des en-têtes de requête portant des credentials.
Localhost media sources
Si le profil source montre localhost, 127.0.0.1 ou une autre URL source réservée au privé, le code d'import de médias généré ne doit pas supposer que Wix peut récupérer ces URLs. L'import de Wix Media est basé sur l'URL (rp-target-wix primitive import-from-URL), donc l'import de médias live a besoin d'une URL publique accessible par les serveurs Wix. C'est optionnel et, autant que nous le savons aujourd'hui, n'affecte que l'import de médias.
La codegen/runtime doit supporter l'un de ces chemins explicites :
-
Utilisez une URL de tunnel/source HTTPS publique pour l'import de médias live. Pour ngrok sur macOS :
brew install ngrok ngrok config add-authtoken "<YOUR_AUTHTOKEN>" ngrok http 8090 export WP_BASE_URL=https://<id>.ngrok-free.app -
Si les réponses REST source contiennent toujours des URLs de médias locales, générez une réécriture configurable de l'URL de base locale vers l'URL de base du tunnel public. Pour WordPress, utilisez
WP_MEDIA_URL_REWRITE_FROMetWP_MEDIA_URL_REWRITE_TO; lorsque ceux-ci sont vides, il est acceptable de réécrire les origines localhost/privées vers l'URL publiqueWP_BASE_URL. -
Ou générez/permettez un mode media-skip/defer et documentez que les références dépendantes des médias telles que les images vedettes, galeries et fichiers téléchargeables seront absents jusqu'à ce que les médias soient importés.
Surfacez le chemin sélectionné dans import-plan.md et le plan d'exécution avant toute écriture live. Ne laissez pas un dry-run avec des URLs de médias localhost impliquer que l'import Wix Media live est prêt.
File targets
Écrivez le code sous l'arborescence source locale du projet :
migrations/<project>/src/readers/migrations/<project>/src/transforms/migrations/<project>/src/writers/migrations/<project>/src/lib/— modules partagés vendus (par exemple le module de transport de l'source adapter), copiés ici afin que le projet s'exécute de manière autonome sans dépendances externesmigrations/<project>/src/extract-source.jsou point d'entrée lecteur équivalent — écrit les fichiers source extraitsmigrations/<project>/src/run-import.js— le point d'entrée import exécutable (requis ; voir "Runnable extraction/import entrypoints" ci-dessus).--dry-runpilote la passe de validation sûre via le même chemin de code import.migrations/<project>/data/source-extract/— fichiers source extraits et manifest(s)migrations/<project>/import-plan.md
Verifying Wix APIs
Le contrôle primaire est le Target write contract ci-dessus : appelez les primitives vérifiées de rp-target-wix quand elles existent. Cet adapter est l'endroit où chaque forme stable est vérifiée une fois (par un appel réel) et où un changement de surface Wix est corrigé en un seul endroit. Quand Wix a une entité native mais que rp-target-wix n'a pas encore de writer dédié, la codegen doit générer un appel Wix REST pour cette entité native via le helper REST direct générique de l'adapter, logger le writer manquant, et appeler le hook de notification RePlatform. Ne routez pas vers CMS simplement parce que le writer est manquant.
- Préférez le Wix MCP (le serveur API-docs/schema) pour localiser l'endpoint et la forme requête/réponse. Si la forme est assez commune, ajoutez une primitive dédiée à
rp-target-wix/lib/wix-writers.js; sinon générez un appel REST natif local au projet viasendDirectRestet marquez-leUNVERIFIED. - Si le Wix MCP est attendu mais manquant, traitez cela comme une lacune de prérequis d'abord. Avant de vous rabattre sur la documentation, essayez d'abord de vous assurer que le Wix MCP est installé/connecté dans le runtime actuel. Si l'environnement supporte les flux connector/plugin install, utilisez-les. Sinon, arrêtez-vous à needs-user avec des instructions d'installation/connexion exactes pour le Wix MCP, puis reprenez la codegen après qu'il soit disponible.
- Confirmez la forme avec un appel réel, pas un exemple de documentation — les exemples publics ont été erronés (FR-007 : énums de plugin Ricos en minuscules 400). Couvrez la nouvelle primitive dans
rp-target-wix/scripts/contract-test.jsafin que la dérive reste visible. - Fallback quand aucun Wix MCP n'est disponible : fiez-vous à la documentation Wix REST/SDK publiée et à des noms conservateurs uniquement quand l'utilisateur accepte explicitement un chemin provisoire. Marquez l'appel natif généré
// UNVERIFIED:jusqu'à ce qu'un appel réel le confirme — ne livrez jamais un appel Wix non vérifié au site live d'un utilisateur sans le surfacer dans le plan d'exécution.
Runtime policy
Vérifiez chaque endpoint et champ Wix par rapport au Wix MCP au moment de la codegen. Le marqueur // UNVERIFIED: est un fallback uniquement pour les environnements où le MCP est réellement indisponible, pas un moyen de livrer des appels non vérifiés qui échouent plus tard sur le site live de l'utilisateur. Tout non vérifié doit être surfacé explicitement dans les artefacts en aval avant exécution.
Missing writer policy
Le fallback CMS est pour les concepts source qui n'ont pas d'entité Wix native appropriée, ou pour les entités natives explicitement rejetées parce qu'elles ne peuvent pas préserver la fidélité ou causeraient des effets secondaires dangereux. CMS n'est pas un fallback pour un writer manquant, et ce n'est pas un défaut spécial pour les coupons simplement parce que la portée/restrictions de coupons ont besoin de mapping.
Quand le mapping cible une entité Wix native et qu'aucun writer rp-target-wix dédié n'existe :
- Générez le code local au projet qui appelle l'endpoint Wix REST natif via
sendDirectRest. - Ajoutez une ligne de log claire avant la première utilisation de ce chemin REST généré.
- Appelez
notifyMissingWriter({ sourceEntity, wixEntity, method, path, reason }). L'implémentation actuelle peut être une no-op ; le code généré doit toujours l'appeler. - Marquez le chemin
UNVERIFIEDdansimport-plan.mdet le rapport execution-plan jusqu'à ce qu'un appel live/sandbox le promeuve. - Maintenez les mêmes règles d'idempotency que les writers dédiés : crosswalk par ID source et ne dédupliquez jamais par slug.
Codegen rules
- Gardez les responsabilités de lecteur et writer séparées.
- Ne générez pas un importeur read-all-into-memory pour le cas général. Le lecteur extrait d'abord sur disque ; l'importeur consomme les fichiers extraits du disque.
- Rendez les transformations déterministes et testables.
- Préservez les ID sources pour la traçabilité, mais ne supposez pas que les ID cibles Wix natifs peuvent être préservés ou assignés par le client.
- Pour les entités Wix natives, générez et utilisez une crosswalk durable (
sourceId -> targetId) chaque fois que l'API cible n'expose pas un champ source-id contrôlé par le client. Amorcez-la au démarrage viaqueryAllDataItems(ImportCrosswalk)et écrivez une ligne par entité créée, afin que les re-exécutions/continuations sautent les enregistrements faits. La dédupe basée sur slug ne fonctionne PAS — Wix réécrit les slugs (FR-010) ; ne vous fiez jamais à cela. - Le nom de collection canonique est
ImportCrosswalk. Si les artefacts en amont disent toujoursMigrationRefs, normalisez-les àImportCrosswalkdans le code généré et notez la normalisation dansimport-plan.md. - Attachez chaque entité connexe, ne la créez pas simplement. Créer un tag/catégorie n'est pas la même chose que le lier. Les articles Blog attachent les tags via
tagIds(GUIDs) et les catégories viacategoryIdslors de la création de draft-post — collectez les ids résolus et passez-les, ou la taxonomie existe sur le site maispostCountreste 0 (le bug du builder FR-012). - Les créations de taxonomie ne sont pas idempotentes (FR-011) : traitez
409 ALREADY_EXISTScomme un succès ET résolvez l'ID de l'entité existante (par exemplelistBlogTags) afin qu'elle puisse toujours être attachée — ne la supprimez pas. - Le texte riche est fragmenté pour vous.
convertHtmlToRichContentdivise transparemment le HTML sur le plafond Ricos de 30k (FR-009) et fusionne les tableaux de nœuds ; passez le HTML complet, ne pré-tronquez pas ou ne sautez pas les grands articles. - Incluez le batching, la pagination, la journalisation et les hooks de retry le cas échéant.
- Ne codez pas en dur les secrets.
Output
Résumez quels fichiers ont été générés, quelles entités ils couvrent et tout écart d'implémentation restant.