15 KiB
Quick Start Guide - Slice 1
Get Your Multi-Tenant Platform Running in 15 Minutes
This guide gets Slice 1 up and running quickly so you can test the complete admin → vendor creation → vendor login flow.
🎯 What You'll Accomplish
By the end of this guide, you'll be able to:
- ✅ Login as super admin
- ✅ Create vendors with auto-generated owner accounts
- ✅ Login as vendor owner
- ✅ See vendor-specific dashboard
- ✅ Verify vendor isolation works
📦 Prerequisites Checklist
Before starting, ensure you have:
# Check Python version (need 3.11+)
python --version
# Check PostgreSQL is running
psql --version
# Check you have the project files
ls main.py # Should exist
⚡ 5-Step Setup
Step 1: Install Dependencies (2 minutes)
# Create virtual environment
python -m venv venv
# Activate it
source venv/bin/activate # macOS/Linux
# OR
venv\Scripts\activate # Windows
# Install requirements
pip install fastapi uvicorn sqlalchemy psycopg2-binary python-jose passlib bcrypt python-multipart
Step 2: Configure Database (3 minutes)
# Create .env file
cat > .env << 'EOF'
# Database
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/multitenant_ecommerce
# JWT Security
JWT_SECRET_KEY=your-super-secret-key-change-this-in-production-please
JWT_EXPIRE_MINUTES=30
# Server
SERVER_ADDRESS=http://localhost:8000
DEBUG=True
PROJECT_NAME=Multi-Tenant Ecommerce Platform
ALLOWED_HOSTS=["*"]
EOF
# Create database
createdb multitenant_ecommerce
# Or using psql:
# psql -U postgres -c "CREATE DATABASE multitenant_ecommerce;"
Step 3: Initialize Database (3 minutes)
Create scripts/init_db.py:
# scripts/init_db.py
import sys
sys.path.append('.')
from app.core.database import Base, engine
from models.database.user import User
from models.database.vendor import Vendor, Role, VendorUser
from middleware.auth import AuthManager
def init_database():
"""Initialize database with tables and admin user"""
print("🔧 Creating database tables...")
Base.metadata.create_all(bind=engine)
print("✅ Tables created successfully")
# Create admin user
from sqlalchemy.orm import Session
db = Session(bind=engine)
try:
admin = db.query(User).filter(User.username == "admin").first()
if not admin:
auth_manager = AuthManager()
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("\n✅ Admin user created:")
print(" 📧 Email: admin@platform.com")
print(" 👤 Username: admin")
print(" 🔑 Password: admin123")
else:
print("\nℹ️ Admin user already exists")
print("\n🎉 Database initialization complete!")
print("\n🚀 Next steps:")
print(" 1. Run: uvicorn main:app --reload")
print(" 2. Visit: http://localhost:8000/static/admin/login.html")
finally:
db.close()
if __name__ == "__main__":
init_database()
Run it:
python scripts/init_db.py
Step 4: Create Directory Structure (2 minutes)
# Create required directories
mkdir -p static/admin
mkdir -p static/vendor
mkdir -p static/js/shared
mkdir -p static/css/admin
mkdir -p static/css/shared
Copy the HTML/JS files I created into these directories:
static/admin/login.htmlstatic/admin/dashboard.htmlstatic/admin/vendors.htmlstatic/vendor/login.htmlstatic/vendor/dashboard.htmlstatic/js/shared/api-client.js
Step 5: Start the Application (1 minute)
# Start FastAPI server
uvicorn main:app --reload --port 8000
You should see:
INFO: Uvicorn running on http://127.0.0.1:8000
INFO: Application startup complete.
🧪 Test the Complete Flow (5 minutes)
Test 1: Admin Login
- Open browser: http://localhost:8000/static/admin/login.html
- Login:
- Username:
admin - Password:
admin123
- Username:
- Expected: Redirected to admin dashboard
Test 2: Create Vendor
- Click: "Create New Vendor" button
- Fill form:
Vendor Code: TECHSTORE Name: Tech Store Luxembourg Subdomain: techstore Owner Email: owner@techstore.com (Leave other fields optional) - Submit: Click "Create Vendor"
- Expected: Success message with credentials displayed
Test 3: Copy Vendor Credentials
IMPORTANT: Copy these credentials immediately (they're shown only once):
Vendor Code: TECHSTORE
Subdomain: techstore
Owner Username: techstore_owner
Owner Email: owner@techstore.com
Temporary Password: [COPY THIS!]
Test 4: Vendor Login (Path-based)
- Open new tab: http://localhost:8000/vendor/techstore/login
- Login:
- Username:
techstore_owner - Password: [paste the temporary password]
- Username:
- Expected: Redirected to vendor dashboard
- Verify: Dashboard shows "TECHSTORE Dashboard"
Test 5: Verify Isolation
- Try accessing different vendor: http://localhost:8000/vendor/otherstore/login
- Expected: "Vendor Not Found" message
- Database check:
SELECT * FROM vendors WHERE vendor_code = 'TECHSTORE'; SELECT * FROM users WHERE email = 'owner@techstore.com';
✅ Success Indicators
You know Slice 1 is working when:
- Admin can login and see dashboard
- Admin can create vendors
- Vendor owner credentials are generated
- Vendor owner can login
- Vendor dashboard shows correct vendor context
- Invalid vendor URLs show error message
- Each vendor is completely isolated
🐛 Common Issues & Fixes
Issue: "Module not found" errors
Fix:
pip install -r requirements.txt
# Or install missing packages individually
pip install fastapi sqlalchemy psycopg2-binary
Issue: Database connection fails
Fix:
# Check PostgreSQL is running
sudo service postgresql status
# Check database exists
psql -U postgres -l | grep multitenant
# Update DATABASE_URL in .env to match your setup
Issue: "401 Unauthorized" in browser console
Fix:
// Open browser console (F12)
// Check token exists:
localStorage.getItem('admin_token')
// If null, login again
// If exists but still fails, token might be expired - login again
Issue: Admin login redirects to login page
Fix:
# Check admin user exists in database:
psql -U postgres -d multitenant_ecommerce -c "SELECT * FROM users WHERE role='admin';"
# If no results, run:
python scripts/init_db.py
Issue: Vendor context not detected
Fix: Check URL format:
- ✅ Correct:
localhost:8000/vendor/techstore/login - ❌ Wrong:
localhost:8000/techstore/login - ❌ Wrong:
localhost:8000/vendor/login
Issue: Static files not loading (404)
Fix:
# Verify main.py has static file mounting:
from fastapi.staticfiles import StaticFiles
app.mount("/static", StaticFiles(directory="static"), name="static")
📊 Database Verification
Check everything was created correctly:
-- Connect to database
psql -U postgres -d multitenant_ecommerce
-- Check tables
\dt
-- Check admin user
SELECT id, username, email, role FROM users WHERE role = 'admin';
-- Check created vendor
SELECT id, vendor_code, name, subdomain, is_active, is_verified
FROM vendors;
-- Check vendor owner
SELECT id, username, email, role
FROM users WHERE email LIKE '%techstore%';
-- Check default roles were created
SELECT id, name, vendor_id
FROM roles
WHERE vendor_id = (SELECT id FROM vendors WHERE vendor_code = 'TECHSTORE');
Expected results:
- 1 admin user
- 1 vendor (TECHSTORE)
- 1 vendor owner user
- 4 roles (Owner, Manager, Editor, Viewer)
🎯 Next Steps
Once Slice 1 is working:
Option 1: Create More Vendors
Test multi-tenancy by creating multiple vendors:
- Create
FASHIONSTOREvendor - Create
BOOKSHOPvendor - Verify each has isolated login and dashboard
Option 2: Proceed to Slice 2
Move on to Slice 2: Marketplace Product Import:
- Implement CSV import functionality
- Create MarketplaceProduct staging table
- Build import UI
- Add Celery for background processing
Option 3: Customize UI
Enhance the frontend:
- Add custom CSS themes
- Improve dashboard widgets
- Add vendor statistics
- Build team management UI
📚 Quick Reference
Important URLs
Admin Portal:
- Login: http://localhost:8000/static/admin/login.html
- Dashboard: http://localhost:8000/static/admin/dashboard.html
- Create Vendor: http://localhost:8000/static/admin/vendors.html
Vendor Portal (Path-based):
- Login: http://localhost:8000/vendor/{subdomain}/login
- Dashboard: http://localhost:8000/vendor/{subdomain}/dashboard
API Documentation:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- Health Check: http://localhost:8000/health
Key API Endpoints
# Authentication
POST /api/v1/auth/login # Login (admin or vendor)
POST /api/v1/auth/register # Register new user
GET /api/v1/auth/me # Get current user info
# Admin - Vendors
POST /api/v1/admin/vendors # Create vendor with owner
GET /api/v1/admin/vendors # List all vendors
GET /api/v1/admin/vendors/{id} # Get vendor details
PUT /api/v1/admin/vendors/{id}/verify # Verify vendor
PUT /api/v1/admin/vendors/{id}/status # Toggle active status
# Admin - Users
GET /api/v1/admin/users # List all users
PUT /api/v1/admin/users/{id}/status # Toggle user status
# Admin - Dashboard
GET /api/v1/admin/dashboard # Get dashboard stats
GET /api/v1/admin/stats/users # User statistics
GET /api/v1/admin/stats/vendors # Vendor statistics
Testing with cURL
# Login as admin
curl -X POST http://localhost:8000/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}'
# Save the token
TOKEN="your_token_here"
# Create vendor
curl -X POST http://localhost:8000/api/v1/admin/vendors \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"vendor_code": "TESTSHOP",
"name": "Test Shop",
"subdomain": "testshop",
"owner_email": "owner@testshop.com"
}'
# Get all vendors
curl -X GET http://localhost:8000/api/v1/admin/vendors \
-H "Authorization: Bearer $TOKEN"
Browser Console Testing
// In browser console (F12), test API calls:
// Login
fetch('/api/v1/auth/login', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({username: 'admin', password: 'admin123'})
})
.then(r => r.json())
.then(d => {
localStorage.setItem('admin_token', d.access_token);
console.log('Logged in!', d);
});
// Create vendor
const token = localStorage.getItem('admin_token');
fetch('/api/v1/admin/vendors', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
vendor_code: 'MYSHOP',
name: 'My Shop',
subdomain: 'myshop',
owner_email: 'owner@myshop.com'
})
})
.then(r => r.json())
.then(d => console.log('Vendor created!', d));
🔒 Security Notes
For Development
Current setup uses:
- ✅ JWT tokens with bcrypt password hashing
- ✅ HttpOnly would be recommended for production cookies
- ✅ CORS middleware configured
- ⚠️ Default admin password (change immediately!)
- ⚠️ DEBUG=True (disable in production)
For Production
Before going live:
-
Change default credentials:
UPDATE users SET hashed_password = 'new_hash' WHERE username = 'admin'; -
Update environment variables:
DEBUG=False JWT_SECRET_KEY=[generate strong random key] ALLOWED_HOSTS=["yourdomain.com"] -
Enable HTTPS:
- Use nginx/apache with SSL certificates
- Force HTTPS redirects
- Set secure cookie flags
-
Set up subdomain routing:
- Configure DNS wildcards:
*.platform.com - Update nginx to route subdomains
- Test subdomain detection
- Configure DNS wildcards:
📝 File Checklist
Ensure you have all these files:
✅ Backend Core:
- main.py
- app/core/config.py
- app/core/database.py
- app/api/main.py
- app/api/deps.py
✅ Models:
- models/database/user.py
- models/database/vendor.py
- models/database/base.py
- models/schemas/auth.py
- models/schemas/vendor.py
✅ Services:
- app/services/admin_service.py
- app/services/auth_service.py
- app/services/vendor_service.py
✅ Middleware:
- middleware/auth.py
- middleware/vendor_context.py
✅ API Endpoints:
- app/api/v1/admin.py
- app/api/v1/auth.py
- app/api/v1/vendor/vendor.py
✅ Frontend:
- static/admin/login.html
- static/admin/dashboard.html
- static/admin/vendors.html
- static/vendor/login.html
- static/vendor/dashboard.html
- static/js/shared/api-client.js
✅ Scripts:
- scripts/init_db.py
✅ Configuration:
- .env
- requirements.txt
🎉 Congratulations!
If you've made it here and everything works, you've successfully implemented Slice 1 of your multi-tenant ecommerce platform!
What You've Built
✅ Multi-tenant foundation with complete vendor isolation
✅ Admin portal for platform management
✅ Vendor creation with automatic owner account generation
✅ Context detection supporting both subdomain and path-based routing
✅ Secure authentication with JWT tokens
✅ Role-based access control separating admin and vendor users
✅ Database schema with proper relationships
✅ Clean architecture following the vertical slice approach
Ready for Production Features
Your platform now has:
- 🔐 Secure authentication system
- 🏪 Vendor account management
- 👥 User role system
- 🎨 Modern, responsive UI
- 📊 Dashboard with statistics
- 🔄 Vendor context isolation
- 🚀 Scalable architecture
📞 Need Help?
If you encounter issues:
- Check logs: Look at terminal output for errors
- Check browser console: F12 → Console tab
- Check database: Use psql to verify data
- Review this guide: Most issues covered above
- Check documentation: See SLICE_1_IMPLEMENTATION_GUIDE.md
🚀 What's Next?
You're now ready for Slice 2! Here's what's coming:
Slice 2: Vendor Imports Products from Letzshop
- CSV file import from marketplace
- MarketplaceProduct staging table
- Product import UI with file upload
- Background job processing with Celery
- Import history and status tracking
Future Slices
- Slice 3: Product catalog management and publishing
- Slice 4: Customer shopping experience
- Slice 5: Order processing and payments
Happy coding! 🎉 You've built a solid foundation for your multi-tenant ecommerce platform!