# Controller Patterns

This document details the controller architecture, patterns, and conventions used in the BuyerKiosk application.

## Directory Structure

```
userfrosting/controllers/
├── Root Controllers (10)
│   ├── AccountController.php          # Authentication
│   ├── AdminController.php            # Site settings
│   ├── BaseController.php             # Foundation class
│   ├── EmployeeApiController.php      # Employee CRUD
│   ├── EmployeeInvitationController.php
│   ├── GroupController.php            # Permission groups
│   ├── InstallController.php          # Installation
│   ├── UserController.php             # User management
│   ├── UserEmployeeLinkController.php # User-Employee links
│   └── UserFrosting.php               # Slim extension
│
├── Backstock/                  (8 controllers)
├── BuyerKiosk/                 (3 controllers)
├── Workbook/                   (8 controllers)
├── Support/                    (4 controllers)
├── DigitalSign/                (6 controllers)
├── Cash/                       (2 controllers)
├── SMS/                        (1 controller)
├── Sales/                      (1 controller)
├── Stats/                      (1 controller)
├── MobileApi/                  (1 controller)
├── SellerMarketing/            (1 controller)
├── ServiceQueue/               (1 controller)
├── SimpleQueue/                (1 controller)
├── FiveStars/                  (4 controllers)
├── QuickBooks/                 (1 controller)
├── Shopify/                    (1 controller)
├── Customers/                  (1 controller)
├── CustomerSurvey/             (1 controller)
├── CustomerAlert/              (1 controller)
├── DailyReport/                (1 controller)
├── WhenIWork/                  (2 controllers)
├── ConstantContact/            (2 controllers)
└── Billing/                    (1 controller)
```

**Total: 63 PHP files across 24 subdirectories**

## Controller Categories

### 1. Page Controllers
Render Twig templates for web pages.

**Characteristics**:
- Extend `UserFrosting\BaseController` or namespace-specific base
- Methods follow `page{FeatureName}($typeNum)` pattern
- Use `$app->render()` for template rendering
- Check permissions before rendering

**Example**:
```php
namespace BuyerKiosk\Workbook;

class WorkbookPageController extends \UserFrosting\BaseController
{
    public function pageWorkbook($typeNum)
    {
        $app = $this->_app;

        // Permission check
        if (!$app->user->checkStoreGroup($typeNum)) {
            $app->notAuthorized();
        }

        // Store initialization
        $storeController = new \BuyerKiosk\StoreController($typeNum);
        $store = $storeController->getStore();

        // Render template
        $app->render('themes/default/workspace/workspace.html', [
            'typeNum' => $typeNum,
            'store' => $store
        ]);
    }
}
```

### 2. API Controllers
Return JSON responses for AJAX/API calls.

**Characteristics**:
- Often standalone (no BaseController parent)
- Methods follow REST pattern: `get*`, `create*`, `update*`, `delete*`
- Return JSON via `$app->response->setBody(json_encode(...))`
- May include API key verification

**Example**:
```php
namespace BuyerKiosk\Stats;

class StatsApiController
{
    public function getTodaysStoreStats($typeNum)
    {
        $app = $this->_app;

        $storeController = new \BuyerKiosk\StoreController($typeNum);
        $store = $storeController->getStore();
        $db = dbConnectByName($store->getDbName());

        $stats = [/* ... */];

        $app->response->setBody(json_encode($stats));
    }
}
```

### 3. Service Controllers
Utility/business logic with no direct page rendering.

**Characteristics**:
- No Slim `$app` dependency (may receive via constructor)
- Redis or in-memory caching
- Focused on specific business operations

**Example**:
```php
namespace BuyerKiosk;

class StoreController
{
    private $typeNum;

    public function __construct($typeNum)
    {
        $this->typeNum = $typeNum;
    }

    public function getStore()
    {
        // Try cache first
        $store = $this->getStoreFromCache();
        if (!$store) {
            $store = $this->getStoreFromDB();
            $this->storeStoreInCache($store);
        }
        return $store;
    }
}
```

## Inheritance Hierarchy

```
Slim Framework
    │
    └── UserFrosting\BaseController
            ├── UserFrosting\AccountController
            ├── UserFrosting\AdminController
            ├── UserFrosting\UserController
            ├── UserFrosting\GroupController
            │
            └── BuyerKiosk\{Feature}Controller
                    ├── Backstock\BackstockController
                    ├── Support\SupportPageController
                    ├── Workbook\WorkbookPageController
                    └── [Most feature controllers]

    └── BuyerKiosk\FiveStars\BaseController (intermediate)
            ├── FiveStars\StoreController
            └── FiveStars\RewardController

    └── Standalone (no extends)
            ├── BuyerKiosk\StoreController (caching)
            ├── MobileApi\MobileApiController
            ├── Stats\StatsApiController
            └── Support\SupportApiController
```

## Method Naming Conventions

| Prefix | Purpose | Example |
|--------|---------|---------|
| `page*` | Render template page | `pageWorkbook()`, `pageBackStock()` |
| `get*` | Retrieve resource(s) | `getCustomersList()`, `getTodayTasks()` |
| `create*` | Create new resource | `createUser()`, `createTask()` |
| `update*` | Modify existing resource | `updateUser()`, `updateTask()` |
| `delete*` | Remove resource | `deleteUser()`, `deleteTask()` |
| Action verbs | Direct actions | `login()`, `logout()`, `punchIn()` |

## Permission Patterns

### Framework-Level Access
```php
if (!$app->user->checkAccess('uri_store_settings')) {
    $app->notAuthorized();
}
```

### Store-Level Access
```php
if (!$app->user->checkStoreGroup($typeNum)) {
    $app->notAuthorized();
}
```

### API Key Verification (Mobile)
```php
public function verifyApiKey($apiKey, $typeNum)
{
    $key = new \MobileAPIKey($typeNum);
    return $key->verify($apiKey);
}
```

## Database Access Pattern

Every store-scoped controller follows this pattern:

```php
// 1. Get store from cache/DB
$storeController = new \BuyerKiosk\StoreController($typeNum);
$store = $storeController->getStore();

// 2. Connect to store-specific database
$db = dbConnectByName($store->getDbName()); // e.g., 'kiosk_ou00'

// 3. Execute queries on store database
$result = $db->query("SELECT * FROM buys WHERE ...");
```

## Largest Controllers (by lines)

| Controller | Lines | Purpose |
|------------|-------|---------|
| `MobileApiController.php` | 3,521 | Mobile app backend |
| `SellerMarketingController.php` | 1,450 | SMS automation |
| `UserController.php` | 1,344 | User management |
| `StatsApiController.php` | 1,339 | Statistics |
| `SupportAdminController.php` | 1,158 | Support admin |
| `SupportApiController.php` | 952 | Support API |
| `AccountController.php` | 902 | Authentication |
| `TasksApiController.php` | 796 | Task management |
| `BackstockPanelController.php` | 753 | Backstock panel |
| `TimePunchController.php` | 708 | Time tracking |

## Controller by Feature Domain

### Workbook Controllers
| File | Key Methods |
|------|-------------|
| `WorkbookPageController.php` | `pageWorkbook`, `pageWorkspace` |
| `TasksApiController.php` | `createTask`, `updateTask`, `completeTask`, `getTodayTasks` |
| `NotesApiController.php` | `getNotes`, `createNote`, `addReaction`, `addComment` |
| `KPIApiController.php` | `getTodayKPIs`, `getConfig`, `updateConfig` |
| `ScheduleApiController.php` | `getTodaySchedule`, `refreshSchedule` |
| `WhiteboardApiController.php` | `getWhiteboard`, `updateWhiteboard` |
| `TimePunchController.php` | `punchIn`, `punchOut`, `getTodayTimePunches` |
| `BackstockPanelController.php` | `getBinsToPull`, `quickAction`, `searchBin` |

### Backstock Controllers
| File | Key Methods |
|------|-------------|
| `BackstockController.php` | `pageBackStock`, `pageEvents` |
| `EventController.php` | Event management |
| `BinController.php` | Bin CRUD |
| `CategoriesController.php` | Category management |
| `LocationsController.php` | Location management |
| `ReportController.php` | Backstock reporting |

### Support Controllers
| File | Key Methods |
|------|-------------|
| `SupportPageController.php` | `pageSupport` |
| `SupportApiController.php` | `getArticles`, `search`, `addComment` |
| `SupportAdminController.php` | Admin operations |
| `SupportAdminPageController.php` | `pageSupportAdmin` |

## Related Documentation

- [Architecture Overview](./architecture-overview.md)
- [Namespace Structure](./namespace-structure.md)
- [Model Patterns](./model-patterns.md)
