Branch Hierarchy Documentation - Organizational Structure for KMP
Module: Branches System
Version: KMP v5.0+
Created: July 16, 2025
Last Updated: July 16, 2025
Overview
The Branch Hierarchy system provides comprehensive organizational structure management for the Kingdom Management Portal (KMP). It implements a flexible, hierarchical tree structure that supports unlimited depth for kingdoms, principalities, baronies, shires, and other administrative divisions within the SCA organizational framework.
Core Architecture
Tree Structure Model
The system implements a nested set model using the Tree behavior for efficient hierarchical queries:
Kingdom (lft: 1, rght: 20)
├── Principality A (lft: 2, rght: 9)
│ ├── Barony 1 (lft: 3, rght: 6)
│ │ └── Shire A (lft: 4, rght: 5)
│ └── Barony 2 (lft: 7, rght: 8)
└── Principality B (lft: 10, rght: 19)
├── Barony 3 (lft: 11, rght: 14)
│ └── Shire B (lft: 12, rght: 13)
└── Barony 4 (lft: 15, rght: 18)
└── Shire C (lft: 16, rght: 17)
Key Components
- Branch Entity (
App\Model\Entity\Branch
)- Hierarchical organizational units
- JSON configuration for external links
- Authorization integration
- Branches Table (
App\Model\Table\BranchesTable
)- Tree operations and caching
- Validation and business rules
- Performance optimization
- Branches Controller (
App\Controller\BranchesController
)- CRUD operations with tree integrity
- Search and navigation
- Member management integration
Database Schema
Core Fields
Field | Type | Description |
---|---|---|
id |
INT | Primary key identifier |
name |
VARCHAR(128) | Unique branch name |
location |
VARCHAR(128) | Geographic/administrative location |
type |
VARCHAR(50) | Branch classification |
parent_id |
INT | Parent branch reference |
lft |
INT | Nested set left boundary |
rght |
INT | Nested set right boundary |
links |
JSON | External resource URLs |
can_have_members |
BOOLEAN | Member enrollment flag |
domain |
VARCHAR(255) | Associated domain |
Audit Fields
Field | Type | Description |
---|---|---|
created |
DATETIME | Creation timestamp |
modified |
DATETIME | Last modification timestamp |
created_by |
INT | Creating user ID |
modified_by |
INT | Last modifying user ID |
deleted |
DATETIME | Soft deletion timestamp |
deleted_date |
DATETIME | Deletion date |
Branch Types
Standard SCA Classifications
- Kingdom: Top-level organizational unit
- Principality: Regional subdivision of kingdoms
- Barony: Local administrative unit
- Shire: Smaller local groups
- College: Educational institutions
- Stronghold: Military-focused groups
- Port: Maritime-focused groups
Configuration
Branch types are configurable through app settings:
// In app configuration
'Branches.Types' => [
'Kingdom',
'Principality',
'Barony',
'Shire',
'College',
'Stronghold',
'Port'
]
Tree Operations
Hierarchy Queries
// Get all descendants
$descendants = $branchesTable->getAllDecendentIds($branchId);
// Get all parents (path to root)
$parents = $branchesTable->getAllParents($branchId);
// Get threaded tree for UI
$tree = $branchesTable->getThreadedTree();
// Find direct children
$children = $branchesTable->find('children', [
'for' => $parentId,
'direct' => true
]);
// Tree list for dropdowns
$treeList = $branchesTable->find('treeList', [
'spacer' => '--'
]);
Tree Maintenance
// Automatic recovery on startup
$branchesTable->recover();
// Manual tree integrity check
$isValid = $branchesTable->verify();
// Rebuild tree structure
$branchesTable->recover();
Caching Strategy
Performance Optimization
The system implements aggressive caching for tree operations:
// Cache configuration
protected const ID_CACHES_TO_CLEAR = [
['descendants_', 'branch_structure'],
['parents_', 'branch_structure'],
];
protected const CACHE_GROUPS_TO_CLEAR = ['security'];
Cache Patterns
- Descendants Cache:
descendants_{branch_id}
- Maps each branch to all descendant IDs
- Used for authorization scope checking
- Parents Cache:
parents_{branch_id}
- Maps each branch to all parent IDs
- Used for breadcrumb generation
- Security Cache: Group-based cache
- Authorization and permission data
- Cleared on any branch structure change
Search Capabilities
Multi-Level Search
The system supports comprehensive search across:
- Branch names (with special character handling)
- Geographic locations
- Parent branch names (3 levels deep)
- Norse/Icelandic character conversion (th ↔ Þ)
// Search implementation
$query->where([
'OR' => [
['Branches.name LIKE' => '%' . $search . '%'],
['Branches.name LIKE' => '%' . $nsearch . '%'], // th->Þ
['Branches.name LIKE' => '%' . $usearch . '%'], // Þ->th
['Branches.location LIKE' => '%' . $search . '%'],
['parent.name LIKE' => '%' . $search . '%'],
['parent2.name LIKE' => '%' . $search . '%'],
['parent3.name LIKE' => '%' . $search . '%'],
],
]);
JSON Links Configuration
External Resources
Branches can store JSON configuration for external links:
{
"website": "https://atlantia.sca.org",
"calendar": "https://calendar.atlantia.sca.org",
"newsletter": "https://acorn.atlantia.sca.org",
"social": {
"facebook": "https://facebook.com/atlantia.sca",
"discord": "https://discord.gg/atlantia"
},
"resources": {
"handbook": "https://atlantia.sca.org/handbook",
"forms": "https://atlantia.sca.org/forms"
}
}
Usage in Controllers
// Processing JSON links
$links = json_decode($this->request->getData('branch_links'), true);
$branch->links = $links;
// Accessing in views
foreach ($branch->links as $type => $url) {
echo $this->Html->link($type, $url);
}
Authorization Integration
Branch-Scoped Permissions
// Entity authorization
public function getBranchId(): ?int
{
return $this->id; // Branch authorizes itself
}
// Permission checking
$user->checkCan('edit', $branch);
// Hierarchical permissions
$branchIds = $user->getPermission('manage_events')->branch_ids;
$canManage = in_array($targetBranchId, $branchIds);
Policy Integration
// In BranchPolicy
public function canEdit(IdentityInterface $user, Branch $branch): bool
{
return $user->hasPermissionForBranch('edit_branches', $branch->id);
}
// Automatic scope application
$this->Authorization->applyScope($query);
Member Integration
Branch-Member Relationships
// Member association
$this->HasMany('Members', [
'className' => 'Members',
'foreignKey' => 'branch_id',
]);
// Member queries with branch scope
$members = $membersTable->find()
->where(['branch_id IN' => $descendantIds]);
// Member visibility by branch
if ($member->branch_id === $userBranchId) {
// Show full details
} else {
// Show limited public information
}
Administrative Features
Branch Management Workflows
- Creation Process:
- Validate unique name and required fields
- Process JSON links configuration
- Establish parent-child relationships
- Update tree structure
- Modification Process:
- Authorization verification
- Circular reference prevention
- Tree structure validation
- Automatic tree recovery
- Deletion Process:
- Safety constraint checking (no children/members)
- Soft deletion with audit trail
- Name prefixing for identification
Error Handling
// Circular reference detection
catch (DatabaseException $e) {
if (strpos($e->getMessage(), 'Cannot use node') === 0) {
$this->Flash->error('Circular reference prevented');
}
}
// Safety constraints
if (!empty($branch->children) || !empty($branch->members)) {
throw new ValidationException('Cannot delete branch with dependencies');
}
Performance Considerations
Optimization Strategies
- Minimal Field Selection:
->select(['id', 'name', 'parent_id']) // UI display ->select(['id', 'sca_name', 'status']) // Member lists
- Efficient Joins:
->join(['parent' => ['table' => 'branches']]) // Parent lookup
- Caching:
- Descendants/parents lookup tables
- Security permission caches
- Application setting caches
- Tree Recovery:
- One-time startup recovery
- Conditional recovery on structure changes
- Background processing for large trees
Integration Points
Plugin Integration
- Officers Plugin: Branch-officer associations
- Activities Plugin: Branch-activity authorizations
- Awards Plugin: Branch-award recommendations
- Reports Plugin: Organizational reporting
External APIs
- Member Cards: Branch information display
- Mobile App: Organizational navigation
- Public Website: Branch directory and contact info
Security Considerations
Data Protection
- Authorization: All operations require proper permissions
- Input Validation: JSON links validation and sanitization
- SQL Injection: Parameterized queries and ORM protection
- CSRF Protection: Form tokens for state changes
Privacy Controls
- Member Visibility: Branch-scoped member access
- Contact Information: Configurable privacy levels
- External Links: Validation and security scanning
- Audit Trail: Complete change tracking
Migration and Maintenance
Database Migrations
// Initial structure
$this->table("branches")
->addColumn("name", "string", ["limit" => 128])
->addColumn("location", "string", ["limit" => 128])
->addColumn("parent_id", "integer", ["null" => true])
->addColumn("lft", "integer", ["null" => true])
->addColumn("rght", "integer", ["null" => true])
->addIndex(["lft", "rght"])
->create();
// JSON links support
$table->addColumn("links", "text", ["null" => true]);
// Branch types
$table->addColumn("type", "string", ["limit" => 50, "null" => true]);
// Domain association
$table->addColumn("domain", "string", ["limit" => 255, "null" => true]);
Maintenance Tasks
- Tree Integrity: Regular verification and recovery
- Cache Management: Periodic cache clearing and rebuilding
- Data Cleanup: Soft deletion maintenance
- Performance Monitoring: Query optimization and indexing
Troubleshooting
Common Issues
- Tree Corruption:
$branchesTable->recover(); // Rebuild lft/rght values
- Cache Inconsistency:
Cache::clear('branch_structure'); // Clear structure cache Cache::clearGroup('security'); // Clear security cache
- Circular References:
- Prevented by Tree behavior validation
- User-friendly error messages
- Automatic rollback on detection
- Performance Issues:
- Enable query logging
- Check cache hit rates
- Optimize tree depth
- Review indexing strategy
Future Enhancements
Planned Features
- Geographic Integration: Mapping and location services
- Event Calendar: Branch-specific event management
- Communication Tools: Branch announcements and messaging
- Mobile Optimization: Enhanced mobile branch management
- Analytics Dashboard: Organizational health metrics
Extensibility
The branch system is designed for extensibility through:
- Plugin architecture for additional features
- Event system for workflow customization
- Configuration-based type management
- API endpoints for external integration
Documentation Maintenance: This documentation should be updated whenever significant changes are made to the branch hierarchy system, including schema changes, new features, or architectural modifications.