diff --git a/docs/parallel-migration.md b/docs/parallel-migration.md new file mode 100644 index 0000000..a65911a --- /dev/null +++ b/docs/parallel-migration.md @@ -0,0 +1,120 @@ +# Parallel Migration Guide + +Run your sovereign stack alongside Shopify during migration — no cutover risk, no forced downtime. + +## Overview + +Five phases: + +1. **Deploy** — Stand up the NotShop bundle (Replit + Fly.io) +2. **Mirror** — Import your product catalog from Shopify Storefront API +3. **Route** — Send a small percentage of traffic to your sovereign stack +4. **Validate** — Confirm orders, payments, and customer accounts work correctly +5. **Cut over** — Move all traffic; cancel Shopify + +Customers always hit one URL. The Fly.io routing layer handles the split transparently. + +--- + +## Phase 1: Deploy + +### 1.1 Fork and deploy to Replit + +1. Fork [git.wellspr.ing/WellBuilder/notshop-bundle](https://git.wellspr.ing/WellBuilder/notshop-bundle) +2. Import into Replit (New Repl → Import from Git) +3. Add environment variables in the Secrets tab (see `.env.example`) +4. Click Run — storefront starts on your Replit domain + +### 1.2 Deploy the Fly.io routing proxy + +```bash +flyctl auth login +flyctl launch --copy-config --name yourstore-proxy +flyctl secrets set SHOPIFY_ORIGIN=https://yourstore.myshopify.com +flyctl secrets set SOVEREIGN_ORIGIN=https://yourrepl.replit.app +flyctl secrets set SOVEREIGN_WEIGHT=0 +flyctl deploy +``` + +### 1.3 Point your domain to Fly + +Update DNS (Bunny.net recommended) to CNAME your domain to the Fly.io app: + +``` +yourstore.com CNAME yourstore-proxy.fly.dev +``` + +At this point 100% of traffic still routes to Shopify. Your sovereign stack is deployed but idle. + +--- + +## Phase 2: Mirror — import product catalog + +```bash +npm run catalog:import +``` + +Pulls products, variants, and collections from the Shopify Storefront API into your PostgreSQL database. +See [storefront-api.md](storefront-api.md) for token setup. + +Re-run anytime to sync changes. For real-time sync, configure the webhook bridge (`server/webhook-bridge.ts`). + +--- + +## Phase 3: Route — split traffic + +Once the catalog is imported and the storefront renders correctly: + +```bash +flyctl secrets set SOVEREIGN_WEIGHT=10 # 10% to sovereign, 90% to Shopify +flyctl deploy +``` + +The proxy assigns a session cookie on first visit so each visitor stays on the same backend for their entire session. + +Ramp gradually: 10 → 25 → 50 → 90 → 100. Each step is a 30-second Fly.io deploy. + +--- + +## Phase 4: Validate + +While traffic is split: + +- **Orders** — Check `/admin` for successful orders +- **Payments** — Confirm Authorize.net transactions in your Authorize.net control panel +- **Checkout flow** — Go through checkout yourself +- **Customer accounts** — Test account creation and login + +--- + +## Phase 5: Cut over + +```bash +flyctl secrets set SOVEREIGN_WEIGHT=100 +flyctl deploy +``` + +All traffic now goes to your sovereign stack. Then: + +1. Cancel Shop Campaigns (if not already paused — do this first) +2. Export order history from Shopify Admin as CSV +3. Downgrade from Shopify Plus (requires notice period per your contract) + +--- + +## Timeline + +Most merchants complete migration in 2–4 weeks: + +| Week | Work | +|---|---| +| 1 | Deploy, mirror catalog, validate storefront | +| 2 | Route 10% traffic, monitor orders | +| 3 | Ramp to 50%, tune any issues | +| 4 | Cut over to 100%, cancel Shopify | + +--- + +## Support + +Questions: [notshop.org/report](https://notshop.org/report) or open an issue in this repository.