Files
manoon-headless/ecommerce-features-checklist.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

461 lines
12 KiB
Markdown

# 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