Launch playbook — integration roadmap
The wizard's "Generate Shopify store" flow ships a structured launch playbook (29 milestones, 19 automated + 10 human checkpoints, across 8 sections) defined in src/features/ai/chat/runtime/wizard/launch-playbook.ts…
The wizard's "Generate Shopify store" flow ships a structured
launch playbook (29 milestones, 19 automated + 10 human checkpoints,
across 8 sections) defined in
src/features/ai/chat/runtime/_wizard/launch-playbook.ts. The
POST /api/wizard/store/launch endpoint persists onboarding spec
- brand kit to
StoreContext.modules(and feeds the memory layer withbrand.*/store.*StoreFacts), then emits onePlatformActivityrow per milestone.
Périmètre (re-cadrage juin 2026) : ce playbook prépare LA BOUTIQUE (« prête à vendre à +90 % » dès l'onboarding). Le marketing continu (flux emails, créatives pub) et l'analytics (pixels GA4/Meta/TikTok, CAPI) sont volontairement HORS playbook : pilotés ailleurs par les agents après le go-live. Les actions que Shopify interdit au custom app (KYC paiement, install d'apps tierces via OAuth marchand, publication) sont des étapes humaines guidées (cf. plus bas).
Execution is AUTONOMOUS since June 2026 : the launch-tick cron
(every 10 min, /api/cron/launch-tick) walks each launching store's
dependsOn DAG and dispatches ready milestones through the shared
runner (src/features/ai/wizard-skills/run-milestone.ts). The
cockpit's "Run now" button (POST /api/wizard/skill/run) uses the
same runner for operator-triggered execution. Milestones whose skill
has no executor yet count as satisfied for DAG purposes (they stay
visibly queued) so they never deadlock implemented downstream work.
This doc tracks what's wired vs what's pending.
Skill executors
Each milestone's skill field names a function in
src/features/ai/wizard-skills/registry.ts.
Automated — câblés (✅)
| Skill id | Notes |
|---|---|
theme-installer | Marco — optional themeCreate from spec.themeUrl (allowlisted zip hosts, unpublished) + brand palette onto MAIN theme settings_data.json via themeFilesUpsert |
product-seeder | Marco — 6 AI products via GraphQL productSet, DRAFT, tag boostecom-seed (idempotent) |
collection-seeder | Marco — smart "New Arrivals" + 3-5 AI thematic collections, idempotent by handle |
page-seeder | Marco — About / Contact / FAQ / Shipping & Returns / Size / Care as DRAFT pages |
menu-builder | Marco — main + footer via GraphQL menuUpdate/menuCreate, non-destructive merge |
blog-writer | Marco — "Journal" blog + 3 unpublished launch articles |
legal-doc-generator | Sam — 5 policy pages as Shopify Pages DRAFT |
seo-meta-writer | Marco — top 20 products, title_tag + description_tag metafields |
structured-data-wiring | Platform — Organization + WebSite JSON-LD into MAIN theme <head> |
pricing-strategist | Faye — advisory pricing, persisted to StoreContext.modules.recommendations.pricing (no mutation) |
accessibility-audit | Marco — fills missing product-image alt text (REST products/*/images), additive + idempotent ; never rewrites theme markup |
webhook-wiring | Platform — registers commerce webhooks (orders/products/customers/app-uninstalled) → /api/webhooks/shopify/events (REST, idempotent) |
Automated — à écrire, Phase 2 (🔧 API Admin disponible)
Vérifier la mutation exacte + le gating de plan via
@shopify/dev-mcpavant chaque implémentation. Tous idempotents,throw→ retry géré par le runner.
| Skill id | API Shopify (à confirmer) | Notes |
|---|---|---|
preferences-configurator | checkoutBrandingUpsert (gating Plus ?) | Branding checkout + cartes cadeaux ; honnête sur les limites |
crawl-surface-builder | themeFilesUpsert (robots.txt.liquid) | Risqué — un robots.txt erroné peut désindexer ; vérif dev-mcp obligatoire |
consent-native | Customer Privacy / réglages | Bandeau cookies natif (prérequis RGPD UE) |
markets-configurator | marketCreate + marketWebPresenceCreate | Pays / devises / langues |
tax-configurator | Shopify Tax (largement auto via Markets) | Pose les régions taxables |
shipping-configurator | deliveryProfile* | Zones + tarif forfait + seuil livraison gratuite (carrier-calc différé) |
search-configurator | metafields/metaobjects Search & Discovery | Fragile — à valider, sinon différer |
accessibility-auditetwebhook-wiringsont désormais câblés (voir tableau « câblés » ci-dessus), ils ne nécessitaient pas de vérification dev-mcp (REST stable, mutations additives non destructives).
Human — étapes guidées (🧍)
Shopify interdit ces actions au custom app. Le runner les refuse (
human_required) ; elles portent unguide(instructions + deep linkhttps://{shopDomain}/admin{deepLinkPath}+ sonde d'auto-détection optionnelle). Le cronlaunch-tick(passe 3) sondeshop.jsonet passepending → approvedtout seul quand c'est détectable ; sinon bouton manuel « Mark done ». VoirPOST /api/wizard/store/checkpoint.
| Skill (sentinelle) | Auto-détection | Notes |
|---|---|---|
human-confirm-domain | domain-connected | DNS / achat domaine |
human-confirm-plan | plan-selected | Plan Shopify payant |
human-confirm-payments | — (manuel) | KYC bancaire — non détectable par API |
human-approve-legal | — (manuel) | Relire + approuver les brouillons (dépend de legal-doc-generator) |
human-confirm-publish | store-published | Retrait page mot de passe (dépend domain+payments+legal) |
human-install-reviews | — (manuel) | Judge.me — OAuth marchand |
human-install-apps | — (manuel) | App stack recommandé — OAuth marchand |
human-enable-backup | — (manuel) | Rewind — OAuth marchand |
human-connect-search-console | — (manuel) | Compte Google du marchand (optionnel) |
human-setup-support | — (manuel) | Shopify Inbox + retours self-serve |
Retiré du playbook (❌ géré ailleurs)
klaviyo-installer, welcome-flow-author, abandoned-cart-flow,
postpurchase-flow, winback-flow (flux emails) ; pixels-installer,
event-mapping, capi-installer (analytics) ; créative pub. → Pilotés
par les agents après le go-live, hors wizard turnkey.
Adding a new executor :
- Drop a new file under
src/features/ai/wizard-skills/exporting aSkillExecutor(seetypes.tsfor the contract). Shared Admin API plumbing lives inshopify-admin.ts(REST + GraphQL + idempotent page upsert). - Register it in
src/features/ai/wizard-skills/registry.ts. - The shared runner picks it up automatically: both the cockpit button and the launch-tick cron dispatch it on the next pass.
Turnkey provisioning + ownership transfer (dev-store pool)
Full architecture : docs/architecture/store-provisioning.md.
The short version — Shopify's public Partner API has NO mutation to create dev stores or transfer ownership (both are Dev Dashboard UI operations ; the transfer invite is accepted by email within 7 days and the new owner picks a paid plan). The production design is a PRE-PROVISIONED POOL :
- Ops creates dev stores at dev.shopify.com, installs the BoostEcom
custom app on each, registers them via
POST /api/admin/devstore-pool(token verified + encrypted). POST /api/wizard/store/provisionclaims an AVAILABLE row atomically → Store.domain + active IntegrationConnection land in milliseconds → the launch-tick cron starts populating immediately.POST /api/wizard/store/transferflips the row to TRANSFER_REQUESTED + alerts ops (email + admin surface) ; ops triggers the actual transfer in the Dev Dashboard.- The launch-tick cron DETECTS acceptance by polling shop.json
plan_namethrough the pool token (dev stores report "partner_test"/"affiliate" ; a real plan means the owner accepted) → row TRANSFERRED + congrats email with the cockpit URL. Invite expiry (7 days) falls the row back to CLAIMED for re-request. - The ops-installed custom app SURVIVES the transfer → the IntegrationConnection keeps working for the new owner: zero re-authorization, the dashboard is live the second they accept.
Vercel ENV — cron auth
The cron jobs scheduled in vercel.json (launch-tick,
intelligence-tick, monthly-credits-reset, etc.) authenticate via
CRON_SECRET. If this env var is missing they log
cron.<name>.missing_secret and skip.
Fix : Vercel project → Settings → Environment Variables → add
CRON_SECRET set to a 32+ char random string (openssl rand -hex 32), check Production + Preview + Development, save.
Vercel auto-redeploys, the cron jobs pick up the new env on the
next tick.