Files
manoon-headless/MIGRATION_GUIDE.md
Unchained 7b94537670 feat(saleor): Phase 1 - GraphQL Client Setup
- Add Apollo Client for Saleor GraphQL API
- Create GraphQL fragments (Product, Variant, Checkout)
- Create GraphQL queries (Products, Checkout)
- Create GraphQL mutations (Checkout operations)
- Add TypeScript types for Saleor entities
- Add product helper functions
- Install @apollo/client and graphql dependencies

Part of WordPress/WooCommerce → Saleor migration
2026-03-21 12:36:21 +02:00

272 lines
7.3 KiB
Markdown

# WooCommerce to Saleor Migration Guide
## Migration Summary
| Component | Status | Notes |
|-----------|--------|-------|
| **Products** | ✅ Complete | 4 products with variants, SKUs, pricing (RSD) |
| **Assets** | ✅ Complete | 204 files migrated to organized folders |
| **Inventory** | ✅ Complete | track_inventory=false, stock records added |
| **Translations** | ✅ Complete | English translations added |
| **Users** | ⏳ Ready | **4,886 total** (1,172 with orders + 2,714 prospects) |
| **Orders** | ⏳ Ready | 1,786 COD orders |
---
## 1. Product Migration (DONE)
Products migrated with:
- SKUs mapped directly
- Prices in RSD (Serbian Dinar)
- Published status
- Channel listings configured
- Inventory settings: `track_inventory=false`
### Product SKU Mapping
| WooCommerce SKU | Saleor SKU | Product |
|----------------|------------|---------|
| morning-glow | MORNING-GLOW-50ML | Morning Glow |
| hair-elixir | HAIR-ELIXIR-30ML | Hair Elixir |
| anti-age-serum | ANTI-AGE-SERUM-30ML | Anti-age Serum |
| luksuzni-set | LUK-SU-ZNI-SET | Luksuzni Set |
---
## 2. Asset Migration (DONE)
All 204 assets organized in MinIO `saleor` bucket:
```
saleor/
├── brand/ (36 files) - Logos, partner badges
├── marketing/ (133 files) - Before/after, testimonials
├── content/ (26 files) - Blog images
└── products/ (9 files) - Product photos
```
**CDN Base URL:** `https://minio-api.nodecrew.me/saleor/`
---
## 3. Customer & Order Migration Strategy
### Customer Analysis
| Category | Count | Description |
|----------|-------|-------------|
| **Total WordPress Users** | 4,886 | All registered accounts |
| **With Orders** | 1,172 | Actually purchased something |
| **Without Orders** | 2,714 | Abandoned carts, newsletter signups |
| **Guest Orders** | 144 | No account, email only |
| **TOTAL REAL CUSTOMERS** | **1,274** | Unique emails from orders |
### Why Migrate All 4,886 Users?
The 2,714 users without orders are valuable for:
- **Abandoned cart recovery** - They started but didn't finish
- **Newsletter subscribers** - Already interested in brand
- **Reactivation campaigns** - Win back potential customers
- **Lookalike audiences** - For Meta/Google ads
### Customer Segmentation
During migration, users are automatically segmented:
| Segment | Criteria | Count (Est.) | Strategy |
|---------|----------|--------------|----------|
| **VIP_CUSTOMER** | 3+ completed orders | ~200 | Loyalty program, early access |
| **ACTIVE_CUSTOMER** | 1-2 completed orders | ~972 | Cross-sell, subscription |
| **CART_ABANDONER** | Pending/processing orders | ~1,086 | Recovery sequence |
| **PROSPECT** | No orders | ~2,628 | Welcome series, education |
---
## 4. Migration Scripts
### Available Scripts
| Script | Purpose | Use When |
|--------|---------|----------|
| `migrate_all_users_and_orders.py` | **Complete migration** (recommended) | You want all users + segmentation |
| `migrate_cod_orders.py` | Orders only (no user creation) | Quick order migration only |
| `migrate_guest_orders.py` | Alternative guest checkout | Legacy option |
### Recommended: Complete Migration
```bash
# Set environment variables
export WP_DB_HOST=doorwayftw
export WP_DB_USER=DUjqYuqsYvaGUFV4
export WP_DB_PASSWORD=voP0UzecALE0WRNJQcTCf0STMcxIiX99
export SALEOR_DB_HOST=doorwayftw
export SALEOR_DB_USER=saleor
export SALEOR_DB_PASSWORD=<get-from-k8s-secret>
# Preview (dry run)
python scripts/migrate_all_users_and_orders.py --users --orders --dry-run
# Migrate specific segment
python scripts/migrate_all_users_and_orders.py --users --segment VIP_CUSTOMER
# Full migration
python scripts/migrate_all_users_and_orders.py --users --orders
```
### Migration by Segments (Phased Approach)
**Phase 1: VIP & Active Customers** (Lowest risk)
```bash
python scripts/migrate_all_users_and_orders.py \
--users --segment VIP_CUSTOMER --orders --limit-orders 100
```
**Phase 2: Cart Abandoners** (Medium value)
```bash
python scripts/migrate_all_users_and_orders.py \
--users --segment CART_ABANDONER --orders
```
**Phase 3: Prospects** (Reactivation focus)
```bash
python scripts/migrate_all_users_and_orders.py \
--users --segment PROSPECT
```
---
## 5. Post-Migration: Email Reactivation Campaigns
See `EMAIL_REACTIVATION_CAMPAIGNS.md` for complete strategy.
### Quick Summary
| Campaign | Target | Goal |
|----------|--------|------|
| **Cart Recovery** | 1,086 abandoners | 10-15% conversion |
| **Welcome Series** | 2,628 prospects | 5-8% first order |
| **Win-Back** | Inactive customers | 3-5% reactivation |
| **VIP Program** | 200 top customers | Loyalty + referrals |
### Campaign Templates Included
- Cart recovery (3 emails)
- Welcome series (4 emails)
- Win-back sequence (2 emails)
- VIP perks announcement
### Technical Setup
Segmentation data stored in user metadata:
```json
{
"segment": "CART_ABANDONER",
"wp_user_id": 12345,
"order_count": 1,
"completed_orders": 0,
"total_spent": 0,
"registration_date": "2022-11-20T13:42:19"
}
```
Export for email platform:
```sql
-- Get all PROSPECTS for welcome campaign
SELECT email, first_name, metadata->>'registration_date'
FROM account_user
WHERE metadata->>'segment' = 'PROSPECT';
```
---
## 6. COD Payment Handling
Since Manoon uses Cash on Delivery:
### Status Mapping
| WC Status | Saleor Status | Payment |
|-----------|---------------|---------|
| `wc-pending` | `UNCONFIRMED` | Unpaid |
| `wc-processing` | `UNFULFILLED` | Unpaid |
| `wc-completed` | `FULFILLED` | ✅ Paid (COD collected) |
| `wc-cancelled` | `CANCELED` | Unpaid |
### Payment Records
For completed orders, a dummy payment record is created:
- Gateway: `mirumee.payments.dummy`
- Status: `FULLY_CHARGED`
- Amount: Order total
This allows reporting and analytics to work correctly.
---
## 7. Data Transformations
| Field | WooCommerce | Saleor |
|-------|-------------|--------|
| **Prices** | Decimal (115.00) | Integer cents (11500) |
| **Tax Rate** | Calculated | Fixed 15% (Serbia VAT) |
| **Status** | wc-* strings | Saleor workflow states |
| **Origin** | Various | `BULK_CREATE` |
| **Passwords** | WP hashed | `!` (unusable, reset required) |
---
## 8. Verification Checklist
After migration:
- [ ] User count matches: 4,886
- [ ] Order count matches: 1,786
- [ ] Segments correctly assigned
- [ ] LTV calculated for each customer
- [ ] Order totals are correct (cents)
- [ ] Completed orders have payment records
- [ ] Addresses formatted correctly
- [ ] SKUs link to correct products
---
## 9. Rollback Plan
If needed:
```sql
-- Delete imported data
DELETE FROM order_order WHERE metadata->>'origin' = 'BULK_CREATE';
DELETE FROM account_user WHERE id IN (
SELECT saleor_user_id FROM wc_complete_user_mapping
);
-- Drop mapping tables
DROP TABLE wc_complete_user_mapping;
DROP TABLE wc_order_mapping;
```
---
## 10. Next Steps
1. ✅ Run migration preview: `--dry-run`
2. ✅ Verify counts match expectations
3. ✅ Run Phase 1 (VIP customers)
4. ✅ Set up email platform (Mautic/MailerLite/Mailchimp)
5. ✅ Import segments into email platform
6. ✅ Launch cart recovery campaign
7. ✅ Launch welcome series for prospects
8. ✅ Monitor conversion rates
9. ✅ Optimize campaigns based on data
---
## Support
For issues:
1. Check Saleor logs: `kubectl logs -n saleor deployment/saleor-api`
2. Run with `--dry-run` first
3. Check mapping tables for progress
4. Review `EMAIL_REACTIVATION_CAMPAIGNS.md` for marketing setup