Files
orion/docs/architecture/diagrams/vendor-domain-diagrams.md
Samir Boulahtit 0d7915c275 docs: update authentication dependency names across documentation
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>
2025-11-22 18:21:23 +01:00

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