Files
orion/docs/__Dev-Slice1/slice1_implementation_guide.md

10 KiB
Raw Blame History

Slice 1 Implementation Guide

Admin Creates Vendor → Vendor Owner Logs In

This guide provides complete instructions for implementing Slice 1 of the multi-tenant ecommerce platform.

What We've Built

Backend Components

  1. Enhanced Admin Service (app/services/admin_service.py)

    • create_vendor_with_owner() - Creates vendor + owner user + default roles
    • Generates secure temporary password
    • Auto-verifies admin-created vendors
  2. Enhanced Admin API (app/api/v1/admin.py)

    • POST /admin/vendors - Create vendor with owner
    • GET /admin/vendors - List vendors with filtering
    • GET /admin/dashboard - Dashboard statistics
    • PUT /admin/vendors/{id}/verify - Verify vendor
    • PUT /admin/vendors/{id}/status - Toggle vendor status
  3. Vendor Schema Updates (models/schemas/vendor.py)

    • Added owner_email field to VendorCreate
    • Created VendorCreateResponse with credentials
  4. Vendor Context Middleware (middleware/vendor_context.py)

    • Subdomain detection (production)
    • Path-based detection (development)
    • Vendor isolation enforcement

Frontend Components

  1. Admin Login Page (static/admin/login.html)

    • Clean, modern UI
    • JWT authentication
    • Role validation (admin only)
  2. Admin Dashboard (static/admin/dashboard.html)

    • Statistics overview
    • Recent vendors list
    • Recent import jobs
    • Navigation to all sections
  3. Vendor Creation Page (static/admin/vendors.html)

    • Complete vendor creation form
    • Auto-formatting inputs
    • Displays generated credentials
    • One-time password display
  4. API Client Utility (static/js/shared/api-client.js)

    • Authenticated API calls
    • Token management
    • Error handling
    • Utility functions

📋 Prerequisites

Before implementing Slice 1, ensure you have:

  • PostgreSQL database running
  • Python 3.11+ with FastAPI
  • All dependencies installed (pip install -r requirements.txt)
  • .env file configured with database URL and JWT secret

🚀 Implementation Steps

Step 1: Update Database Models

Ensure your models/database/vendor.py includes:

class Vendor(Base, TimestampMixin):
    __tablename__ = "vendors"
    
    id = Column(Integer, primary_key=True, index=True)
    vendor_code = Column(String, unique=True, nullable=False, index=True)
    subdomain = Column(String(100), unique=True, nullable=False, index=True)
    name = Column(String, nullable=False)
    description = Column(Text)
    owner_user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
    
    # Business information
    business_email = Column(String)
    business_phone = Column(String)
    contact_email = Column(String)
    contact_phone = Column(String)
    website = Column(String)
    business_address = Column(Text)
    tax_number = Column(String)
    
    # Status flags
    is_active = Column(Boolean, default=True)
    is_verified = Column(Boolean, default=False)
    verified_at = Column(DateTime, nullable=True)
    
    # Theme and configuration
    theme_config = Column(JSON, default=dict)
    
    # CSV URLs for marketplace integration
    letzshop_csv_url_fr = Column(String)
    letzshop_csv_url_en = Column(String)
    letzshop_csv_url_de = Column(String)
    
    # Relationships
    owner = relationship("User", back_populates="owned_vendors")

Step 2: Create Database Migration

Create a new Alembic migration:

# Generate migration
alembic revision --autogenerate -m "Add vendor and role tables for slice 1"

# Review the generated migration file
# Then apply it:
alembic upgrade head

Step 3: Create Default Admin User

Run the script to create initial admin:

# scripts/create_admin.py
from sqlalchemy.orm import Session
from app.core.database import SessionLocal
from middleware.auth import AuthManager
from models.database.user import User

def create_admin():
    db = SessionLocal()
    auth_manager = AuthManager()
    
    # Check if admin exists
    admin = db.query(User).filter(User.username == "admin").first()
    
    if not admin:
        admin = User(
            email="admin@platform.com",
            username="admin",
            hashed_password=auth_manager.hash_password("admin123"),
            role="admin",
            is_active=True
        )
        db.add(admin)
        db.commit()
        print("✅ Admin user created:")
        print("   Username: admin")
        print("   Password: admin123")
        print("   Email: admin@platform.com")
    else:
        print("  Admin user already exists")
    
    db.close()

if __name__ == "__main__":
    create_admin()

Run it:

python scripts/create_admin.py

Step 4: Deploy Frontend Files

Ensure the following structure exists:

static/
├── admin/
│   ├── login.html
│   ├── dashboard.html
│   └── vendors.html
├── js/
│   └── shared/
│       └── api-client.js
└── css/
    ├── shared/
    │   └── base.css
    └── admin/
        └── admin.css

Step 5: Update API Router

Ensure app/api/main.py includes admin routes:

from app.api.v1 import admin

api_router.include_router(
    admin.router,
    prefix="/admin",
    tags=["admin"]
)

Step 6: Start the Application

# Start the server
uvicorn main:app --reload --port 8000

# Or with hot reload
python main.py

Step 7: Test the Flow

7.1 Admin Login

  1. Navigate to http://localhost:8000/static/admin/login.html
  2. Login with:
    • Username: admin
    • Password: admin123
  3. Should redirect to dashboard

7.2 Create Vendor

  1. Click "Create New Vendor" button
  2. Fill in the form:
    • Vendor Code: TECHSTORE
    • Name: Tech Store Luxembourg
    • Subdomain: techstore
    • Owner Email: owner@techstore.com
  3. Submit the form
  4. Save the displayed credentials!

7.3 Verify Vendor Creation

  1. Check database:
SELECT * FROM vendors WHERE vendor_code = 'TECHSTORE';
SELECT * FROM users WHERE email = 'owner@techstore.com';
SELECT * FROM roles WHERE vendor_id = (SELECT id FROM vendors WHERE vendor_code = 'TECHSTORE');
  1. Check admin dashboard - vendor should appear in "Recent Vendors"

🧪 Testing Checklist

Admin Interface Tests

  • Admin can login with correct credentials
  • Admin login rejects non-admin users
  • Dashboard displays vendor statistics
  • Dashboard displays user statistics
  • Recent vendors list shows newest vendors
  • Vendor creation form validates inputs
  • Vendor code is auto-uppercased
  • Subdomain is auto-lowercased
  • Duplicate vendor code is rejected
  • Duplicate subdomain is rejected
  • Generated credentials are displayed once
  • Admin can view all vendors
  • Admin can verify/unverify vendors
  • Admin can activate/deactivate vendors

Vendor Context Tests

  • Subdomain detection works: vendor.localhost:8000
  • Path detection works: localhost:8000/vendor/vendorname/
  • Admin routes are excluded from vendor context
  • API routes are excluded from vendor context
  • Invalid vendor returns 404

Database Tests

  • Vendor record created correctly
  • Owner user record created
  • Owner has correct relationship to vendor
  • Default roles created (Owner, Manager, Editor, Viewer)
  • Vendor is auto-verified when created by admin
  • Timestamps are set correctly

🔐 Security Considerations

  1. Password Security

    • Temporary passwords are 12+ characters
    • Include letters, numbers, and symbols
    • Hashed with bcrypt before storage
    • Displayed only once
  2. Admin Access Control

    • JWT token required for all admin endpoints
    • Role validation on every request
    • Token expiration enforced
  3. Vendor Isolation

    • Vendor context middleware enforces boundaries
    • All queries filtered by vendor_id
    • Cross-vendor access prevented

📝 Configuration

Environment Variables

# Database
DATABASE_URL=postgresql://user:pass@localhost:5432/dbname

# JWT
JWT_SECRET_KEY=your-secret-key-change-in-production
JWT_EXPIRE_MINUTES=30

# Server
SERVER_ADDRESS=http://localhost:8000
DEBUG=True

# Platform
PROJECT_NAME="Multi-Tenant Ecommerce Platform"
ALLOWED_HOSTS=["*"]

Development vs Production

Development Mode (path-based):

http://localhost:8000/vendor/techstore/
http://localhost:8000/admin/

Production Mode (subdomain-based):

https://techstore.platform.com/
https://admin.platform.com/

🐛 Troubleshooting

Issue: Admin login fails

Solution: Check that admin user exists and role is "admin"

python scripts/create_admin.py

Issue: Vendor creation returns 401

Solution: Check that JWT token is valid and not expired

// In browser console
localStorage.getItem('admin_token')

Issue: Vendor context not detected

Solution: Check middleware is registered in main.py:

app.middleware("http")(vendor_context_middleware)

Issue: Database foreign key error

Solution: Run migrations in correct order:

alembic upgrade head

📊 Success Metrics

Slice 1 is complete when:

  • Admin can log into admin interface
  • Admin can create new vendors
  • System generates vendor owner credentials
  • Vendor owner can log into vendor-specific interface
  • Vendor context detection works in dev and production modes
  • Database properly isolates vendor data
  • All tests pass
  • Documentation is complete

🎯 Next Steps - Slice 2

Once Slice 1 is complete and tested, proceed to Slice 2: Vendor Imports Products from Letzshop:

  1. Implement marketplace CSV import
  2. Create MarketplaceProduct staging table
  3. Build product import UI
  4. Add background job processing with Celery
  5. Create import job monitoring

💡 Tips

  1. Always test in order: Admin login → Vendor creation → Context detection
  2. Save credentials immediately: Password is shown only once
  3. Use browser dev tools: Check console for API errors
  4. Check database directly: Verify data is created correctly
  5. Test both detection modes: Path-based (dev) and subdomain (prod)