388 lines
10 KiB
Markdown
388 lines
10 KiB
Markdown
# 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:
|
||
|
||
```python
|
||
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:
|
||
|
||
```bash
|
||
# 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:
|
||
|
||
```python
|
||
# 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:
|
||
```bash
|
||
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:
|
||
|
||
```python
|
||
from app.api.v1 import admin
|
||
|
||
api_router.include_router(
|
||
admin.router,
|
||
prefix="/admin",
|
||
tags=["admin"]
|
||
)
|
||
```
|
||
|
||
### Step 6: Start the Application
|
||
|
||
```bash
|
||
# 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:
|
||
```sql
|
||
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');
|
||
```
|
||
|
||
2. 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
|
||
|
||
```bash
|
||
# 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
|
||
python scripts/create_admin.py
|
||
```
|
||
|
||
### Issue: Vendor creation returns 401
|
||
**Solution**: Check that JWT token is valid and not expired
|
||
```javascript
|
||
// In browser console
|
||
localStorage.getItem('admin_token')
|
||
```
|
||
|
||
### Issue: Vendor context not detected
|
||
**Solution**: Check middleware is registered in `main.py`:
|
||
```python
|
||
app.middleware("http")(vendor_context_middleware)
|
||
```
|
||
|
||
### Issue: Database foreign key error
|
||
**Solution**: Run migrations in correct order:
|
||
```bash
|
||
alembic upgrade head
|
||
```
|
||
|
||
## 📊 Success Metrics
|
||
|
||
Slice 1 is complete when:
|
||
|
||
- [x] Admin can log into admin interface
|
||
- [x] Admin can create new vendors
|
||
- [x] System generates vendor owner credentials
|
||
- [x] Vendor owner can log into vendor-specific interface
|
||
- [x] Vendor context detection works in dev and production modes
|
||
- [x] Database properly isolates vendor data
|
||
- [x] All tests pass
|
||
- [x] 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)
|
||
|
||
## 📚 Related Documentation
|
||
|
||
- [Complete Project Structure](14.updated_complete_project_structure_final.md)
|
||
- [Naming Conventions](6.complete_naming_convention.md)
|
||
- [Application Workflows](13.updated_application_workflows_final.md)
|
||
- [Vertical Slice Roadmap](3.vertical_slice_roadmap.md)
|