refactor: rename Wizamart to Orion across entire codebase

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>
This commit is contained in:
2026-02-14 16:46:56 +01:00
parent 34ee7bb7ad
commit e9253fbd84
184 changed files with 1227 additions and 1228 deletions

View File

@@ -1,6 +1,6 @@
# Code Quality
This guide covers the code quality tools and standards used in the Wizamart platform.
This guide covers the code quality tools and standards used in the Orion platform.
## Overview

Binary file not shown.

View File

@@ -1,6 +1,6 @@
# Creating Modules
This guide explains how to create new **plug-and-play modules** for the Wizamart platform. Modules are fully self-contained and automatically discovered - no changes to framework files required.
This guide explains how to create new **plug-and-play modules** for the Orion platform. Modules are fully self-contained and automatically discovered - no changes to framework files required.
## Quick Start (5 Minutes)
@@ -331,9 +331,9 @@ __all__ = ["mymodule_service", "MyModuleService"]
```python
# app/modules/mymodule/exceptions.py
from app.exceptions import WizamartException
from app.exceptions import OrionException
class MyModuleException(WizamartException):
class MyModuleException(OrionException):
"""Base exception for mymodule."""
pass

View File

@@ -43,7 +43,7 @@ JWT tokens have `type: "customer"` to distinguish them.
# Domain/Subdomain access
cookie_path = "/shop"
# Path-based access (/stores/wizamart/shop)
# Path-based access (/stores/orion/shop)
cookie_path = f"/stores/{store_code}/shop"
```
@@ -68,9 +68,9 @@ cookie_path = f"/stores/{store_code}/shop"
```
# Path-based access
http://localhost:8000/stores/wizamart/shop/account/login
http://localhost:8000/stores/wizamart/shop/account/register
http://localhost:8000/stores/wizamart/shop/account/dashboard
http://localhost:8000/stores/orion/shop/account/login
http://localhost:8000/stores/orion/shop/account/register
http://localhost:8000/stores/orion/shop/account/dashboard
```
## Next Steps (TODO)

View File

@@ -56,9 +56,9 @@ Cookies must be set with paths that match how the store is accessed:
| Access Method | Example URL | Cookie Path |
|--------------|-------------|-------------|
| Domain | `wizamart.com/shop/account/login` | `/shop` |
| Subdomain | `wizamart.localhost/shop/account/login` | `/shop` |
| Path-based | `localhost/stores/wizamart/shop/account/login` | `/stores/wizamart/shop` |
| Domain | `orion.lu/shop/account/login` | `/shop` |
| Subdomain | `orion.localhost/shop/account/login` | `/shop` |
| Path-based | `localhost/stores/orion/shop/account/login` | `/stores/orion/shop` |
This ensures cookies are only sent to the correct store's routes.
@@ -145,7 +145,7 @@ access_method = store_context.get('detection_method', 'unknown') if store_contex
cookie_path = "/shop" # Default for domain/subdomain access
if access_method == "path":
# For path-based access like /stores/wizamart/shop
# For path-based access like /stores/orion/shop
full_prefix = store_context.get('full_prefix', '/store/') if store_context else '/store/'
cookie_path = f"{full_prefix}{store.subdomain}/shop"
@@ -300,30 +300,30 @@ The implementation properly supports all three store access methods:
#### Domain-based Access
```
URL: https://wizamart.com/shop/account/login
URL: https://orion.lu/shop/account/login
Cookie Path: /shop
Cookie Sent To: https://wizamart.com/shop/*
Cookie Sent To: https://orion.lu/shop/*
```
#### Subdomain-based Access
```
URL: https://wizamart.myplatform.com/shop/account/login
URL: https://orion.myplatform.com/shop/account/login
Cookie Path: /shop
Cookie Sent To: https://wizamart.myplatform.com/shop/*
Cookie Sent To: https://orion.myplatform.com/shop/*
```
#### Path-based Access
```
URL: https://myplatform.com/stores/wizamart/shop/account/login
Cookie Path: /stores/wizamart/shop
Cookie Sent To: https://myplatform.com/stores/wizamart/shop/*
URL: https://myplatform.com/stores/orion/shop/account/login
Cookie Path: /stores/orion/shop
Cookie Sent To: https://myplatform.com/stores/orion/shop/*
```
## Authentication Flow
### Login Flow
1. **User loads login page**`GET /stores/wizamart/shop/account/login`
1. **User loads login page**`GET /stores/orion/shop/account/login`
- Middleware detects store from path
- Sets `detection_method = "path"` in store_context
- Renders login template
@@ -337,7 +337,7 @@ Cookie Sent To: https://myplatform.com/stores/wizamart/shop/*
- Sets `customer_token` cookie with correct path
- Returns token + customer data
3. **Browser redirects to dashboard**`GET /stores/wizamart/shop/account/dashboard`
3. **Browser redirects to dashboard**`GET /stores/orion/shop/account/dashboard`
- Browser sends `customer_token` cookie (path matches!)
- Dependency `get_current_customer_from_cookie_or_header` extracts token
- Decodes JWT, validates `type == "customer"`

View File

@@ -1,8 +1,8 @@
# Database Initialization Guide
**Wizamart Platform - Database Management Documentation**
**Orion Platform - Database Management Documentation**
This guide covers the database initialization, seeding, and management workflows for the Wizamart multi-tenant e-commerce platform.
This guide covers the database initialization, seeding, and management workflows for the Orion multi-tenant e-commerce platform.
---
@@ -23,7 +23,7 @@ This guide covers the database initialization, seeding, and management workflows
### Database Initialization Philosophy
The Wizamart platform uses a **two-tier initialization system**:
The Orion platform uses a **two-tier initialization system**:
1. **Production Initialization** (`init_production.py`)
- Creates essential platform infrastructure
@@ -112,7 +112,7 @@ ENVIRONMENT=development # development | staging | production
# =============================================================================
# ADMIN INITIALIZATION
# =============================================================================
ADMIN_EMAIL=admin@wizamart.com
ADMIN_EMAIL=admin@orion.lu
ADMIN_USERNAME=admin
ADMIN_PASSWORD=admin123 # ⚠️ CHANGE IN PRODUCTION!
ADMIN_FIRST_NAME=Platform
@@ -185,7 +185,7 @@ if warnings:
# 1. Configure environment
cat > .env << EOF
ENVIRONMENT=production
DATABASE_URL=postgresql://user:pass@localhost/wizamart
DATABASE_URL=postgresql://user:pass@localhost/orion
ADMIN_EMAIL=admin@yourmerchant.com
ADMIN_USERNAME=admin
ADMIN_PASSWORD=SecurePassword123!
@@ -373,10 +373,10 @@ Edit `scripts/seed/init_production.py` to add new platform settings:
```python
def create_admin_settings(db: Session) -> int:
"""Create essential admin settings."""
default_settings = [
# ... existing settings ...
# Add your new setting
{
"key": "your_new_setting",
@@ -396,13 +396,13 @@ Edit `scripts/seed/seed_demo.py` to extend demo data creation:
```python
def seed_demo_data(db: Session, auth_manager: AuthManager):
"""Seed demo data for development."""
# ... existing steps ...
# Add your new demo data
print_step(7, "Creating your demo data...")
create_your_demo_data(db, stores)
# ... commit
```
@@ -411,7 +411,7 @@ Create a new function for your data:
```python
def create_your_demo_data(db: Session, stores: List[Store]) -> List[YourModel]:
"""Create demo data for your feature."""
items = []
for store in stores:
# Create demo items for this store
@@ -421,7 +421,7 @@ def create_your_demo_data(db: Session, stores: List[Store]) -> List[YourModel]:
)
db.add(item)
items.append(item)
db.flush()
print_success(f"Created {len(items)} demo items")
return items
@@ -436,12 +436,12 @@ Edit `app/core/config.py`:
```python
class Settings(BaseSettings):
# ... existing settings ...
# Your new settings
your_new_setting: str = "default_value"
your_numeric_setting: int = 42
your_boolean_setting: bool = True
# Optional with validation
your_list_setting: List[str] = ["item1", "item2"]
```
@@ -473,7 +473,7 @@ Edit the `DEMO_STORES` list in `scripts/seed/seed_demo.py`:
```python
DEMO_STORES = [
# ... existing stores ...
# Your new demo store
{
"store_code": "YOURSHOP",
@@ -680,7 +680,7 @@ make migrate-status
**Solution**: No action needed. This message confirms the admin user exists.
```
⚠ Admin user already exists: admin@wizamart.com
⚠ Admin user already exists: admin@orion.lu
✓ All changes committed
```
@@ -688,7 +688,7 @@ make migrate-status
**Cause**: Correct behavior - safety feature working
**Solution**:
**Solution**:
- If you're in development: Set `ENVIRONMENT=development` in `.env`
- If you're in production: Don't seed demo data! Create stores via admin panel
@@ -712,7 +712,7 @@ pip list | grep pydantic
**Cause**: Running seed scripts multiple times without checking existence
**Solution**:
**Solution**:
- Use `make seed-demo-reset` for fresh data
- Check scripts for proper idempotent checks
- Verify database state before seeding
@@ -778,7 +778,7 @@ python -c "from app.core.config import settings; print(f'Env: {settings.environm
URL: http://localhost:8000/admin/login
Username: admin
Password: admin123 (⚠️ CHANGE IN PRODUCTION!)
Email: admin@wizamart.com
Email: admin@orion.lu
```
#### Demo Stores (After `make seed-demo`)
@@ -793,7 +793,7 @@ Store 3: store3@example.com / password123
### File Locations
```
wizamart/
orion/
├── .env # Environment configuration
├── Makefile # Command definitions
├── app/
@@ -845,8 +845,8 @@ Complete list of database-related environment variables:
| Variable | Type | Default | Description |
|----------|------|---------|-------------|
| `ENVIRONMENT` | string | `development` | Environment mode (development/staging/production) |
| `DATABASE_URL` | string | `sqlite:///./wizamart.db` | Database connection string |
| `ADMIN_EMAIL` | string | `admin@wizamart.com` | Platform admin email |
| `DATABASE_URL` | string | `sqlite:///./orion.db` | Database connection string |
| `ADMIN_EMAIL` | string | `admin@orion.lu` | Platform admin email |
| `ADMIN_USERNAME` | string | `admin` | Platform admin username |
| `ADMIN_PASSWORD` | string | `admin123` | Platform admin password |
| `ADMIN_FIRST_NAME` | string | `Platform` | Admin first name |
@@ -1000,6 +1000,6 @@ For questions or issues:
---
**Last Updated**: 2025
**Maintained By**: Wizamart Platform Team
**Version**: 2.0
**Last Updated**: 2025
**Maintained By**: Orion Platform Team
**Version**: 2.0

View File

@@ -68,10 +68,10 @@ make db-reset # rollback + migrate + reset
### Required Settings
```bash
ENVIRONMENT=development # development/staging/production
DATABASE_URL=sqlite:///./wizamart.db
DATABASE_URL=sqlite:///./orion.db
# Admin credentials (CHANGE IN PRODUCTION!)
ADMIN_EMAIL=admin@wizamart.com
ADMIN_EMAIL=admin@orion.lu
ADMIN_USERNAME=admin
ADMIN_PASSWORD=admin123
```
@@ -121,35 +121,35 @@ Store 3: store3@example.com / password123
## 📊 What Each Command Creates
### `make init-prod`
✅ Platform admin user
✅ Admin settings
✅ Role templates
✅ RBAC schema verification
✅ Platform admin user
✅ Admin settings
✅ Role templates
✅ RBAC schema verification
**Safe for production**: YES
**Contains fake data**: NO
**Safe for production**: YES
**Contains fake data**: NO
### `make seed-demo`
✅ 3 demo stores
✅ Demo store users
✅ ~45 customers (15 per store)
✅ ~60 products (20 per store)
✅ Store themes
✅ Custom domains
✅ 3 demo stores
✅ Demo store users
✅ ~45 customers (15 per store)
✅ ~60 products (20 per store)
✅ Store themes
✅ Custom domains
**Safe for production**: NO
**Contains fake data**: YES - ALL OF IT
**Safe for production**: NO
**Contains fake data**: YES - ALL OF IT
### `make seed-demo-minimal`
✅ 1 demo store
✅ 1 demo store user
✅ ~15 customers
✅ ~20 products
✅ Store theme
✅ Custom domain
✅ 1 demo store
✅ 1 demo store user
✅ ~15 customers
✅ ~20 products
✅ Store theme
✅ Custom domain
**Safe for production**: NO
**Contains fake data**: YES
**Safe for production**: NO
**Contains fake data**: YES
---
@@ -244,4 +244,4 @@ make help-db # Database-specific help
**Documentation**:
- `database-init-guide.md` - Detailed guide
- `MIGRATION_GUIDE.md` - Migration from old system
- `README.md` - Project overview
- `README.md` - Project overview

View File

@@ -2,13 +2,13 @@
## Overview
I've created a comprehensive database seeder for your Wizamart platform that significantly expands coverage beyond your original implementation. The new seeder creates realistic test data across all your database models.
I've created a comprehensive database seeder for your Orion platform that significantly expands coverage beyond your original implementation. The new seeder creates realistic test data across all your database models.
## What's New
### Original Seeder Coverage
- ✓ Admin user
- ✓ 2 Stores (TESTSTORE, WIZAMART)
- ✓ 2 Stores (TESTSTORE, ORION)
### Enhanced Seeder Coverage
- ✓ Admin user + multiple test users (stores, customers)
@@ -88,7 +88,7 @@ python scripts/seed_database.py
This creates:
- 1 admin user
- 3 test users (2 stores, 1 customer)
- 3 stores (WIZAMART, FASHIONHUB, BOOKSTORE)
- 3 stores (ORION, FASHIONHUB, BOOKSTORE)
- 5 marketplace products
- 10 store-product links
- 4 customers
@@ -107,7 +107,7 @@ python scripts/seed_database.py --minimal
This creates only:
- 1 admin user
- 1 store (WIZAMART)
- 1 store (ORION)
#### Option C: Reset and Seed (Fresh Start)
```bash
@@ -133,7 +133,7 @@ This runs:
| Username | Email | Password | Role |
|----------|-------|----------|------|
| admin | admin@wizamart.com | admin123 | admin |
| admin | admin@orion.lu | admin123 | admin |
| store1 | store1@example.com | password123 | store |
| store2 | store2@example.com | password123 | store |
| customer1 | customer1@example.com | password123 | customer |
@@ -142,7 +142,7 @@ This runs:
| Code | Name | Subdomain | Theme | Custom Domain |
|------|------|-----------|-------|---------------|
| WIZAMART | WizaMart | wizamart | modern | wizamart.shop |
| ORION | Orion | orion | modern | orion.shop |
| FASHIONHUB | Fashion Hub | fashionhub | vibrant | fashionhub.store |
| BOOKSTORE | The Book Store | bookstore | classic | (none) |
@@ -218,12 +218,12 @@ python scripts/seed_database.py [--reset] [--minimal]
- Password: `admin123`
### Store Shops
- WIZAMART: `http://localhost:8000/shop/WIZAMART`
- ORION: `http://localhost:8000/shop/ORION`
- FASHIONHUB: `http://localhost:8000/shop/FASHIONHUB`
- BOOKSTORE: `http://localhost:8000/shop/BOOKSTORE`
### Theme Editors
- WIZAMART Theme: `http://localhost:8000/admin/stores/WIZAMART/theme`
- ORION Theme: `http://localhost:8000/admin/stores/ORION/theme`
- FASHIONHUB Theme: `http://localhost:8000/admin/stores/FASHIONHUB/theme`
- BOOKSTORE Theme: `http://localhost:8000/admin/stores/BOOKSTORE/theme`
@@ -231,7 +231,7 @@ python scripts/seed_database.py [--reset] [--minimal]
```
╔════════════════════════════════════════════════════════════════════╗
WIZAMART DATABASE SEEDER ║
ORION DATABASE SEEDER ║
╚════════════════════════════════════════════════════════════════════╝
STEP 1: Verifying database...
@@ -248,9 +248,9 @@ STEP 1: Creating users...
✓ User 'customer1' created (ID: 4)
STEP 2: Creating stores...
WIZAMART created (ID: 1)
ORION created (ID: 1)
✓ Theme 'modern' applied
✓ Custom domain 'wizamart.shop' added
✓ Custom domain 'orion.shop' added
✓ FASHIONHUB created (ID: 2)
✓ Theme 'vibrant' applied
✓ Custom domain 'fashionhub.store' added
@@ -285,7 +285,7 @@ You can customize the seeder by editing the configuration constants at the top o
```python
# Admin credentials
DEFAULT_ADMIN_EMAIL = "admin@wizamart.com"
DEFAULT_ADMIN_EMAIL = "admin@orion.lu"
DEFAULT_ADMIN_USERNAME = "admin"
DEFAULT_ADMIN_PASSWORD = "admin123"
@@ -414,7 +414,7 @@ make db-setup
## Security Notes
⚠️ **IMPORTANT**:
⚠️ **IMPORTANT**:
- Default passwords are simple for development convenience
- Change ALL default passwords in production environments
- The admin password is intentionally weak for local development

View File

@@ -21,7 +21,7 @@
## Overview
The Wizamart platform uses **automatic environment detection** to determine the runtime environment (development, staging, or production) and adjust security settings accordingly.
The Orion platform uses **automatic environment detection** to determine the runtime environment (development, staging, or production) and adjust security settings accordingly.
### Why Auto-Detection?
@@ -158,7 +158,7 @@ from app.core.environment import is_development, is_production
def debug_info():
if not is_development():
raise HTTPException(status_code=404, detail="Not found")
# Only accessible in development
return {
"database": get_db_info(),
@@ -226,7 +226,7 @@ from app.core.environment import get_environment
def configure_logging():
env = get_environment()
if env == "development":
# Verbose logging for development
logging.basicConfig(
@@ -255,10 +255,10 @@ from app.core.environment import get_cached_environment
def process_request(request: Request):
# Use cached version for frequent calls
env = get_cached_environment() # Cached - faster
# Instead of:
# env = get_environment() # Re-detects every time
if env == "production":
# Production-specific optimization
use_cache = True
@@ -335,7 +335,7 @@ ExecStart=/usr/bin/uvicorn main:app --host 0.0.0.0 --port 8000
```yaml
services:
web:
image: wizamart:latest
image: orion:latest
environment:
- ENV=production
ports:
@@ -421,14 +421,14 @@ from app.core.environment import get_environment, should_use_secure_cookies
def test_environment_detection_with_env_var():
"""Test environment detection with ENV variable."""
os.environ["ENV"] = "production"
# Clear cache first
import app.core.environment as env_module
env_module._cached_environment = None
assert get_environment() == "production"
assert should_use_secure_cookies() == True
# Cleanup
del os.environ["ENV"]
@@ -437,11 +437,11 @@ def test_environment_defaults_to_development():
# Ensure no env vars set
os.environ.pop("ENV", None)
os.environ.pop("ENVIRONMENT", None)
# Clear cache
import app.core.environment as env_module
env_module._cached_environment = None
assert get_environment() == "development"
assert should_use_secure_cookies() == False
```
@@ -453,17 +453,17 @@ def test_login_sets_secure_cookie_in_production(test_client, monkeypatch):
"""Test that login sets secure cookie in production."""
# Mock production environment
monkeypatch.setenv("ENV", "production")
# Clear cache
import app.core.environment as env_module
env_module._cached_environment = None
# Test login
response = test_client.post("/api/v1/admin/auth/login", json={
"username": "admin",
"password": "admin123"
})
# Check cookie has secure flag
set_cookie_header = response.headers.get("set-cookie")
assert "Secure" in set_cookie_header
@@ -481,7 +481,7 @@ from app.core.environment import get_environment, should_use_secure_cookies
async def startup_event():
env = get_environment()
secure = should_use_secure_cookies()
print(f"🌍 Environment: {env}")
print(f"🔒 Secure cookies: {secure}")
print(f"📍 Running on: {os.getenv('HOSTNAME', 'localhost')}")
@@ -498,7 +498,7 @@ def debug_environment():
"""Debug endpoint to check environment detection."""
if not is_development():
raise HTTPException(status_code=404)
return {
"detected_environment": get_environment(),
"should_use_secure_cookies": should_use_secure_cookies(),
@@ -518,8 +518,8 @@ def debug_environment():
**Setup:**
```bash
# Clone repo
git clone <wizamart-repo>
cd wizamart-repo
git clone <orion-repo>
cd orion-repo
# Create virtual environment
python -m venv venv
@@ -553,16 +553,16 @@ services:
build: .
environment:
- ENV=staging
- DATABASE_URL=postgresql://user:pass@db:5432/wizamart_staging
- DATABASE_URL=postgresql://user:pass@db:5432/orion_staging
ports:
- "8000:8000"
depends_on:
- db
db:
image: postgres:15
environment:
- POSTGRES_DB=wizamart_staging
- POSTGRES_DB=orion_staging
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
```
@@ -572,13 +572,13 @@ services:
apiVersion: apps/v1
kind: Deployment
metadata:
name: wizamart-staging
name: orion-staging
spec:
template:
spec:
containers:
- name: web
image: wizamart:latest
image: orion:latest
env:
- name: ENV
value: "staging"
@@ -599,15 +599,15 @@ spec:
**systemd Service:**
```ini
[Unit]
Description=Wizamart Platform
Description=Orion Platform
After=network.target
[Service]
User=wizamart
WorkingDirectory=/opt/wizamart
User=orion
WorkingDirectory=/opt/orion
Environment="ENV=production"
Environment="DATABASE_URL=postgresql://user:pass@localhost/wizamart_prod"
ExecStart=/opt/wizamart/venv/bin/uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
Environment="DATABASE_URL=postgresql://user:pass@localhost/orion_prod"
ExecStart=/opt/orion/venv/bin/uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
Restart=always
[Install]
@@ -742,42 +742,42 @@ class TestEnvironmentDetection:
# Clear any env vars
os.environ.pop("ENV", None)
os.environ.pop("ENVIRONMENT", None)
assert get_environment() == "development"
assert is_development() == True
assert is_production() == False
assert should_use_secure_cookies() == False
def test_env_variable_production(self, monkeypatch):
"""Test ENV=production detection."""
monkeypatch.setenv("ENV", "production")
assert get_environment() == "production"
assert is_production() == True
assert should_use_secure_cookies() == True
def test_environment_variable_staging(self, monkeypatch):
"""Test ENVIRONMENT=staging detection."""
monkeypatch.setenv("ENVIRONMENT", "staging")
assert get_environment() == "staging"
assert is_staging() == True
assert should_use_secure_cookies() == True
def test_env_takes_priority_over_environment(self, monkeypatch):
"""Test that ENV variable has priority."""
monkeypatch.setenv("ENV", "production")
monkeypatch.setenv("ENVIRONMENT", "staging")
# ENV should win
assert get_environment() == "production"
def test_debug_true_is_development(self, monkeypatch):
"""Test that DEBUG=true results in development."""
monkeypatch.delenv("ENV", raising=False)
monkeypatch.delenv("ENVIRONMENT", raising=False)
monkeypatch.setenv("DEBUG", "true")
assert get_environment() == "development"
@@ -786,7 +786,7 @@ class TestCookieSecurity:
"""Test cookies are secure in production."""
monkeypatch.setenv("ENV", "production")
assert should_use_secure_cookies() == True
def test_insecure_cookies_in_development(self):
"""Test cookies are not secure in development."""
os.environ.pop("ENV", None)
@@ -803,21 +803,21 @@ def test_login_cookie_matches_environment(test_client, monkeypatch):
"username": "admin",
"password": "admin123"
})
set_cookie = response.headers.get("set-cookie", "")
assert "Secure" not in set_cookie # No Secure in development
# Test production
monkeypatch.setenv("ENV", "production")
# Clear cache
import app.core.environment as env_module
env_module._cached_environment = None
response = test_client.post("/api/v1/admin/auth/login", json={
"username": "admin",
"password": "admin123"
})
set_cookie = response.headers.get("set-cookie", "")
assert "Secure" in set_cookie # Secure in production
```
@@ -854,7 +854,7 @@ def test_login_cookie_matches_environment(test_client, monkeypatch):
def send_email(to: str, subject: str):
"""
Send email to recipient.
Environment behavior:
- Development: Logs email to console (no actual send)
- Staging: Sends to test email address
@@ -887,7 +887,7 @@ def test_login_cookie_matches_environment(test_client, monkeypatch):
# ❌ Bad
if os.getenv("ENV") == "production":
use_https = True
# ✅ Good
use_https = should_use_secure_cookies()
```
@@ -896,7 +896,7 @@ def test_login_cookie_matches_environment(test_client, monkeypatch):
```python
# ❌ Bad - assumes production
response.set_cookie(secure=True)
# ✅ Good - adapts to environment
response.set_cookie(secure=should_use_secure_cookies())
```
@@ -907,7 +907,7 @@ def test_login_cookie_matches_environment(test_client, monkeypatch):
FORCE_PRODUCTION = True
if FORCE_PRODUCTION:
...
# ✅ Good - use environment variable
# export ENV=production
if is_production():
@@ -921,7 +921,7 @@ def test_login_cookie_matches_environment(test_client, monkeypatch):
log_level = "WARNING"
elif is_development():
log_level = "DEBUG"
# ✅ Good - consistent
env = get_environment()
if env == "production":
@@ -936,7 +936,7 @@ def test_login_cookie_matches_environment(test_client, monkeypatch):
def test_production():
os.environ["ENV"] = "production"
assert get_environment() == "production" # May fail if cached
# ✅ Good - clear cache
def test_production():
import app.core.environment as env_module

View File

@@ -182,7 +182,7 @@ ErrorPageRenderer.render_error_page(
**Handlers:**
- `WizamartException` - Custom application exceptions
- `OrionException` - Custom application exceptions
- `HTTPException` - FastAPI HTTP exceptions
- `RequestValidationError` - Pydantic validation errors
- `Exception` - Generic Python exceptions

View File

@@ -41,7 +41,7 @@
┌────────────────────────────────────────────────────────┐
│ Exception Handler │
│ - WizamartException │
│ - OrionException │
│ - HTTPException │
│ - RequestValidationError │
│ - Generic Exception │
@@ -296,14 +296,14 @@ middleware/
## Benefits Summary
**Separation of Concerns**: HTML templates separate from handler logic
**Context-Aware**: Different error pages for different areas
**Maintainable**: Easy to update individual error pages
**Scalable**: Easy to add new contexts or error types
**Professional**: Polished error pages matching area design
**Flexible**: Fallback mechanism ensures errors always render
**Secure**: Debug info only shown to admins
**Themed**: Shop errors can use store branding (Phase 3)
**Separation of Concerns**: HTML templates separate from handler logic
**Context-Aware**: Different error pages for different areas
**Maintainable**: Easy to update individual error pages
**Scalable**: Easy to add new contexts or error types
**Professional**: Polished error pages matching area design
**Flexible**: Fallback mechanism ensures errors always render
**Secure**: Debug info only shown to admins
**Themed**: Shop errors can use store branding (Phase 3)
---

View File

@@ -2,14 +2,14 @@
## Overview
The Wizamart API uses a unified custom exception system to provide consistent, meaningful error responses across all endpoints. This system was redesigned to eliminate competing exception handlers and provide a single source of truth for error handling.
The Orion API uses a unified custom exception system to provide consistent, meaningful error responses across all endpoints. This system was redesigned to eliminate competing exception handlers and provide a single source of truth for error handling.
## Architecture
### Exception Hierarchy
```
WizamartException (Base)
OrionException (Base)
├── ValidationException (422)
├── AuthenticationException (401)
├── AuthorizationException (403)
@@ -91,7 +91,7 @@ The system handles four categories of exceptions:
```python
# app/exceptions/handler.py
@app.exception_handler(WizamartException)
@app.exception_handler(OrionException)
async def custom_exception_handler(request, exc):
"""Handle all custom business exceptions"""
return JSONResponse(
@@ -99,7 +99,7 @@ async def custom_exception_handler(request, exc):
content=exc.to_dict()
)
@app.exception_handler(HTTPException)
@app.exception_handler(HTTPException)
async def http_exception_handler(request, exc):
"""Handle FastAPI HTTP exceptions"""
return JSONResponse(
@@ -149,11 +149,11 @@ from app.exceptions.admin import UserNotFoundException, CannotModifySelfExceptio
def toggle_user_status(self, db: Session, user_id: int, current_admin_id: int):
user = self._get_user_by_id_or_raise(db, user_id)
# Prevent self-modification
if user.id == current_admin_id:
raise CannotModifySelfException(user_id, "deactivate account")
# Prevent admin-to-admin modification
if user.role == "admin" and user.id != current_admin_id:
raise UserStatusChangeException(
@@ -214,7 +214,7 @@ from .base import BusinessLogicException, ResourceNotFoundException
class PaymentNotFoundException(ResourceNotFoundException):
"""Raised when payment record is not found."""
def __init__(self, payment_id: str):
super().__init__(
resource_type="Payment",
@@ -225,7 +225,7 @@ class PaymentNotFoundException(ResourceNotFoundException):
class InsufficientFundsException(BusinessLogicException):
"""Raised when account has insufficient funds."""
def __init__(self, required: float, available: float, account_id: str):
super().__init__(
message=f"Insufficient funds. Required: {required}, Available: {available}",
@@ -246,7 +246,7 @@ from .payment import PaymentNotFoundException, InsufficientFundsException
__all__ = [
# ... existing exports
"PaymentNotFoundException",
"PaymentNotFoundException",
"InsufficientFundsException",
]
```
@@ -259,10 +259,10 @@ from app.exceptions import PaymentNotFoundException, InsufficientFundsException
def process_payment(self, db: Session, payment_id: str, amount: float):
payment = self._get_payment_by_id_or_raise(db, payment_id)
if payment.account_balance < amount:
raise InsufficientFundsException(amount, payment.account_balance, payment.account_id)
# Process payment...
return payment
```
@@ -280,7 +280,7 @@ from app.exceptions.admin import UserNotFoundException, CannotModifySelfExceptio
def test_user_not_found_exception():
exc = UserNotFoundException("123")
assert exc.error_code == "USER_NOT_FOUND"
assert exc.status_code == 404
assert "123" in exc.message
@@ -288,7 +288,7 @@ def test_user_not_found_exception():
def test_cannot_modify_self_exception():
exc = CannotModifySelfException(456, "deactivate account")
assert exc.error_code == "CANNOT_MODIFY_SELF"
assert exc.status_code == 400
assert "deactivate account" in exc.message
@@ -303,7 +303,7 @@ Test complete error handling flow:
def test_toggle_user_status_cannot_modify_self(client, admin_headers, test_admin):
"""Test that admin cannot modify their own account"""
response = client.put(
f"/api/v1/admin/users/{test_admin.id}/status",
f"/api/v1/admin/users/{test_admin.id}/status",
headers=admin_headers
)
@@ -352,14 +352,14 @@ def test_get_all_users_non_admin(client, auth_headers):
- `INVALID_TOKEN`: Malformed or invalid token
- `USER_NOT_ACTIVE`: User account is deactivated
### Authorization (403)
### Authorization (403)
- `ADMIN_REQUIRED`: Admin privileges required for operation
- `INSUFFICIENT_PERMISSIONS`: User lacks required permissions
- `UNAUTHORIZED_SHOP_ACCESS`: Cannot access shop (not owner)
### Resource Not Found (404)
- `USER_NOT_FOUND`: User with specified ID not found
- `SHOP_NOT_FOUND`: Shop with specified code/ID not found
- `SHOP_NOT_FOUND`: Shop with specified code/ID not found
- `PRODUCT_NOT_FOUND`: MarketplaceProduct with specified ID not found
### Business Logic (400)

View File

@@ -2,7 +2,7 @@
## Overview
This document describes the implementation of multi-language support for the Wizamart platform. The system supports four languages (English, French, German, Luxembourgish) with flexible configuration at store, user, and customer levels.
This document describes the implementation of multi-language support for the Orion platform. The system supports four languages (English, French, German, Luxembourgish) with flexible configuration at store, user, and customer levels.
## Supported Languages

View File

@@ -4,7 +4,7 @@ This document tracks the migration of legacy code to the self-contained module a
## Overview
The Wizamart platform has been migrating from a monolithic structure with code in centralized locations (`app/api/v1/`, `app/services/`, `models/`) to a fully modular architecture where each module owns all its entities (routes, services, models, schemas, tasks).
The Orion platform has been migrating from a monolithic structure with code in centralized locations (`app/api/v1/`, `app/services/`, `models/`) to a fully modular architecture where each module owns all its entities (routes, services, models, schemas, tasks).
## Migration Goals

View File

@@ -8,7 +8,7 @@
## Overview
This document establishes consistent naming conventions across the entire Wizamart multi-tenant ecommerce platform. Consistent naming improves code readability, reduces developer confusion, and ensures maintainable architecture.
This document establishes consistent naming conventions across the entire Orion multi-tenant ecommerce platform. Consistent naming improves code readability, reduces developer confusion, and ensures maintainable architecture.
## Core Principles
@@ -481,4 +481,4 @@ Consider implementing linting rules or pre-commit hooks to enforce:
**Last Updated:** November 2025
**Maintained By:** Backend Team
This naming convention guide ensures consistent, maintainable, and intuitive code across the entire Wizamart multi-tenant ecommerce platform.
This naming convention guide ensures consistent, maintainable, and intuitive code across the entire Orion multi-tenant ecommerce platform.

View File

@@ -459,7 +459,7 @@ If you need to work immediately:
```
Host: localhost
Port: 5432
Database: wizamart_db
Database: orion_db
User: [from .env file]
Password: [from .env file]
```