Updated all documentation to use correct authentication dependency names: - HTML pages: get_current_admin_from_cookie_or_header, get_current_vendor_from_cookie_or_header, get_current_customer_from_cookie_or_header - API endpoints: get_current_admin_api, get_current_vendor_api, get_current_customer_api Changes: - Updated authentication flow diagrams with correct dependency names for admin and vendor flows - Added comprehensive customer/shop authentication flow documentation - Updated cookie isolation architecture to show all three contexts (admin, vendor, shop) - Expanded security boundary enforcement diagram to include shop routes - Added customer cross-context prevention examples - Updated all code examples in frontend and backend documentation - Fixed import statements to use app.api.deps instead of app.core.auth Files updated: - docs/api/authentication-flow-diagrams.md (added customer flows) - docs/frontend/admin/page-templates.md - docs/frontend/admin/architecture.md - docs/frontend/shared/ui-components.md - docs/frontend/shared/sidebar.md - docs/development/exception-handling.md - docs/architecture/diagrams/vendor-domain-diagrams.md - docs/backend/admin-integration-guide.md - docs/backend/admin-feature-integration.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
28 KiB
28 KiB
Vendor Domains - Architecture Diagram
System Architecture Overview
┌─────────────────────────────────────────────────────────────────┐
│ CLIENT REQUEST │
│ POST /vendors/1/domains │
│ {"domain": "myshop.com"} │
└────────────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ ENDPOINT LAYER │
│ app/api/v1/admin/vendor_domains.py │
├─────────────────────────────────────────────────────────────────┤
│ │
│ @router.post("/{vendor_id}/domains") │
│ def add_vendor_domain( │
│ vendor_id: int, │
│ domain_data: VendorDomainCreate, ◄───┐ │
│ db: Session, │ │
│ current_admin: User │ │
│ ): │ │
│ domain = vendor_domain_service │ │
│ .add_domain(...) │ │
│ return VendorDomainResponse(...) │ │
│ │ │
└─────────────────────┬───────────────────────┼───────────────────┘
│ │
│ │
┌────────────▼──────────┐ ┌────────▼─────────┐
│ Pydantic Validation │ │ Authentication │
│ (Auto by FastAPI) │ │ Dependency │
└────────────┬──────────┘ └──────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ SERVICE LAYER │
│ app/services/vendor_domain_service.py │
├─────────────────────────────────────────────────────────────────┤
│ │
│ class VendorDomainService: │
│ │
│ def add_domain(db, vendor_id, domain_data): │
│ ┌─────────────────────────────────────┐ │
│ │ 1. Verify vendor exists │ │
│ │ 2. Check domain limit │ │
│ │ 3. Validate domain format │ │
│ │ 4. Check uniqueness │ │
│ │ 5. Handle primary domain logic │ │
│ │ 6. Create database record │ │
│ │ 7. Generate verification token │ │
│ └─────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────┐ │
│ │ Raises Custom Exceptions │ │
│ │ - VendorNotFoundException │ │
│ │ - DomainAlreadyExistsException │ │
│ │ - MaxDomainsReachedException │ │
│ └─────────────────────────────────────┘ │
│ │
└─────────────────────┬───────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ DATABASE LAYER │
│ models/database/vendor_domain.py │
├─────────────────────────────────────────────────────────────────┤
│ │
│ class VendorDomain(Base): │
│ id: int │
│ vendor_id: int (FK) │
│ domain: str (unique) │
│ is_primary: bool │
│ is_active: bool │
│ is_verified: bool │
│ verification_token: str │
│ ssl_status: str │
│ ... │
│ │
└─────────────────────┬───────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ DATABASE │
│ PostgreSQL / MySQL │
└─────────────────────────────────────────────────────────────────┘
Request Flow Diagram
┌──────────┐
│ Client │
└────┬─────┘
│ POST /vendors/1/domains
│ {"domain": "myshop.com", "is_primary": true}
│
▼
┌────────────────────────────────────────────┐
│ FastAPI Router │
│ ┌──────────────────────────────────────┐ │
│ │ 1. URL Routing │ │
│ │ 2. Pydantic Validation │ │
│ │ 3. Dependency Injection │ │
│ │ - get_db() │ │
│ │ - get_current_admin_api() │ │
│ └──────────────────────────────────────┘ │
└────────────────┬───────────────────────────┘
│
▼
┌────────────────────────────────────────────┐
│ Endpoint Function │
│ add_vendor_domain() │
│ │
│ ✓ Receives validated data │
│ ✓ Has DB session │
│ ✓ Has authenticated admin user │
│ ✓ Calls service layer │
│ ✓ Returns response model │
└────────────────┬───────────────────────────┘
│
▼
┌────────────────────────────────────────────┐
│ Service Layer │
│ vendor_domain_service.add_domain() │
│ │
│ Business Logic: │
│ ┌──────────────────────────────────────┐ │
│ │ Vendor Validation │ │
│ │ ├─ Check vendor exists │ │
│ │ └─ Get vendor object │ │
│ │ │ │
│ │ Limit Checking │ │
│ │ ├─ Count existing domains │ │
│ │ └─ Enforce max limit │ │
│ │ │ │
│ │ Domain Validation │ │
│ │ ├─ Normalize format │ │
│ │ ├─ Check reserved subdomains │ │
│ │ └─ Validate regex pattern │ │
│ │ │ │
│ │ Uniqueness Check │ │
│ │ └─ Query existing domains │ │
│ │ │ │
│ │ Primary Domain Logic │ │
│ │ └─ Unset other primary domains │ │
│ │ │ │
│ │ Create Record │ │
│ │ ├─ Generate verification token │ │
│ │ ├─ Set initial status │ │
│ │ └─ Create VendorDomain object │ │
│ │ │ │
│ │ Database Transaction │ │
│ │ ├─ db.add() │ │
│ │ ├─ db.commit() │ │
│ │ └─ db.refresh() │ │
│ └──────────────────────────────────────┘ │
└────────────────┬───────────────────────────┘
│
▼
┌────────────────────────────────────────────┐
│ Database │
│ INSERT INTO vendor_domains ... │
└────────────────┬───────────────────────────┘
│
▼
┌────────────────────────────────────────────┐
│ Return to Endpoint │
│ ← VendorDomain object │
└────────────────┬───────────────────────────┘
│
▼
┌────────────────────────────────────────────┐
│ Endpoint Response │
│ VendorDomainResponse( │
│ id=1, │
│ domain="myshop.com", │
│ is_verified=False, │
│ verification_token="abc123...", │
│ ... │
│ ) │
└────────────────┬───────────────────────────┘
│
▼
┌────────────────────────────────────────────┐
│ FastAPI Serialization │
│ Convert to JSON │
└────────────────┬───────────────────────────┘
│
▼
┌────────────────────────────────────────────┐
│ HTTP Response (201 Created) │
│ { │
│ "id": 1, │
│ "domain": "myshop.com", │
│ "is_verified": false, │
│ "verification_token": "abc123...", │
│ ... │
│ } │
└────────────────┬───────────────────────────┘
│
▼
┌──────────┐
│ Client │
└──────────┘
Error Handling Flow
┌──────────┐
│ Client │
└────┬─────┘
│ POST /vendors/1/domains
│ {"domain": "existing.com"}
│
▼
┌────────────────────────────────────────────┐
│ Service Layer │
│ │
│ def add_domain(...): │
│ if self._domain_exists(db, domain): │
│ raise VendorDomainAlready │
│ ExistsException( │
│ domain="existing.com", │
│ existing_vendor_id=2 │
│ ) │
└────────────────┬───────────────────────────┘
│
│ Exception raised
│
▼
┌────────────────────────────────────────────┐
│ Exception Handler │
│ app/exceptions/handler.py │
│ │
│ @app.exception_handler(WizamartException) │
│ async def custom_exception_handler(...): │
│ return JSONResponse( │
│ status_code=exc.status_code, │
│ content=exc.to_dict() │
│ ) │
└────────────────┬───────────────────────────┘
│
▼
┌────────────────────────────────────────────┐
│ HTTP Response (409 Conflict) │
│ { │
│ "error_code": "VENDOR_DOMAIN_ │
│ ALREADY_EXISTS", │
│ "message": "Domain 'existing.com' │
│ is already registered", │
│ "status_code": 409, │
│ "details": { │
│ "domain": "existing.com", │
│ "existing_vendor_id": 2 │
│ } │
│ } │
└────────────────┬───────────────────────────┘
│
▼
┌──────────┐
│ Client │
└──────────┘
Component Interaction Diagram
┌─────────────────┐
│ Endpoints │ ◄─── HTTP Requests from client
│ (HTTP Layer) │ ───► HTTP Responses to client
└────────┬────────┘
│ Calls
│
▼
┌─────────────────┐
│ Service │ ◄─── Business logic
│ Layer │ ───► Returns domain objects
└────────┬────────┘ or raises exceptions
│ Uses
│
├──────────────────┐
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Database │ │ Exceptions │
│ Models │ │ (Custom) │
└─────────────────┘ └─────────────────┘
│ │
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ SQLAlchemy │ │ Exception │
│ ORM │ │ Handler │
└─────────────────┘ └─────────────────┘
│ │
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Database │ │ JSON Error │
│ (PostgreSQL) │ │ Response │
└─────────────────┘ └─────────────────┘
Data Flow for Domain Verification
Step 1: Add Domain
┌──────────┐
│ Admin │ POST /vendors/1/domains
└────┬─────┘ {"domain": "myshop.com"}
│
▼
┌────────────────────────────────────┐
│ System creates domain record │
│ - domain: "myshop.com" │
│ - is_verified: false │
│ - verification_token: "abc123..." │
└────────────────────────────────────┘
Step 2: Get Instructions
┌──────────┐
│ Admin │ GET /domains/1/verification-instructions
└────┬─────┘
│
▼
┌────────────────────────────────────┐
│ System returns instructions: │
│ "Add TXT record: │
│ _wizamart-verify.myshop.com │
│ Value: abc123..." │
└────────────────────────────────────┘
Step 3: Vendor Adds DNS Record
┌──────────┐
│ Vendor │ Adds TXT record at DNS provider
└────┬─────┘
│
▼
┌────────────────────────────────────┐
│ DNS Provider (GoDaddy/etc) │
│ _wizamart-verify.myshop.com TXT │
│ "abc123..." │
└────────────────────────────────────┘
Step 4: Verify Domain
┌──────────┐
│ Admin │ POST /domains/1/verify
└────┬─────┘
│
▼
┌────────────────────────────────────┐
│ System: │
│ 1. Queries DNS for TXT record │
│ 2. Checks token matches │
│ 3. Updates domain: │
│ - is_verified: true │
│ - verified_at: now() │
└────────────────────────────────────┘
Step 5: Activate Domain
┌──────────┐
│ Admin │ PUT /domains/1 {"is_active": true}
└────┬─────┘
│
▼
┌────────────────────────────────────┐
│ System activates domain: │
│ - is_active: true │
│ - Domain now routes to vendor │
└────────────────────────────────────┘
Result: Domain Active!
┌──────────────┐
│ Customer │ Visits https://myshop.com
└──────┬───────┘
│
▼
┌────────────────────────────────────┐
│ Middleware detects custom domain │
│ Routes to Vendor 1 │
└────────────────────────────────────┘
File Structure Visual
project/
│
├── app/
│ ├── api/
│ │ └── v1/
│ │ └── admin/
│ │ ├── vendors.py ✓ Existing (reference)
│ │ └── vendor_domains.py ★ NEW (endpoints)
│ │
│ ├── services/
│ │ ├── vendor_service.py ✓ Existing (reference)
│ │ └── vendor_domain_service.py ★ NEW (business logic)
│ │
│ └── exceptions/
│ ├── __init__.py ✓ UPDATE (add exports)
│ ├── base.py ✓ Existing
│ ├── auth.py ✓ Existing
│ ├── admin.py ✓ Existing
│ └── vendor_domain.py ★ NEW (custom exceptions)
│
└── models/
├── schema/
│ ├── vendor.py ✓ Existing
│ └── vendor_domain.py ★ NEW (pydantic schemas)
│
└── database/
├── vendor.py ✓ UPDATE (add domains relationship)
└── vendor_domain.py ✓ Existing (database model)
Legend:
★ NEW - Files to create
✓ Existing - Files already exist
✓ UPDATE - Files to modify
Separation of Concerns Visual
┌─────────────────────────────────────────────────────────────┐
│ ENDPOINT LAYER │
│ - HTTP request/response │
│ - FastAPI decorators │
│ - Dependency injection │
│ - Response models │
│ - Documentation │
│ │
│ ✓ No business logic │
│ ✓ No database operations │
│ ✓ No validation (handled by Pydantic) │
└──────────────────────┬──────────────────────────────────────┘
│
│ Calls
│
┌──────────────────────▼──────────────────────────────────────┐
│ SERVICE LAYER │
│ - Business logic │
│ - Database operations │
│ - Transaction management │
│ - Error handling │
│ - Validation logic │
│ - Logging │
│ │
│ ✓ Reusable methods │
│ ✓ Unit testable │
│ ✓ No HTTP concerns │
└──────────────────────┬──────────────────────────────────────┘
│
│ Uses
│
┌──────────────────────▼──────────────────────────────────────┐
│ DATABASE LAYER │
│ - SQLAlchemy models │
│ - Table definitions │
│ - Relationships │
│ - Database constraints │
│ │
│ ✓ Pure data models │
│ ✓ No business logic │
└─────────────────────────────────────────────────────────────┘
This architecture ensures:
- ✅ Clean separation of concerns
- ✅ Easy to test each layer
- ✅ Reusable business logic
- ✅ Maintainable codebase
- ✅ Follows SOLID principles