# Company-Vendor Management Architecture ## Overview The Wizamart platform implements a hierarchical multi-tenant architecture where **Companies** are the primary business entities and **Vendors** are storefronts/brands that operate under companies. ``` Company (Business Entity) ├── Owner (User) ├── Contact Information ├── Business Details └── Vendors (Storefronts/Brands) ├── Vendor 1 ├── Vendor 2 └── Vendor N ``` ## Key Concepts ### Company A **Company** represents a business entity on the platform. It contains: - **Owner**: A user account that has full control over the company - **Contact Information**: Business email, phone, website - **Business Details**: Address, tax number - **Status**: Active/Inactive, Verified/Pending ### Vendor A **Vendor** (also called storefront or brand) represents a specific storefront operating under a company. A company can have multiple vendors. - **Unique Identity**: Vendor code and subdomain - **Marketplace Integration**: CSV URLs for product feeds (FR, EN, DE) - **Status**: Active/Inactive, Verified/Pending - **Products**: Each vendor has its own product catalog ## Data Model ### Company Model ```python class Company: id: int name: str description: str | None # Owner (at company level) owner_user_id: int # FK to User # Contact Information contact_email: str contact_phone: str | None website: str | None # Business Details business_address: str | None tax_number: str | None # Status is_active: bool is_verified: bool # Timestamps created_at: datetime updated_at: datetime # Relationships owner: User # Company owner vendors: list[Vendor] # Storefronts under this company ``` ### Vendor Model ```python class Vendor: id: int company_id: int # FK to Company vendor_code: str # Unique identifier (e.g., "TECHSTORE") subdomain: str # URL subdomain (e.g., "tech-store") name: str description: str | None # Marketplace URLs (brand-specific) letzshop_csv_url_fr: str | None letzshop_csv_url_en: str | None letzshop_csv_url_de: str | None # Status is_active: bool is_verified: bool # Timestamps created_at: datetime updated_at: datetime # Relationships company: Company # Parent company (owner is accessed via company.owner) ``` ## Key Design Decisions ### 1. Owner at Company Level Only Previously, each vendor had its own `owner_user_id`. This has been refactored: - **Before**: `Vendor.owner_user_id` - each vendor had a separate owner - **After**: `Company.owner_user_id` - ownership is at company level **Rationale**: A business entity (company) should have a single owner who can manage all storefronts. This simplifies: - User management - Permission handling - Ownership transfer operations ### 2. Contact Information at Company Level Business contact information (email, phone, website, address, tax number) is now stored at the company level: - **Before**: Vendors had contact fields - **After**: Contact info on Company model, vendors reference parent company **Rationale**: Business details are typically the same across all storefronts of a company. ### 3. Clean Architecture The `Vendor.owner_user_id` field has been completely removed: - Ownership is determined solely via the company relationship - Use `vendor.company.owner_user_id` to get the owner - Use `vendor.company.owner` to get the owner User object ## API Endpoints ### Company Management (Admin) | Method | Endpoint | Description | |--------|----------|-------------| | POST | `/api/v1/admin/companies` | Create company with owner | | GET | `/api/v1/admin/companies` | List all companies | | GET | `/api/v1/admin/companies/{id}` | Get company details | | PUT | `/api/v1/admin/companies/{id}` | Update company | | PUT | `/api/v1/admin/companies/{id}/verification` | Toggle verification | | PUT | `/api/v1/admin/companies/{id}/status` | Toggle active status | | POST | `/api/v1/admin/companies/{id}/transfer-ownership` | Transfer ownership | | DELETE | `/api/v1/admin/companies/{id}` | Delete company | ### Vendor Management (Admin) | Method | Endpoint | Description | |--------|----------|-------------| | POST | `/api/v1/admin/vendors` | Create vendor under company | | GET | `/api/v1/admin/vendors` | List all vendors | | GET | `/api/v1/admin/vendors/{id}` | Get vendor details | | PUT | `/api/v1/admin/vendors/{id}` | Update vendor | | PUT | `/api/v1/admin/vendors/{id}/verification` | Toggle verification | | PUT | `/api/v1/admin/vendors/{id}/status` | Toggle active status | | DELETE | `/api/v1/admin/vendors/{id}` | Delete vendor | ### User Management (Admin) | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/v1/admin/users` | List all users | | GET | `/api/v1/admin/users/search?q={query}` | Search users by name/email | | PUT | `/api/v1/admin/users/{id}/status` | Toggle user status | | GET | `/api/v1/admin/users/stats` | Get user statistics | ## Service Layer ### CompanyService (`app/services/company_service.py`) Primary service for company operations: - `create_company_with_owner()` - Creates company and owner user account - `get_company_by_id()` - Get company with vendors loaded - `get_companies()` - Paginated list with filtering - `update_company()` - Update company fields - `toggle_verification()` - Verify/unverify company - `toggle_active()` - Activate/deactivate company - `transfer_ownership()` - Transfer to new owner - `delete_company()` - Delete company (requires no vendors) ### AdminService (`app/services/admin_service.py`) Admin-specific vendor operations: - `create_vendor()` - Create vendor under existing company - `get_all_vendors()` - Paginated list with company relationship - `update_vendor()` - Update vendor fields - `verify_vendor()` - Toggle verification - `toggle_vendor_status()` - Toggle active status - `delete_vendor()` - Delete vendor ### VendorService (`app/services/vendor_service.py`) Self-service vendor operations (for company owners): - `create_vendor()` - Create vendor (requires company_id, validates ownership) - `get_vendors()` - Get vendors with access control - `get_vendor_by_code()` - Get single vendor ## Creating a New Company with Vendors ### Via Admin API ```python # 1. Create company with owner POST /api/v1/admin/companies { "name": "Tech Solutions Ltd", "owner_email": "owner@techsolutions.com", "contact_email": "info@techsolutions.com", "contact_phone": "+352 123 456", "website": "https://techsolutions.com", "business_address": "123 Tech Street, Luxembourg", "tax_number": "LU12345678" } # Response includes temporary password for owner # 2. Create vendor under company POST /api/v1/admin/vendors { "company_id": 1, "vendor_code": "TECHSTORE", "subdomain": "tech-store", "name": "Tech Store", "description": "Consumer electronics storefront" } ``` ## Ownership Transfer Ownership transfer is a critical operation available at the company level: 1. **Admin initiates transfer** via `/api/v1/admin/companies/{id}/transfer-ownership` 2. **Company owner changes** - `Company.owner_user_id` updated 3. **All vendors affected** - Vendors inherit new owner via company relationship 4. **Audit trail** - Transfer reason logged ```python POST /api/v1/admin/companies/1/transfer-ownership { "new_owner_user_id": 42, "confirm_transfer": true, "transfer_reason": "Business acquisition" } ``` ## Admin UI Pages ### Company List Page (`/admin/companies`) - Lists all companies with owner, vendor count, and status - **Actions**: View, Edit, Delete (disabled if company has vendors) - Stats cards showing total, verified, active companies ### Company Detail Page (`/admin/companies/{id}`) - **Quick Actions** - Edit Company, Delete Company - **Status Cards** - Verification, Active status, Vendor count, Created date - **Information Sections** - Basic info, Contact info, Business details, Owner info - **Vendors Table** - Lists all vendors under this company with links - **More Actions** - Create Vendor button ### Company Edit Page (`/admin/companies/{id}/edit`) - **Quick Actions** - Verify/Unverify, Activate/Deactivate - **Edit Form** - Company details, contact info, business details - **Statistics** - Vendor counts (readonly) - **More Actions** - Transfer Ownership, Delete Company ### Vendor Detail Page (`/admin/vendors/{code}`) - **Quick Actions** - Edit Vendor, Delete Vendor - **Status Cards** - Verification, Active status, Created/Updated dates - **Information Sections** - Basic info, Contact info, Business details, Owner info - **More Actions** - View Parent Company link, Customize Theme ### Transfer Ownership Modal A modal dialog for transferring company ownership: - **User Search** - Autocomplete search by username or email - **Selected User Display** - Shows selected user with option to clear - **Transfer Reason** - Optional field for audit trail - **Confirmation Checkbox** - Required before transfer - **Validation** - Inline error messages for missing fields ## Best Practices ### Creating Vendors Always use `company_id` when creating vendors: ```python # Correct vendor_data = VendorCreate( company_id=company.id, vendor_code="MYSTORE", subdomain="my-store", name="My Store" ) # Incorrect (old pattern - don't use) vendor_data = VendorCreate( owner_email="owner@example.com", # No longer supported ... ) ``` ### Accessing Owner Information Use the company relationship: ```python # Get owner User object owner = vendor.company.owner # Get owner details owner_email = vendor.company.owner.email owner_id = vendor.company.owner_user_id ``` ### Checking Permissions For vendor operations, check company ownership: ```python def can_manage_vendor(user, vendor): if user.role == "admin": return True return vendor.company.owner_user_id == user.id ``` ## Migration Notes The `Vendor.owner_user_id` column has been removed. If you have an existing database: 1. Run the migration: `alembic upgrade head` 2. This will drop the `owner_user_id` column from vendors table 3. Ownership is now determined via `vendor.company.owner_user_id` If migrating from an older vendor-centric model: 1. Create companies for existing vendors (group by owner) 2. Assign vendors to companies via `company_id` 3. Copy contact info from vendors to companies 4. Run the migration to drop the old owner_user_id column ## Related Documentation - [Multi-Tenant Architecture](multi-tenant.md) - [Authentication & RBAC](auth-rbac.md) - [Models Structure](models-structure.md) - [Admin Integration Guide](../backend/admin-integration-guide.md)