Skip to the content.

← Back to Table of Contents

3.1 Core Foundation Architecture

This document provides detailed architectural insights discovered during the comprehensive code documentation effort, focusing on the foundational patterns and systems that power the Kingdom Management Portal (KMP).

Table of Contents

  1. Application Bootstrap & Configuration
  2. Core Architecture Components
  3. Cache Management Architecture
  4. Authorization & Branch Scoping
  5. Utility & Helper Systems
  6. Performance Patterns
  7. Security Architecture

Application Bootstrap & Configuration

Application.php - The Foundation

The Application.php class serves as the architectural foundation of KMP, implementing a sophisticated multi-tier bootstrap process with comprehensive security and performance considerations.

Middleware Stack Architecture

KMP implements a carefully ordered middleware stack for security and functionality:

graph TD
    Request[HTTP Request] --> ErrorHandler[Error Handling Middleware]
    ErrorHandler --> SecurityHeaders[Security Headers Middleware]
    SecurityHeaders --> AssetMiddleware[Asset Delivery Middleware]
    AssetMiddleware --> RoutingMiddleware[Routing Middleware]
    RoutingMiddleware --> BodyParser[Body Parser Middleware]
    BodyParser --> CSRF[CSRF Protection Middleware]
    CSRF --> AuthenticationMiddleware[Authentication Middleware]
    AuthenticationMiddleware --> AuthorizationMiddleware[Authorization Middleware]
    AuthorizationMiddleware --> FootprintMiddleware[Footprint Middleware]
    FootprintMiddleware --> Controller[Controller Layer]

Key Architectural Decisions:

Service Container Configuration

KMP uses dependency injection extensively for loose coupling and testability:

// Service Registration Patterns
public function services(ContainerInterface $container): void
{
    $container->add(WarrantManagerInterface::class, DefaultWarrantManager::class);
    $container->add(ActiveWindowManagerInterface::class, DefaultActiveWindowManager::class);
    $container->add(NavigationRegistry::class)->addArgument($container);
    $container->add(CsvExportService::class);
    $container->add(KmpAuthorizationService::class)->addArgument(Identity::class);
}

Container Architecture Benefits:

Configuration Management Strategy

Multi-Environment Configuration

KMP implements a sophisticated configuration hierarchy based on CakePHP conventions:

Configuration Priority (Highest to Lowest):
1. Environment Variables (e.g., DEBUG, DATABASE_URL)
2. app_local.php (local overrides, not in version control)
3. app.php (default configuration)
4. Plugin-specific configuration files
5. Framework defaults

Security Configuration Patterns

Session Security:

'Session' => [
    'defaults' => 'php',
    'timeout' => 240, // 4 hours
    'cookie' => [
        'name' => 'KMP_SESSION',
        'httponly' => true,
        'secure' => true,  // HTTPS only
        'samesite' => 'Strict'
    ]
]

CSRF Protection:

'csrfProtection' => [
    'cookieName' => 'csrfToken',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Strict'
]

Caching Strategy Architecture

KMP implements a multi-tier caching system optimized for organizational data:

graph TD
    Application[Application Layer] --> L1[Static Caches]
    Application --> L2[Entity Caches]
    Application --> L3[Group Caches]
    L1 --> CacheBackend[File/APCu Cache Backend]
    L2 --> CacheBackend
    L3 --> CacheBackend
    CacheBackend --> Database[(Database)]

Cache Configuration Examples:

// High-performance cache for frequently accessed data
'_cake_core_' => [
    'className' => ApcuEngine::class,
    'prefix' => 'kmp_core_',
    'serialize' => true,
    'duration' => '+1 hours',
]

// Branch structure cache for authorization
'branch_structure' => [
    'className' => FileEngine::class,
    'prefix' => 'kmp_branches_',
    'duration' => '+30 minutes',
]

Core Architecture Components

BaseController Pattern (AppController)

The AppController implements a sophisticated 8-phase request processing pipeline:

Processing Pipeline

sequenceDiagram
    participant Client
    participant AppController
    participant PluginValidator
    participant NavigationHistory
    participant ViewCellRegistry
    participant EventSystem

    Client->>AppController: HTTP Request
    AppController->>AppController: Phase 1: Detect Request Type (CSV/JSON/Turbo)
    AppController->>PluginValidator: Phase 2: Validate Plugin Access
    AppController->>AppController: Phase 3: Initialize Authorization
    AppController->>NavigationHistory: Phase 4: Build Navigation History
    AppController->>ViewCellRegistry: Phase 5: Register Available View Cells
    AppController->>EventSystem: Phase 6: Dispatch Plugin Events
    AppController->>AppController: Phase 7: Configure Turbo Integration
    AppController->>AppController: Phase 8: Finalize Request Context
    AppController->>Client: Response

Key Architectural Features:

BaseTable Pattern

The BaseTable class implements a sophisticated data access layer with three-tier cache management:

Cache Management Architecture

// Three-tier cache invalidation configuration
protected const CACHES_TO_CLEAR = [
    ['navigation_menu', 'navigation'],
    ['global_stats', 'statistics']
];

protected const ID_CACHES_TO_CLEAR = [
    ['member_profile_', 'members'],
    ['branch_descendants_', 'branch_structure']
];

protected const CACHE_GROUPS_TO_CLEAR = ['security', 'navigation'];

Cache Invalidation Flow:

  1. Static Caches: Fixed cache keys cleared on any table change
  2. Entity Caches: ID-prefixed cache keys cleared when specific entity changes
  3. Group Caches: Entire cache groups cleared for related data sets

Branch Scoping Architecture

KMP implements organizational data isolation through branch scoping:

graph TD
    UserRequest[User Request] --> Authorization[Authorization Check]
    Authorization --> BranchScope[Get User Branch IDs]
    BranchScope --> QueryModification[Modify Query with Branch Filter]
    QueryModification --> HierarchyCheck[Apply Hierarchy Rules]
    HierarchyCheck --> DataFilter[Execute Filtered Query]
    DataFilter --> Results[Branch-Scoped Results]

Branch Scoping Implementation:

public function addBranchScopeQuery(Query $query, array $options = []): Query
{
    // Default implementation - child classes can override
    if (isset($this->_schema['branch_id'])) {
        $branchIds = $this->getAuthorizedBranchIds();
        if ($branchIds !== null) {
            return $query->where([$this->getAlias() . '.branch_id IN' => $branchIds]);
        }
    }
    return $query;
}

BaseEntity Pattern

The BaseEntity class provides the foundation for all data entities with branch authorization support:

Authorization Integration

public function getBranchId(): ?int
{
    // Core pattern - entities must provide their organizational scope
    // Default implementation for entities with direct branch_id
    return $this->branch_id ?? null;
}

Entity Hierarchy Structure:

BaseEntity
├── Branch (self-referential hierarchy, returns $this->id)
├── Member (implements KmpIdentityInterface, returns $this->branch_id)
├── Permission (security entities)
├── ActiveWindowBaseEntity (adds start/expire functionality)
│   ├── MemberRole (time-bounded role assignments)
│   ├── WarrantRoster (officer appointments)
│   └── ActivityAuthorization (activity permissions)
└── Plugin Entities
    ├── Award (Awards plugin)
    ├── Activity (Activities plugin)
    └── Office (Officers plugin)

Cache Management Architecture

Three-Tier Cache Strategy

KMP implements a sophisticated caching architecture optimized for organizational hierarchies and frequent authorization checks:

Tier 1: Static Application Caches

// Application-wide data that changes infrequently
protected const CACHES_TO_CLEAR = [
    ['navigation_items', 'navigation'],
    ['app_settings_cache', 'default'],
    ['plugin_status_cache', 'default']
];

Use Cases:

Tier 2: Entity-Specific Caches

// Record-specific cached data with ID-based keys
protected const ID_CACHES_TO_CLEAR = [
    ['member_profile_', 'members'],        // member_profile_123
    ['branch_descendants_', 'branch_structure'], // branch_descendants_456
    ['warrant_eligibility_', 'warrants']   // warrant_eligibility_789
];

Use Cases:

Tier 3: Group-Based Caches

// Related data sets with shared invalidation triggers
protected const CACHE_GROUPS_TO_CLEAR = [
    'security',        // All authorization-related caches
    'navigation',      // All navigation-related caches
    'branch_structure' // All hierarchy-related caches
];

Use Cases:

Cache Invalidation Patterns

Automatic Invalidation on Entity Save

graph TD
    EntitySave[Entity Save Operation] --> CacheInvalidation[afterSave Event Triggered]
    CacheInvalidation --> Phase1[Phase 1: Clear Static Caches]
    Phase1 --> Phase2[Phase 2: Clear Entity-Specific Caches]
    Phase2 --> Phase3[Phase 3: Clear Group Caches]
    Phase3 --> Complete[Cache Invalidation Complete]

Implementation:

public function afterSave(EventInterface $event, EntityInterface $entity, ArrayObject $options): void
{
    // Phase 1: Static cache clearing
    foreach (static::CACHES_TO_CLEAR as [$key, $config]) {
        Cache::delete($key, $config);
    }
    
    // Phase 2: Entity-specific cache clearing
    if ($entity->id) {
        foreach (static::ID_CACHES_TO_CLEAR as [$prefix, $config]) {
            Cache::delete($prefix . $entity->id, $config);
        }
    }
    
    // Phase 3: Group cache clearing
    foreach (static::CACHE_GROUPS_TO_CLEAR as $group) {
        Cache::clearGroup($group);
    }
}

Authorization & Branch Scoping

Hierarchical Permission System

KMP implements a sophisticated authorization system based on organizational hierarchy using the PermissionsLoader:

Permission Inheritance Model

graph TD
    Kingdom[Kingdom Level] --> Principality[Principality Level]
    Principality --> Barony[Barony Level]
    Barony --> Shire[Shire Level]
    Shire --> Individual[Individual Level]
    
    Kingdom -.->|inherits down| Principality
    Principality -.->|inherits down| Barony
    Barony -.->|inherits down| Shire
    Shire -.->|inherits down| Individual

Authorization Flow:

  1. Direct Permissions: User has explicit permission for specific branch
  2. Inherited Permissions: Permission granted at parent level includes all child branches
  3. Global Permissions: Special permissions that bypass branch restrictions
  4. Scope-Based Permissions: Role-based permissions with specific branch scopes

Actual Branch Scoping Implementation

Based on the PermissionsLoader implementation:

// Real permission processing from PermissionsLoader
foreach ($memberRoles as $role) {
    $branch_id = $role->_matchingData['MemberRoles']->branch_id;
    
    if ($permission->scope === 'global') {
        $permissions[$permission->id]->branch_ids = null; // Global access
    } elseif ($permission->scope === 'branch') {
        $permissions[$permission->id]->branch_ids = [$branch_id];
    } elseif ($permission->scope === 'branch_and_descendants') {
        $descendants = $branchTable->getAllDecendentIds($branch_id);
        $descendants[] = $branch_id;
        $permissions[$permission->id]->branch_ids = $descendants;
    }
}

Policy-Based Authorization

KMP uses CakePHP’s Authorization plugin with custom policy resolution:

Policy Resolution Flow

sequenceDiagram
    participant Controller
    participant AuthService as Authorization Service
    participant PolicyResolver
    participant Policy
    participant Entity

    Controller->>AuthService: authorize($entity, $action)
    AuthService->>PolicyResolver: resolvePolicy($entity)
    PolicyResolver->>Policy: new EntityPolicy()
    Policy->>Entity: getBranchId()
    Entity-->>Policy: branch_id
    Policy->>Policy: checkPermission($user, $branch_id, $action)
    Policy-->>AuthService: authorized/denied
    AuthService-->>Controller: result

Utility & Helper Systems

StaticHelpers Architecture

The StaticHelpers class provides 14 core utility methods organized into functional areas:

Multi-Layer Configuration System

Configuration Resolution Hierarchy (from actual implementation):

public static function getAppSetting(string $key, mixed $default = null, ?string $type = null, bool $useDatabase = true): mixed
{
    // 1. Check CakePHP Configure first (highest priority)
    $value = Configure::read($key);
    if ($value !== null) {
        return $value;
    }
    
    // 2. Check database AppSettings table (if enabled)
    if ($useDatabase) {
        // Database query logic...
    }
    
    // 3. Return default value (lowest priority)
    return $default;
}

Configuration Methods Available:

Template Processing System

Advanced Template Processing with Nested Property Access:

// Real template processing from StaticHelpers
$template = "Welcome to {site_title} - Branch: {branch.name}";
$variables = [
    'site_title' => 'Kingdom of Atlantia',
    'branch' => ['name' => 'Barony of Windmasters Hill']
];

// Supports nested property access with array[index] and object.property syntax
$processed = StaticHelpers::processTemplate($template, $variables);

Template Features:

File and Image Processing

Comprehensive File Operations:

// Directory management with proper error handling
StaticHelpers::ensureDirectoryExists('/path/to/dir', 0755);

// Image scaling with aspect ratio preservation
$scaledPath = StaticHelpers::saveScaledImage(
    'source.jpg',      // Source image
    200, 200,         // Max dimensions
    '/uploads/',      // Source directory
    '/thumbs/'        // Destination directory
);

// Safe file deletion with existence checking
StaticHelpers::deleteFile('/path/to/file.txt');

Performance Patterns

Query Optimization Strategies

Efficient Association Loading

Based on actual KMP controller patterns:

// Optimized member loading from BranchesController
$branch = $this->Branches->get($id, [
    'contain' => [
        'Parent',
        'Members' => function ($q) {
            return $q
                ->select(['id', 'sca_name', 'branch_id', 'membership_number', 
                         'membership_expires_on', 'status', 'birth_month', 'birth_year'])
                ->orderBy(['sca_name' => 'ASC']);
        }
    ]
]);

Cached Hierarchy Queries

Branch Hierarchy Caching for O(1) Authorization (from BranchesTable):

public function getAllDecendentIds($id): array
{
    $descendants = Cache::read('descendants_' . $id, 'branch_structure');
    if (!$descendants) {
        $descendants = $this->getDescendantsLookup();
        foreach ($descendants as $key => $value) {
            Cache::write('descendants_' . $key, $value, 'branch_structure');
        }
        $descendants = $descendants[$id] ?? [];
    }
    return $descendants ?? [];
}

Memory Management

Stream-Based Processing (from CsvExportService)

public function exportFromQuery(Query $query, array $headers, ?callable $rowMapper = null): Response
{
    $response = new Response();
    $response = $response->withType('csv');
    
    $body = new CallbackStream(function () use ($query, $headers, $rowMapper) {
        $output = fopen('php://output', 'w');
        fputcsv($output, $headers);
        
        foreach ($query->enableBufferedResults(false) as $entity) {
            $row = $rowMapper ? $rowMapper($entity) : $entity->toArray();
            fputcsv($output, $row);
        }
        fclose($output);
    });
    
    return $response->withBody($body);
}

Security Architecture

Input Validation & Sanitization

Multi-Layer Validation Pipeline

graph TD
    UserInput[User Input] --> CSRFCheck[CSRF Token Validation]
    CSRFCheck --> TypeValidation[Data Type Validation]
    TypeValidation --> BusinessRules[Business Rule Validation]
    BusinessRules --> AuthorizationCheck[Authorization Check]
    AuthorizationCheck --> DatabaseValidation[Database Constraint Validation]
    DatabaseValidation --> ProcessedData[Safely Processed Data]

XSS Prevention

Automatic Output Escaping:

// Template output escaping (KMP standard)
echo h($user->sca_name); // Escaped output

// Safe HTML generation
echo $this->Html->link(
    h($branch->name),
    ['controller' => 'Branches', 'action' => 'view', $branch->id]
);

Authentication Security

Session Security Configuration

Actual Session Configuration from app.php:

'Session' => [
    'defaults' => 'php',
    'timeout' => 240, // 4 hours
    'cookie' => [
        'name' => 'KMP_SESSION',
        'httponly' => true,
        'secure' => true,
        'samesite' => 'Strict'
    ],
    'regenerateId' => true
]

Security Headers Implementation

Comprehensive Security Headers (from Application.php middleware):

$response = $response
    ->withHeader('X-Content-Type-Options', 'nosniff')
    ->withHeader('X-Frame-Options', 'SAMEORIGIN')
    ->withHeader('X-XSS-Protection', '1; mode=block')
    ->withHeader('Referrer-Policy', 'strict-origin-when-cross-origin')
    ->withHeader('Content-Security-Policy', $cspHeader);

Integration Patterns

Plugin Integration Architecture

Event-Driven Plugin System:

graph TD
    CoreApp[Core Application] --> EventDispatcher[Event Manager]
    EventDispatcher --> NavigationEvent[Navigation Event]
    EventDispatcher --> ViewCellEvent[View Cell Event]
    
    NavigationEvent --> ActivitiesPlugin[Activities Plugin]
    NavigationEvent --> OfficersPlugin[Officers Plugin]
    NavigationEvent --> AwardsPlugin[Awards Plugin]
    
    ViewCellEvent --> PluginViewCells[Plugin View Cells]
    
    ActivitiesPlugin --> NavigationRegistry[Navigation Registry]
    OfficersPlugin --> NavigationRegistry
    AwardsPlugin --> NavigationRegistry

Service Integration Pattern

Dependency Injection Service Configuration:

// Real service integration from Application.php
public function services(ContainerInterface $container): void
{
    $container->add(WarrantManagerInterface::class, DefaultWarrantManager::class)
        ->addArgument(ActiveWindowManagerInterface::class)
        ->addArgument(EventManager::class);
        
    $container->add(ActiveWindowManagerInterface::class, DefaultActiveWindowManager::class);
    
    $container->add(NavigationRegistry::class)
        ->addArgument($container);
}

This foundational architecture provides the robust, scalable, and secure foundation that powers all of KMP’s advanced features and organizational management capabilities.


Next: Core Modules Previous: Architecture Overview