# Bundle Stores System - Complete Flow Analysis

## System Overview

This is a **multi-tenant data bundle store system** where:
- **Store Owners** create and manage their own stores
- **Agents (Sub-agents)** work under store owners to sell data bundles
- The system handles data bundle orders, pricing, balance management, and profit tracking

---

## User Roles & Relationships

### 1. **Store Owner** (`role = 'store_owner'`, `is_store_owner = 1`)
- **Creation**: When a user registers via `register.php`, a store is automatically created for them
- **Characteristics**:
  - Owns exactly one store (linked via `stores.owner_id`)
  - Has `role = 'store_owner'` and `is_store_owner = 1` in `agents` table
  - Has `store_id` pointing to their owned store
  - Can create and manage agents (sub-agents)
  - Sets custom pricing for their agents via `store_pricing` table
  - Manages their store's balance and agent balances
  - Can place orders directly (as store owner)
  - Redirected to `pages/store_dashboard.php` on login

### 2. **Agent (Sub-agent)** (`role = 'agent'`, `is_store_owner = 0`)
- **Creation**: 
  - Can register via `register_agent.php` (public registration for a specific store)
  - Can be created by store owner via `StoreManager::createAgentDirectly()`
  - Can be added to store via invitation (existing user)
- **Characteristics**:
  - Has `role = 'agent'` and `is_store_owner = 0`
  - Has `store_id` pointing to the store they belong to
  - Listed in `store_agents` junction table
  - Uses store owner's pricing (from `store_pricing` table)
  - Has their own balance (separate from store owner)
  - Can place orders that debit their balance first, then store owner's balance
  - Redirected to `user_index.php` (agent dashboard) on login

### 3. **Admin** (System Administrator)
- Manages the entire system
- Sets base admin pricing in `agent_pricing_rules` table
- Can view all stores and agents

---

## Database Structure & Relationships

### Core Tables

#### 1. **`agents` Table** (All users - both store owners and agents)
```
- id (PK)
- username
- email
- phone
- password_hash
- balance (individual balance)
- role (ENUM: 'agent', 'super_agent', 'dealers', 'store_owner')
- is_store_owner (0 or 1)
- store_id (FK to stores.id - NULL for store owners, set for agents)
- created_at
```

**Key Points**:
- Store owners: `role='store_owner'`, `is_store_owner=1`, `store_id` = their store ID
- Agents: `role='agent'`, `is_store_owner=0`, `store_id` = their store's ID

#### 2. **`stores` Table**
```
- id (PK)
- store_name
- store_slug (unique URL identifier)
- owner_id (FK to agents.id - the store owner)
- description
- phone
- momo_name
- email
- whatsapp
- address
- status (active/inactive)
- created_at
```

**Relationship**: One store has one owner (`stores.owner_id` → `agents.id`)

#### 3. **`store_agents` Table** (Junction Table)
```
- id (PK)
- store_id (FK to stores.id)
- agent_id (FK to agents.id)
- role (e.g., 'agent')
- status (active/inactive)
- joined_at
```

**Purpose**: Links agents to stores (many-to-many relationship)
- One store can have many agents
- One agent belongs to one store (enforced by `agents.store_id`)

#### 4. **`store_pricing` Table** (Store Owner's Custom Pricing)
```
- id (PK)
- store_id (FK to stores.id)
- network_type (mtn, vodafone, airteltigo, etc.)
- min_size_gb
- max_size_gb
- price_per_gb
- is_active
```

**Purpose**: Store owners set custom pricing for their agents
- Agents use this pricing when placing orders
- Store owner earns profit = (store_pricing price) - (admin base price)

#### 5. **`agent_pricing_rules` Table** (Admin Base Pricing)
```
- id (PK)
- network_type
- role (e.g., 'agent')
- min_size_gb
- max_size_gb
- price_per_gb
- is_active
```

**Purpose**: System-wide base pricing (what store owners pay to admin)

#### 6. **`orders` Table**
```
- id (PK)
- order_reference (unique)
- agent_id (FK to agents.id - who placed the order)
- store_id (FK to stores.id)
- network_type
- package_size
- beneficiary_number
- amount (what customer paid / store owner's price)
- status (pending, processing, completed, failed, etc.)
- created_at
- status_updated_at
```

**Key Points**:
- `agent_id` = who placed the order (store owner or sub-agent)
- `store_id` = which store the order belongs to
- `amount` = customer-facing price (store owner's price)

---

## System Flow

### A. Registration & Store Creation Flow

#### 1. **Store Owner Registration** (`register.php`)
```
User registers → Creates account in agents table
              → Automatically creates store via StoreManager::createStore()
              → Marks user as store owner (role='store_owner', is_store_owner=1)
              → Sets up default pricing from agent_pricing_rules
              → User can now access store dashboard
```

#### 2. **Agent Registration** (`register_agent.php`)
```
Agent visits store page → Clicks "Register as Agent"
                      → Fills registration form
                      → Creates account with role='agent', is_store_owner=0
                      → Sets store_id to the store they're joining
                      → Adds entry to store_agents junction table
                      → Redirects to login
```

#### 3. **Store Owner Creates Agent** (`StoreManager::createAgentDirectly()`)
```
Store owner → Creates agent account
          → Enforces role='agent', is_store_owner=0
          → Sets store_id to store owner's store
          → Adds to store_agents table
```

### B. Order Processing Flow

#### 1. **Agent Places Order** (`api/create_order.php`)

**For Sub-Agent Orders**:
```
1. Agent selects packages and places order
2. System calculates:
   - Store Cost = store_pricing price (what agent pays to store owner)
   - Admin Cost = agent_pricing_rules price (what store owner pays to admin)
3. Check balances:
   - Agent's balance >= Store Cost
   - Store owner's balance >= Admin Cost
4. Debit balances:
   - Agent balance -= Store Cost
   - Store owner balance -= Admin Cost
5. Create order with status='pending'
6. Store owner processes order (manually or automatically)
7. Order sent to external API
8. Status updated to 'completed' or 'failed'
```

**For Store Owner Orders**:
```
1. Store owner places order directly
2. System calculates:
   - Admin Cost = agent_pricing_rules price (what store owner pays)
3. Check balance:
   - Store owner's balance >= Admin Cost
4. Debit balance:
   - Store owner balance -= Admin Cost
5. Create order and process (same as above)
```

#### 2. **Order Processing** (`process_pending_order.php` or `store_paystack_callback.php`)

**For Pending Orders (Payment Required)**:
```
1. Customer pays via Paystack
2. Payment callback received
3. System checks:
   - If sub-agent order: Check agent balance >= store price
   - Check store owner balance >= admin price
4. Debit balances (if not already debited)
5. Send order to external API
6. Update order status
```

### C. Balance Management Flow

#### 1. **Top-Up Flow**

**Store Owner Top-Up** (`api/store_owner_topup.php`):
```
1. Store owner initiates top-up
2. Paystack payment created
3. Payment callback → paystack_callback.php
4. Verify payment
5. Credit store owner's balance
6. Log balance history
7. Redirect to store dashboard
```

**Agent Top-Up** (`api/subagent_topup.php`):
```
1. Agent initiates top-up
2. Paystack payment created
3. Payment callback → paystack_callback.php
4. Verify payment
5. Credit agent's balance
6. Log balance history
7. Redirect to agent dashboard
```

#### 2. **Balance Deduction Flow**

**Sub-Agent Order**:
```
1. Agent balance -= Store Price (store_pricing)
2. Store owner balance -= Admin Price (agent_pricing_rules)
3. Both debits happen in same transaction (atomic)
```

**Store Owner Order**:
```
1. Store owner balance -= Admin Price (agent_pricing_rules)
```

### D. Pricing & Profit Flow

#### 1. **Pricing Hierarchy**

```
Admin Base Price (agent_pricing_rules)
    ↓
Store Owner's Price (store_pricing) ← Store owner sets this for agents
    ↓
Customer Price (orders.amount) ← What customer pays
```

#### 2. **Profit Calculation**

**Store Owner Profit**:
```
Profit = Revenue from Agent Orders - Admin Cost for All Orders

Where:
- Revenue = Sum of (store_pricing price × quantity) from agent orders
- Admin Cost = Sum of (agent_pricing_rules price × quantity) for all orders
```

**Example**:
```
Agent orders 10GB MTN bundle:
- Store Price (what agent pays) = GH₵ 50
- Admin Price (what store owner pays) = GH₵ 45
- Store Owner Profit = GH₵ 50 - GH₵ 45 = GH₵ 5
```

---

## Key Relationships Diagram

```
┌─────────────┐
│   agents    │
│─────────────│
│ id (PK)     │◄─────┐
│ role        │      │
│ is_store_  │      │
│   owner     │      │
│ store_id    │      │
└─────────────┘      │
                     │
         ┌───────────┘
         │
         │ owner_id
         │
┌─────────────┐      ┌──────────────┐
│   stores    │      │ store_agents │
│─────────────│      │──────────────│
│ id (PK)     │◄─────┤ store_id (FK)│
│ owner_id    │      │ agent_id (FK)│
│ store_slug  │      │ status       │
└─────────────┘      └──────────────┘
         │                    │
         │ store_id           │ agent_id
         │                    │
         │            ┌────────┘
         │            │
         │            │
┌─────────────┐      ┌─────────────┐
│store_pricing│      │   orders    │
│─────────────│      │─────────────│
│ store_id(FK)│      │ agent_id(FK)│
│ network_type│      │ store_id(FK)│
│ price_per_gb│      │ amount      │
└─────────────┘      └─────────────┘
```

---

## Security & Validation

### Multi-Layer Security Checks

1. **Role Verification**:
   - `verifyStoreOwner()`: Checks `role='store_owner'`, `is_store_owner=1`, and store ownership
   - `verifyAgent()`: Checks `role='agent'`, `is_store_owner=0`, and store membership

2. **Balance Checks**:
   - All balance operations use database transactions
   - Row-level locking (`FOR UPDATE`) prevents race conditions
   - Balance verification after updates

3. **Access Control**:
   - Store owners can only create agents (not other store owners)
   - Agents can only access their own store's resources
   - Session validation prevents hijacking

---

## Key Files & Their Purposes

### Registration & Authentication
- `register.php` - Store owner registration
- `register_agent.php` - Agent registration under a store
- `login.php` - User authentication
- `user_index.php` - Agent dashboard router

### Store Management
- `app/classes/StoreManager.php` - Core store operations
- `pages/store_dashboard.php` - Store owner dashboard
- `pages/store_pricing.php` - Manage agent pricing

### Order Processing
- `api/create_order.php` - Create orders (API endpoint)
- `process_pending_order.php` - Process pending orders
- `process_store_order.php` - Process store owner orders
- `store_paystack_callback.php` - Payment callback handler

### Balance Management
- `api/store_owner_topup.php` - Store owner top-up
- `api/subagent_topup.php` - Agent top-up
- `paystack_callback.php` - Payment verification
- `app/classes/BalanceHistory.php` - Balance audit trail

### Pricing
- `app/classes/StorePricingManager.php` - Store pricing calculations
- `app/classes/ExternalAPIPricingManager.php` - Admin pricing

---

## Summary

**Store Owners**:
- Own and manage a store
- Set custom pricing for their agents
- Earn profit margin on agent orders
- Manage agent accounts and balances
- Place orders directly

**Agents (Sub-agents)**:
- Work under a store owner
- Use store owner's pricing
- Have separate balance
- Place orders that debit their balance first, then store owner's
- Cannot create other users

**System Flow**:
1. Registration → Store/Agent creation
2. Top-up → Balance credit
3. Order placement → Balance debit → API processing
4. Profit tracking → Revenue - Admin costs

The system ensures clear separation between store owners and agents through multi-layer validation and strict role enforcement.

