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
This commit is contained in:
460
ecommerce-features-checklist.md
Normal file
460
ecommerce-features-checklist.md
Normal file
@@ -0,0 +1,460 @@
|
||||
# Advanced E-Commerce Features Checklist
|
||||
|
||||
## Saleor Built-in vs Missing Features
|
||||
|
||||
### ✅ Built-in (Ready to Use)
|
||||
|
||||
| Feature | Saleor Support | Notes |
|
||||
|---------|---------------|-------|
|
||||
| **Products & Variants** | ✅ Native | Simple & variable products |
|
||||
| **Categories** | ✅ Native | Hierarchical with nesting |
|
||||
| **Collections** | ✅ Native | Manual & automated collections |
|
||||
| **Inventory** | ✅ Native | Multi-warehouse support |
|
||||
| **Multi-language** | ✅ Native | Full translation support |
|
||||
| **Multi-currency** | ✅ Native | Per-channel pricing |
|
||||
| **Promotions** | ✅ Native | % off, fixed amount, vouchers |
|
||||
| **Gift Cards** | ✅ Native | Digital gift cards |
|
||||
| **Taxes** | ✅ Native | Per-country tax rates |
|
||||
| **Shipping** | ✅ Native | Zones & methods |
|
||||
| **Customer Accounts** | ✅ Native | Full account management |
|
||||
| **Order Management** | ✅ Native | Status tracking, fulfillments |
|
||||
| **Staff Permissions** | ✅ Native | Role-based access |
|
||||
| **Pages & Menus** | ✅ Native | CMS features |
|
||||
| **Checkout** | ✅ Native | Customizable flow |
|
||||
| **Payments** | ✅ Native | Stripe, Adyen, etc. |
|
||||
|
||||
---
|
||||
|
||||
## ❌ Missing Features (Need to Build/Add)
|
||||
|
||||
### 1. Product Reviews ⭐ HIGH PRIORITY
|
||||
|
||||
**Status:** NOT in Saleor (on roadmap but not planned)
|
||||
|
||||
**Solutions:**
|
||||
| Solution | Cost | Effort | Best For |
|
||||
|----------|------|--------|----------|
|
||||
| **Judge.me** | Free-$15/mo | 2 hours | Budget option, works well |
|
||||
| **Trustpilot** | $200+/mo | 2 hours | SEO, brand trust |
|
||||
| **Yotpo** | $300+/mo | 4 hours | Enterprise, UGC |
|
||||
| **Build Custom** | Free | 2-4 weeks | Full control |
|
||||
|
||||
**Custom Build SQL:**
|
||||
```sql
|
||||
CREATE TABLE product_review (
|
||||
id SERIAL PRIMARY KEY,
|
||||
product_id INTEGER REFERENCES product_product(id),
|
||||
user_id INTEGER REFERENCES account_user(id),
|
||||
rating INTEGER CHECK (rating >= 1 AND rating <= 5),
|
||||
title VARCHAR(255),
|
||||
comment TEXT,
|
||||
is_verified_purchase BOOLEAN DEFAULT false,
|
||||
is_approved BOOLEAN DEFAULT false,
|
||||
helpful_count INTEGER DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Upsells & Cross-sells ⭐ HIGH PRIORITY
|
||||
|
||||
**Status:** NOT in Saleor (confirmed missing)
|
||||
|
||||
**What You Need:**
|
||||
|
||||
```sql
|
||||
-- Related products / upsells table
|
||||
CREATE TABLE product_related (
|
||||
id SERIAL PRIMARY KEY,
|
||||
product_id INTEGER REFERENCES product_product(id),
|
||||
related_product_id INTEGER REFERENCES product_product(id),
|
||||
type VARCHAR(50), -- 'upsell', 'cross_sell', 'related'
|
||||
sort_order INTEGER DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
UNIQUE(product_id, related_product_id, type)
|
||||
);
|
||||
```
|
||||
|
||||
**Types of Upsells:**
|
||||
|
||||
| Type | Example | Location |
|
||||
|------|---------|----------|
|
||||
| **Upsell** | 500ml → 1L (upgrade) | Product page |
|
||||
| **Cross-sell** | Olive oil + vinegar (complementary) | Cart page |
|
||||
| **Related** | Same category products | Product page |
|
||||
| **Bundle** | Oil + vinegar + herbs package | Product page |
|
||||
| **Frequently Bought Together** | AI-based recommendations | Cart page |
|
||||
|
||||
**Implementation Options:**
|
||||
|
||||
#### Option A: Manual (Product-Level)
|
||||
```sql
|
||||
-- Admin manually assigns related products
|
||||
INSERT INTO product_related (product_id, related_product_id, type, sort_order)
|
||||
VALUES
|
||||
(1, 5, 'upsell', 1), -- Product 1 shows Product 5 as upsell
|
||||
(1, 6, 'cross_sell', 1), -- Product 1 shows Product 6 as cross-sell
|
||||
(1, 7, 'related', 1); -- Product 1 shows Product 7 as related
|
||||
```
|
||||
|
||||
**Admin UI Needed:**
|
||||
- Product edit page with "Related Products" section
|
||||
- Search & select products
|
||||
- Drag to reorder
|
||||
- Choose type (upsell/cross-sell/related)
|
||||
|
||||
#### Option B: Automated (Category-Based)
|
||||
```typescript
|
||||
// Automatically show products from same category
|
||||
const getRelatedProducts = async (productId: string, categoryId: string) => {
|
||||
return await saleorClient.query({
|
||||
query: gql`
|
||||
query GetRelatedProducts($categoryId: ID!, $excludeId: ID!) {
|
||||
products(
|
||||
first: 4,
|
||||
filter: {categories: [$categoryId]},
|
||||
channel: "default-channel"
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
slug
|
||||
thumbnail { url }
|
||||
variants {
|
||||
channelListings {
|
||||
price { amount currency }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: { categoryId, excludeId: productId }
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
#### Option C: AI/ML Recommendations (Advanced)
|
||||
Services:
|
||||
- **Recombee** - $99/mo+
|
||||
- **Amazon Personalize** - Pay per use
|
||||
- **Algolia Recommend** - $29/mo+
|
||||
- **Build custom** - Requires order history analysis
|
||||
|
||||
**Effort:** High (4-8 weeks)
|
||||
|
||||
---
|
||||
|
||||
### 3. Product Bundles ⭐ MEDIUM PRIORITY
|
||||
|
||||
**Status:** NOT in Saleor (requested, on roadmap)
|
||||
|
||||
**Example:**
|
||||
- Olive Oil 500ml + Vinegar 250ml = Bundle price $15 (save $3)
|
||||
|
||||
**Custom Implementation:**
|
||||
|
||||
```sql
|
||||
-- Bundle definition
|
||||
CREATE TABLE product_bundle (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(250),
|
||||
slug VARCHAR(255) UNIQUE,
|
||||
description JSONB,
|
||||
product_type_id INTEGER REFERENCES product_producttype(id),
|
||||
bundle_price_amount NUMERIC(20,3),
|
||||
currency VARCHAR(3),
|
||||
is_active BOOLEAN DEFAULT true,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Bundle items
|
||||
CREATE TABLE product_bundle_item (
|
||||
id SERIAL PRIMARY KEY,
|
||||
bundle_id INTEGER REFERENCES product_bundle(id),
|
||||
product_variant_id INTEGER REFERENCES product_productvariant(id),
|
||||
quantity INTEGER DEFAULT 1,
|
||||
sort_order INTEGER DEFAULT 0
|
||||
);
|
||||
```
|
||||
|
||||
**Storefront Display:**
|
||||
```typescript
|
||||
// Show bundle on product page
|
||||
<ProductBundle
|
||||
bundle={{
|
||||
name: "Mediterranean Starter Pack",
|
||||
items: [
|
||||
{ name: "Olive Oil 500ml", price: 12 },
|
||||
{ name: "Balsamic Vinegar 250ml", price: 6 },
|
||||
],
|
||||
regularPrice: 18,
|
||||
bundlePrice: 15,
|
||||
savings: 3
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Abandoned Cart Recovery ⭐ HIGH PRIORITY
|
||||
|
||||
**Status:** NOT in Saleor
|
||||
|
||||
**Solutions:**
|
||||
1. **Mautic** (FREE - you have it!) - See `mautic-abandoned-cart.md`
|
||||
2. **Klaviyo** - $20-50/mo
|
||||
3. **N8N automation** - FREE
|
||||
|
||||
---
|
||||
|
||||
### 5. Email Marketing ⭐ MEDIUM PRIORITY
|
||||
|
||||
**Status:** NOT in Saleor
|
||||
|
||||
**Solutions:**
|
||||
1. **Mautic** (FREE - you have it!)
|
||||
2. **Klaviyo** - Best for e-commerce
|
||||
3. **Mailchimp** - Good free tier
|
||||
|
||||
**Email Types Needed:**
|
||||
- Welcome email
|
||||
- Order confirmation
|
||||
- Shipping notification
|
||||
- Post-purchase follow-up
|
||||
- Win-back campaign
|
||||
- Birthday discount
|
||||
|
||||
---
|
||||
|
||||
### 6. Loyalty/Rewards Program ⭐ MEDIUM PRIORITY
|
||||
|
||||
**Status:** NOT in Saleor
|
||||
|
||||
**Custom Build:**
|
||||
```sql
|
||||
-- Loyalty points
|
||||
CREATE TABLE loyalty_account (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES account_user(id),
|
||||
points_balance INTEGER DEFAULT 0,
|
||||
lifetime_points INTEGER DEFAULT 0,
|
||||
tier VARCHAR(50) DEFAULT 'bronze', -- bronze, silver, gold
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Points transactions
|
||||
CREATE TABLE loyalty_transaction (
|
||||
id SERIAL PRIMARY KEY,
|
||||
account_id INTEGER REFERENCES loyalty_account(id),
|
||||
points INTEGER, -- positive for earn, negative for redeem
|
||||
type VARCHAR(50), -- 'purchase', 'referral', 'redemption', 'bonus'
|
||||
description TEXT,
|
||||
order_id INTEGER REFERENCES order_order(id),
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Subscription/Recurring Products ⭐ LOW PRIORITY
|
||||
|
||||
**Status:** NOT in Saleor
|
||||
|
||||
**Solutions:**
|
||||
- **Stripe Billing** - Best integration
|
||||
- **Recharge** - $300/mo+ (Shopify-focused)
|
||||
- **Chargebee** - $249/mo+
|
||||
- **Build custom** with Stripe
|
||||
|
||||
---
|
||||
|
||||
### 8. Wishlist/Favorites ⭐ MEDIUM PRIORITY
|
||||
|
||||
**Status:** NOT in Saleor
|
||||
|
||||
**Simple Implementation:**
|
||||
```sql
|
||||
CREATE TABLE wishlist_item (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES account_user(id),
|
||||
product_variant_id INTEGER REFERENCES product_productvariant(id),
|
||||
added_at TIMESTAMP DEFAULT NOW(),
|
||||
UNIQUE(user_id, product_variant_id)
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 9. Recently Viewed Products ⭐ LOW PRIORITY
|
||||
|
||||
**Implementation:**
|
||||
```typescript
|
||||
// Store in localStorage or Redis
|
||||
const trackProductView = (productId: string) => {
|
||||
const recentlyViewed = JSON.parse(localStorage.getItem('recentlyViewed') || '[]');
|
||||
recentlyViewed.unshift(productId);
|
||||
localStorage.setItem('recentlyViewed', JSON.stringify(recentlyViewed.slice(0, 10)));
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 10. Product Comparison ⭐ LOW PRIORITY
|
||||
|
||||
**Implementation:**
|
||||
```typescript
|
||||
// Allow users to compare 2-3 products side-by-side
|
||||
const ProductComparison = ({ products }) => {
|
||||
return (
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Feature</th>
|
||||
{products.map(p => <th key={p.id}>{p.name}</th>)}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Price</td>
|
||||
{products.map(p => <td key={p.id}>${p.price}</td>)}
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Volume</td>
|
||||
{products.map(p => <td key={p.id}>{p.volume}</td>)}
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 11. Quick View (Modal) ⭐ LOW PRIORITY
|
||||
|
||||
**Implementation:**
|
||||
```typescript
|
||||
// Product card with quick view button
|
||||
<ProductCard>
|
||||
<Image src={product.thumbnail} />
|
||||
<h3>{product.name}</h3>
|
||||
<button onClick={() => openQuickView(product.id)}>
|
||||
Quick View
|
||||
</button>
|
||||
</ProductCard>
|
||||
|
||||
// Modal fetches product details
|
||||
<QuickViewModal productId={selectedProductId} />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 12. AJAX Add to Cart (No Page Reload) ⭐ MEDIUM PRIORITY
|
||||
|
||||
**Implementation:**
|
||||
```typescript
|
||||
const AddToCartButton = ({ variantId }) => {
|
||||
const [adding, setAdding] = useState(false);
|
||||
|
||||
const handleAdd = async () => {
|
||||
setAdding(true);
|
||||
await saleorClient.mutate({
|
||||
mutation: ADD_TO_CART,
|
||||
variables: { variantId, quantity: 1 }
|
||||
});
|
||||
setAdding(false);
|
||||
showToast('Added to cart!');
|
||||
updateCartCount(); // Update header cart icon
|
||||
};
|
||||
|
||||
return <button onClick={handleAdd} disabled={adding}>Add to Cart</button>;
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 13. Dynamic Pricing / Volume Discounts ⭐ LOW PRIORITY
|
||||
|
||||
**Example:**
|
||||
- Buy 1: $12
|
||||
- Buy 2: $11 each (save $2)
|
||||
- Buy 3+: $10 each (save $6)
|
||||
|
||||
**Saleor Native:** Not supported
|
||||
|
||||
**Custom:**
|
||||
```typescript
|
||||
const getVolumePrice = (basePrice: number, quantity: number) => {
|
||||
if (quantity >= 3) return basePrice * 0.83; // 17% off
|
||||
if (quantity >= 2) return basePrice * 0.92; // 8% off
|
||||
return basePrice;
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 14. Back in Stock Notifications ⭐ MEDIUM PRIORITY
|
||||
|
||||
**Implementation:**
|
||||
```sql
|
||||
CREATE TABLE stock_notification_request (
|
||||
id SERIAL PRIMARY KEY,
|
||||
email VARCHAR(255),
|
||||
product_variant_id INTEGER REFERENCES product_productvariant(id),
|
||||
is_notified BOOLEAN DEFAULT false,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- When stock is updated, check and send emails
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Recommended Priority Order
|
||||
|
||||
### Phase 1: Essential (Launch)
|
||||
- [x] Saleor core products
|
||||
- [ ] **Reviews** (Judge.me or custom)
|
||||
- [ ] **Upsells/Cross-sells** (manual assignment)
|
||||
- [ ] **AJAX cart**
|
||||
- [ ] **Mautic abandoned cart**
|
||||
|
||||
### Phase 2: Growth (1-3 months post-launch)
|
||||
- [ ] **Email marketing** (Mautic or Klaviyo)
|
||||
- [ ] **Wishlist**
|
||||
- [ ] **Bundles**
|
||||
- [ ] **Recently viewed**
|
||||
|
||||
### Phase 3: Advanced (6+ months)
|
||||
- [ ] **Loyalty program**
|
||||
- [ ] **AI recommendations**
|
||||
- [ ] **Subscriptions**
|
||||
- [ ] **Product comparison**
|
||||
|
||||
---
|
||||
|
||||
## Cost Summary
|
||||
|
||||
| Feature | DIY Build | Third-Party | Recommended |
|
||||
|---------|-----------|-------------|-------------|
|
||||
| Reviews | 2-4 weeks | Judge.me FREE | **Judge.me** |
|
||||
| Upsells | 1-2 weeks | N/A | **Custom** |
|
||||
| Bundles | 2-3 weeks | N/A | **Custom** |
|
||||
| Abandoned Cart | 2-3 days | Klaviyo $20/mo | **Mautic FREE** |
|
||||
| Email Marketing | 1 week | Klaviyo $20/mo | **Mautic FREE** |
|
||||
| Loyalty | 2-3 weeks | Smile.io $199/mo | **Custom later** |
|
||||
| Subscriptions | 4-6 weeks | Recharge $300/mo | **Stripe later** |
|
||||
|
||||
---
|
||||
|
||||
## Total Estimated Dev Time
|
||||
|
||||
**Phase 1:** 4-6 weeks
|
||||
**Phase 2:** 3-4 weeks
|
||||
**Phase 3:** 6-8 weeks
|
||||
|
||||
**Total:** 3-4 months for full-featured store
|
||||
Reference in New Issue
Block a user