Replace all ~1,086 occurrences of Wizamart/wizamart/WIZAMART/WizaMart with Orion/orion/ORION across 184 files. This includes database identifiers, email addresses, domain references, R2 bucket names, DNS prefixes, encryption salt, Celery app name, config defaults, Docker configs, CI configs, documentation, seed data, and templates. Renames homepage-wizamart.html template to homepage-orion.html. Fixes duplicate file_pattern key in api.yaml architecture rule. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
9.7 KiB
Shop Frontend Troubleshooting
Common issues and solutions for the store shop frontend.
Cart and Product Issues
Products Cannot Be Added to Cart
Symptoms:
- "Add to Cart" button is disabled
- No response when clicking "Add to Cart"
- Console shows
canAddToCart: false
Root Cause:
Products have available_inventory: 0 because the inventory table is empty.
How it Works:
- Product's
available_inventoryis a calculated property - It sums
quantity - reserved_quantityfrom allinventory_entries - If there are no inventory entries,
available_inventory= 0 - The
canAddToCartcheck fails whenavailable_inventory <= 0
Solution:
# Create inventory entries for all products
python scripts/create_inventory.py
This script:
- Finds all products without inventory entries
- Creates inventory with 100 units in "Main Warehouse"
- Can be run multiple times (only creates missing entries)
Verify Fix:
# Check a product's inventory
from app.core.database import SessionLocal
from models.database.product import Product
db = SessionLocal()
product = db.query(Product).first()
print(f"Available inventory: {product.available_inventory}")
# Should show: Available inventory: 100
Cart is Empty After Adding Products
Symptoms:
- Success toast appears: "1 item(s) added to cart!"
- Cart count in header doesn't update
- Cart page shows 0 items
- Console shows
session_1234_abcbut API returns empty cart
Root Cause: Session ID not properly initialized in Alpine.js components.
How it Works:
- Cart uses session ID stored in localStorage as
cart_session_id shopLayoutData()base component initializessessionIdin itsinit()method- Child components (product, cart) must call parent
init()to getsessionId - If parent init isn't called,
sessionIdisundefined
Solution Already Implemented: The product and cart pages now properly call parent init:
// In product.html and cart.html
async init() {
// Call parent init to set up sessionId
if (baseData.init) {
baseData.init.call(this);
}
// Now sessionId is available
await this.loadCart();
}
Verify Fix: Open browser console and check for:
🔍 [SHOP] Session ID: session_1763765104510_zc866tt5d
If you see undefined, the parent init isn't being called properly.
Styling and Layout Issues
Page Has No Styling / CSS 404 Errors
Symptoms:
- Page displays with no styling
- Console shows 404 errors:
/static/css/shared/base.cssnot found/static/css/store/store.cssnot found
- Page is just plain HTML
Root Cause:
Template doesn't extend shop/base.html and has hardcoded non-existent CSS references.
How it Works:
- All shop pages should extend
shop/base.html - Base template includes Tailwind CSS and shop styles
- Standalone HTML pages with
<link>tags won't work
Solution: Refactor template to extend base:
{# BEFORE: Standalone HTML #}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/static/css/shared/base.css"> ❌
</head>
<body>
<!-- content -->
</body>
</html>
{# AFTER: Extends base #}
{% extends "shop/base.html" %}
{% block title %}My Page{% endblock %}
{% block alpine_data %}myComponent(){% endblock %}
{% block content %}
<!-- content -->
{% endblock %}
Templates Already Fixed:
- ✅
shop/product.html- Refactored to extend base - ✅
shop/cart.html- Refactored to extend base - ✅
shop/products.html- Already extends base - ✅
shop/home.html- Already extends base
Images Not Loading / Placeholder Not Showing
Symptoms:
- Product images show broken image icon
- Console shows 404:
/static/shop/img/placeholder.jpg - OR images point to fake URLs like
https://orion.example.com/images/product-1.jpg
Root Cause:
- Test data has fake image URLs
- Placeholder file was
.jpgbut contained SVG content
How it Works:
- Products have
marketplace_product.image_linkURLs - Template uses fallback:
:src="image || '/static/shop/img/placeholder.svg'" @errorhandler switches to placeholder when image fails to load- Browsers won't render SVG content from
.jpgfiles
Solution Already Implemented:
- Created proper
/static/shop/img/placeholder.svg - Added
@errorhandlers to all image tags:
<img
:src="product.image_link || '/static/shop/img/placeholder.svg'"
@error="$el.src = '/static/shop/img/placeholder.svg'"
alt="Product image"
>
Update Test Data (Optional):
# Replace fake URLs with real placeholder images
import sqlite3
conn = sqlite3.connect('orion.db')
cursor = conn.cursor()
cursor.execute("""
UPDATE marketplace_products
SET image_link = NULL
WHERE image_link LIKE '%example.com%'
""")
conn.commit()
Navigation and Routing Issues
Product Detail Page Returns 404
Symptoms:
- Clicking product shows 404 error
- URL is:
/stores/orion/shop/shop/products/4(double/shop/) - Server log shows route not found
Root Cause:
Duplicate /shop prefix in route definitions when router already has prefix.
How it Works:
# Router is mounted with prefix
app.include_router(shop_pages.router, prefix="/shop")
# Route decorator should NOT repeat the prefix
@router.get("/products/{id}") # ✅ Correct
@router.get("/shop/products/{id}") # ❌ Wrong - creates /shop/shop/products/{id}
Solution Already Implemented:
All routes in shop_pages.py have been fixed to remove duplicate /shop/ prefix.
Missing /shop/ in Links
Symptoms:
- Links go to
/stores/orion/productsinstead of/stores/orion/shop/products - 404 errors on navigation
- Footer/header links broken
Root Cause:
Template links missing /shop/ prefix after {{ base_url }}.
Solution:
{# WRONG #}
<a href="{{ base_url }}products">Products</a>
{# CORRECT #}
<a href="{{ base_url }}shop/products">Products</a>
All Templates Fixed:
- ✅
shop/base.html- Header, footer, navigation - ✅
shop/products.html- Product links - ✅
shop/product.html- Breadcrumbs, related products - ✅
shop/cart.html- Continue shopping, checkout - ✅
shop/errors/404.html- All fallback links
Landing Page Issues
Store Root Shows 404
Symptoms:
http://localhost:8000/stores/orion/returns 404/path not found
Root Cause: No landing page created for store.
How it Works:
# Root handler checks for landing page
if has_landing_page():
return render_landing_page()
else:
return redirect("/shop/") # Fallback
Solution:
# Create landing page
python scripts/create_landing_page.py
# Choose store and template
Or Accept Redirect:
The system auto-redirects to /shop/ if no landing page exists. This is normal behavior.
Breadcrumb "Home" Points to Wrong Place
Symptoms:
- Clicking "Home" in breadcrumb goes to shop instead of landing page
- Want "Home" to point to store root (/)
Solution Already Implemented:
{# Breadcrumb Home link points to store root #}
<a href="{{ base_url }}">Home</a>
{# Shop homepage link #}
<a href="{{ base_url }}shop/">Shop</a>
Navigation pattern:
- Logo click →
/shop/(stays in shop for convenience) - Breadcrumb "Home" →
/(returns to landing page/root) - Header "Home" link →
/(returns to landing page/root)
Alpine.js / JavaScript Issues
Component Data Not Available
Symptoms:
this.sessionIdisundefinedthis.cartCountdoesn't work- Console: "Cannot read property of undefined"
Root Cause:
Child component doesn't call parent init() method.
Solution:
// Store reference to parent
const baseData = shopLayoutData();
return {
...baseData,
// Child properties
items: [],
// Call parent init
async init() {
if (baseData.init) {
baseData.init.call(this);
}
// Now parent properties are initialized
await this.loadData();
}
};
Product ID is Undefined
Symptoms:
- API call:
/api/v1/shop/products/undefined - Console:
productId: undefined
Root Cause:
Product ID not accessible from this.$el.dataset when x-data is on <html> tag.
Solution Already Implemented: Pass via window globals:
{% block extra_scripts %}
<script>
window.PRODUCT_ID = {{ product_id }};
window.STORE_ID = {{ store.id }};
Alpine.data('productDetail', () => ({
productId: window.PRODUCT_ID,
storeId: window.STORE_ID,
// ...
}));
</script>
{% endblock %}
Debugging Tips
Enable Verbose Logging
// In shop-layout.js, the shopLog is already configured
// Check browser console for:
🛒 [SHOP] Shop layout initializing...
🔍 [SHOP] Session ID: session_xxx
[SHOP] Adding to cart: {...}
[SHOP] Cart loaded: 3 items
Check Session ID
// In browser console
localStorage.getItem('cart_session_id')
// Should show: "session_1763765104510_zc866tt5d"
Inspect Product Data
// In browser console on product page
Alpine.$data(document.querySelector('[x-data]')).product
// Shows full product object with inventory
Check API Responses
In browser Network tab, filter by "shop" and check:
- GET
/api/v1/shop/products- Should return products array - GET
/api/v1/shop/cart/{session_id}- Should return cart items - POST
/api/v1/shop/cart/{session_id}/items- Should return success
Getting Help
- Check this guide first
- Check browser console for errors
- Check server logs for API errors
- Verify database has inventory entries
- Ensure all templates extend
shop/base.html - Check that session ID is initialized
If still stuck, provide:
- Browser console output
- Server log excerpt
- Network tab showing failed requests
- Steps to reproduce