rp-quick-runtime

Par wix · skills

Récupération déterministe de la limite cible partagée et exécution du rapport final que chaque adaptateur quick-mode rp-quick-<platform> utilise avant une écriture Wix Stores.

npx skills add https://github.com/wix/skills --skill rp-quick-runtime

rp-quick-runtime

Non invoqué directement — c'est une bibliothèque partagée (lib/limit-recovery.js), pas un adaptateur autonome. Chaque adaptateur quick-mode rp-quick-<platform> (rp-quick-shopify, rp-quick-woocommerce) l'importe depuis son propre scripts/quick-mode.js et doit l'utiliser dès sa première version. Les adaptateurs de plateforme possèdent l'extraction de source et la sémantique des champs ; ce runtime possède l'application des limites cibles, l'agrégation du ledger de récupération et le rapport final lisible par l'homme — de sorte qu'une limite de validation Wix Stores ne transforme jamais silencieusement un enregistrement par ailleurs valide en skip opaque.

const recovery = require('../rp-quick-runtime/lib/limit-recovery.js');

const normalized = recovery.normalizeProduct({ sourceId, sku, tagIds });
// normalized.sku / normalized.tagIds sont les valeurs plafonnées/réduites à écrire ;
// normalized.recoveries liste ce qui a été plafonné ou réduit, le cas échéant.
await writeProduct({ ...product, sku: normalized.sku, tagIds: normalized.tagIds });
// Enregistrez written_with_loss uniquement après la réussite de l'écriture cible, jamais en dry run.
if (normalized.recoveries.length) {
  if (!dryRun) await recovery.appendRecoveries(projectDir, adapterName, sourceId, normalized.recoveries);
  recovery.recordRecoveredRecord(summary, normalized.recoveries);
}
// ...après la run :
await recovery.writeFinalReport(projectDir, summary, { dryRun });

normalizeProduct applique les deux limites Stores vérifiées de manière déterministe : plafonne tagIds à STORES_PRODUCT_TAGS_MAX (ordre de source vu en premier, extras omis) et réduit sku à STORES_SKU_MAX caractères Unicode-sûrs avec un suffixe dérivé stable de l'ID source afin qu'un SKU réduit reste unique. Chaque plafonnement/réduction est rapporté dans recoveries[], jamais appliqué silencieusement.

appendRecoveries enregistre chaque récupération dans execution/quick-limit-recoveries.ndjson sous le nom de l'adaptateur, marqué outcome: written_with_loss — l'enregistrement durable de ce qui a été préservé ou perdu, par enregistrement source. Ne l'appelez qu'après la réussite de l'écriture cible.

recordRecoveredRecord incrémente summary.recovered une fois pour l'enregistrement source écrit et incrémente summary.recoveryCounts une fois pour chaque événement de récupération sur cet enregistrement.

writeFinalReport produit execution/quick-mode-final-report.md : un décompte des enregistrements importés avec récupération déterministe plus une ventilation par code de récupération, afin que l'opérateur obtienne un compte compact et actionnable au lieu d'un simple décompte de skips. Il ajoute une section « Collections non migrées » depuis summary.excludedCollections, une section « Produits à vérifier » depuis summary.writtenUnverified.product et un pointeur d'inventaire quand summary.inventory est défini. Avec { dryRun: true } il écrit execution/dry-run-final-report.md à la place et définit summary.finalReport sur ce chemin, afin qu'un dry run ne puisse jamais écraser ou remplacer le rapport live. Un dry run ne doit écrire aucun artefact live (rapport, ledger, log d'audit, crosswalk ou marqueur) ; les adaptateurs ignorent ces écritures quand dryRun est true. writeFileAtomic (fichier temporaire, puis renommage) est la façon partagée de publier un rapport qu'un crash ne doit pas laisser demi-écrit.

lib/import-progress.js contient trois autres pièces partagées. L'import de chaque adaptateur appelle d'abord assertQuickImportAdapter, qui échoue à moins que le plan et le manifest d'extraction ne portent exactement le contrat chargé { id, version, fingerprint }. Il appelle ensuite writeQuickImportStartedMarker(projectDir, plan.adapter) avant sa première écriture en destination. Il est ignoré en dry run et jamais réécrit à la reprise ; les tentatives initiales concurrentes publient un marqueur (fichier temporaire, puis un hard link sans remplacement). Il écrit state/quick-import-started.json, que le router lit comme preuve d'une importation interrompue. validateQuickExecutionManifest est la vérification du router du manifest que plan écrit.

Skills similaires