# Merchant-Store Management Architecture

## Overview

The Orion platform implements a hierarchical multi-tenant architecture where **Merchants** are the primary business entities and **Stores** are storefronts/brands that operate under merchants.

```
Merchant (Business Entity)
├── Owner (User)
├── Contact Information
├── Business Details
└── Stores (Storefronts/Brands)
    ├── Store 1
    ├── Store 2
    └── Store N
```

## Key Concepts

### Merchant
A **Merchant** represents a business entity on the platform. It contains:

- **Owner**: A user account that has full control over the merchant
- **Contact Information**: Business email, phone, website
- **Business Details**: Address, tax number
- **Status**: Active/Inactive, Verified/Pending

### Store
A **Store** (also called storefront or brand) represents a specific storefront operating under a merchant. A merchant can have multiple stores.

- **Unique Identity**: Store code and subdomain
- **Marketplace Integration**: CSV URLs for product feeds (FR, EN, DE)
- **Status**: Active/Inactive, Verified/Pending
- **Products**: Each store has its own product catalog

## Data Model

### Merchant Model
```python
class Merchant:
    id: int
    name: str
    description: str | None

    # Owner (at merchant 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  # Merchant owner
    stores: list[Store]  # Storefronts under this merchant
```

### Store Model
```python
class Store:
    id: int
    merchant_id: int  # FK to Merchant
    store_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
    merchant: Merchant  # Parent merchant (owner is accessed via merchant.owner)
```

## Key Design Decisions

### 1. Owner at Merchant Level Only
Previously, each store had its own `owner_user_id`. This has been refactored:

- **Before**: `Store.owner_user_id` - each store had a separate owner
- **After**: `Merchant.owner_user_id` - ownership is at merchant level

**Rationale**: A business entity (merchant) should have a single owner who can manage all storefronts. This simplifies:
- User management
- Permission handling
- Ownership transfer operations

### 2. Contact Information at Merchant Level
Business contact information (email, phone, website, address, tax number) is now stored at the merchant level:

- **Before**: Stores had contact fields
- **After**: Contact info on Merchant model, stores reference parent merchant

**Rationale**: Business details are typically the same across all storefronts of a merchant.

### 3. Clean Architecture
The `Store.owner_user_id` field has been completely removed:

- Ownership is determined solely via the merchant relationship
- Use `store.merchant.owner_user_id` to get the owner
- Use `store.merchant.owner` to get the owner User object

## API Endpoints

### Merchant Management (Admin)
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/v1/admin/merchants` | Create merchant with owner |
| GET | `/api/v1/admin/merchants` | List all merchants |
| GET | `/api/v1/admin/merchants/{id}` | Get merchant details |
| PUT | `/api/v1/admin/merchants/{id}` | Update merchant |
| PUT | `/api/v1/admin/merchants/{id}/verification` | Toggle verification |
| PUT | `/api/v1/admin/merchants/{id}/status` | Toggle active status |
| POST | `/api/v1/admin/merchants/{id}/transfer-ownership` | Transfer ownership |
| DELETE | `/api/v1/admin/merchants/{id}` | Delete merchant |

### Store Management (Admin)
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/v1/admin/stores` | Create store under merchant |
| GET | `/api/v1/admin/stores` | List all stores |
| GET | `/api/v1/admin/stores/{id}` | Get store details |
| PUT | `/api/v1/admin/stores/{id}` | Update store |
| PUT | `/api/v1/admin/stores/{id}/verification` | Toggle verification |
| PUT | `/api/v1/admin/stores/{id}/status` | Toggle active status |
| DELETE | `/api/v1/admin/stores/{id}` | Delete store |

### 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

### MerchantService (`app/services/merchant_service.py`)
Primary service for merchant operations:

- `create_merchant_with_owner()` - Creates merchant and owner user account
- `get_merchant_by_id()` - Get merchant with stores loaded
- `get_merchants()` - Paginated list with filtering
- `update_merchant()` - Update merchant fields
- `toggle_verification()` - Verify/unverify merchant
- `toggle_active()` - Activate/deactivate merchant
- `transfer_ownership()` - Transfer to new owner
- `delete_merchant()` - Delete merchant (requires no stores)

### AdminService (`app/services/admin_service.py`)
Admin-specific store operations:

- `create_store()` - Create store under existing merchant
- `get_all_stores()` - Paginated list with merchant relationship
- `update_store()` - Update store fields
- `verify_store()` - Toggle verification
- `toggle_store_status()` - Toggle active status
- `delete_store()` - Delete store

### StoreService (`app/services/store_service.py`)
Self-service store operations (for merchant owners):

- `create_store()` - Create store (requires merchant_id, validates ownership)
- `get_stores()` - Get stores with access control
- `get_store_by_code()` - Get single store

## Creating a New Merchant with Stores

### Via Admin API
```python
# 1. Create merchant with owner
POST /api/v1/admin/merchants
{
    "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 store under merchant
POST /api/v1/admin/stores
{
    "merchant_id": 1,
    "store_code": "TECHSTORE",
    "subdomain": "tech-store",
    "name": "Tech Store",
    "description": "Consumer electronics storefront"
}
```

## Ownership Transfer

Ownership transfer is a critical operation available at the merchant level:

1. **Admin initiates transfer** via `/api/v1/admin/merchants/{id}/transfer-ownership`
2. **Merchant owner changes** - `Merchant.owner_user_id` updated
3. **All stores affected** - Stores inherit new owner via merchant relationship
4. **Audit trail** - Transfer reason logged

```python
POST /api/v1/admin/merchants/1/transfer-ownership
{
    "new_owner_user_id": 42,
    "confirm_transfer": true,
    "transfer_reason": "Business acquisition"
}
```

## Admin UI Pages

### Merchant List Page (`/admin/merchants`)
- Lists all merchants with owner, store count, and status
- **Actions**: View, Edit, Delete (disabled if merchant has stores)
- Stats cards showing total, verified, active merchants

### Merchant Detail Page (`/admin/merchants/{id}`)
- **Quick Actions** - Edit Merchant, Delete Merchant
- **Status Cards** - Verification, Active status, Store count, Created date
- **Information Sections** - Basic info, Contact info, Business details, Owner info
- **Stores Table** - Lists all stores under this merchant with links
- **More Actions** - Create Store button

### Merchant Edit Page (`/admin/merchants/{id}/edit`)
- **Quick Actions** - Verify/Unverify, Activate/Deactivate
- **Edit Form** - Merchant details, contact info, business details
- **Statistics** - Store counts (readonly)
- **More Actions** - Transfer Ownership, Delete Merchant

### Store Detail Page (`/admin/stores/{code}`)
- **Quick Actions** - Edit Store, Delete Store
- **Status Cards** - Verification, Active status, Created/Updated dates
- **Information Sections** - Basic info, Contact info, Business details, Owner info
- **More Actions** - View Parent Merchant link, Customize Theme

### Transfer Ownership Modal
A modal dialog for transferring merchant 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 Stores
Always use `merchant_id` when creating stores:
```python
# Correct
store_data = StoreCreate(
    merchant_id=merchant.id,
    store_code="MYSTORE",
    subdomain="my-store",
    name="My Store"
)

# Incorrect (old pattern - don't use)
store_data = StoreCreate(
    owner_email="owner@example.com",  # No longer supported
    ...
)
```

### Accessing Owner Information
Use the merchant relationship:
```python
# Get owner User object
owner = store.merchant.owner

# Get owner details
owner_email = store.merchant.owner.email
owner_id = store.merchant.owner_user_id
```

### Checking Permissions
For store operations, check merchant ownership:
```python
def can_manage_store(user, store):
    if user.role == "admin":
        return True
    return store.merchant.owner_user_id == user.id
```

## Migration Notes

The `Store.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 stores table
3. Ownership is now determined via `store.merchant.owner_user_id`

If migrating from an older store-centric model:

1. Create merchants for existing stores (group by owner)
2. Assign stores to merchants via `merchant_id`
3. Copy contact info from stores to merchants
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)
