3.4 Database Migration Documentation
Overview
The KMP database schema is managed through a comprehensive migration system using Phinx (via CakePHP’s Migration plugin). This documentation covers the migration history, patterns, and evolution of the database schema from initial setup to current state.
Migration Framework
Technology Stack
- Migration Engine: Phinx migration framework integrated with CakePHP
- Migration Files: PHP classes extending
BaseMigration
inapp/config/Migrations/
- Execution Environment: Command-line interface via
bin/cake migrations
commands - Version Control: Git-based tracking of schema evolution
- Environment Support: Development, testing, and production migration paths
Migration Naming Convention
Migrations follow the format: YYYYMMDDHHIISS_DescriptiveName.php
// Example migration filename
20230511170042_Init.php // Initial schema creation
20241204160759_Warrants.php // Warrant system addition
20250227173909_AddScopeToMemberRoles.php // Feature enhancement
Migration History
1. Initial Schema (20230511170042_Init.php
)
Purpose: Establish core KMP database schema with foundational tables.
Key Components:
- Complete member management system
- Role-based access control (RBAC) framework
- Branch organizational hierarchy
- Notes system for entity documentation
- Application configuration management
Major Tables Created:
// Core entity tables
'members' // Member profiles and authentication
'branches' // Organizational hierarchy (nested set model)
'roles' // Permission grouping
'permissions' // Granular access rights
'roles_permissions' // Many-to-many junction table
'member_roles' // Temporal role assignments
'notes' // Polymorphic notes system
'app_settings' // Application configuration
Advanced Features:
- Nested Set Model: Branch hierarchy with
lft
/rght
values for efficient tree queries - JSON Fields: Flexible configuration storage in
additional_info
andlinks
- Temporal Management: ActiveWindow pattern with
start_on
/expires_on
inmember_roles
- Audit Trails: Complete
created
/modified
/created_by
/modified_by
tracking - Soft Deletion: Logical deletion with
deleted
timestamp fields
2. View Members Permission (20241001141705_AddViewMembersPermission.php
)
Purpose: Enhance permission system with member viewing capabilities.
Changes:
// Permission addition
INSERT INTO permissions (name, require_active_membership, ...)
VALUES ('view members', true, ...);
// Role assignment
INSERT INTO roles_permissions (role_id, permission_id)
VALUES (getRoleId('Member'), getPermissionId('view members'));
Impact: Enables granular control over member directory access.
3. Member Profile Enhancements (20241009145957_AddTitlePronounsPronunciationToMembers.php
)
Purpose: Expand member profiles with additional personal information.
Schema Changes:
ALTER TABLE members ADD COLUMN title VARCHAR(255) NULL;
ALTER TABLE members ADD COLUMN pronouns VARCHAR(255) NULL;
ALTER TABLE members ADD COLUMN pronunciation VARCHAR(255) NULL;
Features Added:
- Title Field: Member titles and honors display
- Pronouns: Personal pronoun preferences
- Pronunciation: SCA name pronunciation guides
4. Settings Schema Evolution (20241024125311_ChangeAppSettingValueToText.php
)
Purpose: Improve application settings storage flexibility.
Schema Change:
ALTER TABLE app_settings MODIFY COLUMN value TEXT NULL;
Rationale:
- JSON field limitations in older MySQL versions
- Larger configuration value support
- Improved compatibility across database versions
5. Comprehensive Warrant System (20241204160759_Warrants.php
)
Purpose: Implement complete warrant management system for authorization tracking.
New Tables:
'warrant_periods' // Temporal warrant validity periods
'warrants' // Individual warrant assignments
Key Features:
- Temporal Periods:
warrant_periods
defines valid timeframes - Entity Polymorphism: Warrants can be assigned to any entity type
- Status Lifecycle: Complete warrant status management
- Integration Points: Links to member roles and organizational positions
6. Member Warrant Eligibility (20241207172311_AddWarrantableToMembers.php
)
Purpose: Add warrant eligibility tracking to member profiles.
Schema Change:
ALTER TABLE members ADD COLUMN warrantable BOOLEAN DEFAULT false;
Usage: Controls which members are eligible for warrant assignment.
7. Association Field Refactoring (20241225192403_RefactorAgnosticJoinFields.php
)
Purpose: Standardize polymorphic association field naming across the system.
Changes:
// notes table
topic_model → entity_type
topic_id → entity_id
// member_roles table
granting_model → entity_type
granting_id → entity_id
Impact: Consistent naming pattern for polymorphic relationships improves code maintainability and reduces confusion.
8. Branch Type Classification (20241231164137_AddTypeToBranches.php
)
Purpose: Add organizational classification to branch structure.
Schema Change:
ALTER TABLE branches ADD COLUMN type VARCHAR(50) NULL;
Branch Types:
Local
: Local SCA groupsCollege
: College/University groupsHousehold
: Household groupsKingdom
: Kingdom-level organization
9. Required Application Settings (20250108190610_AddRequiredToAppSetting.php
)
Purpose: Implement validation for critical application configuration.
Schema Change:
ALTER TABLE app_settings ADD COLUMN required BOOLEAN DEFAULT false;
Impact: Ensures essential configuration values are properly maintained.
10. Member Role Scoping (20250227173909_AddScopeToMemberRoles.php
)
Purpose: Add contextual scoping to role assignments and permission evaluation.
Schema Changes:
// Add branch scoping to member roles
ALTER TABLE member_roles ADD COLUMN branch_id INT(11) NULL;
ALTER TABLE member_roles ADD FOREIGN KEY (branch_id) REFERENCES branches(id);
// Add permission scoping rules
ALTER TABLE permissions ADD COLUMN scoping_rule VARCHAR(255) NOT NULL DEFAULT 'Global';
Scope Examples:
branch:local
: Role applies to specific branchevent:crown_tournament
: Event-specific role assignmentglobal
: System-wide role assignment
Impact: Enables branch-specific role assignments and permission scoping for better organizational data isolation.
11. Multi-Site Domain Support (20250227230531_AddDomainToBranch.php
)
Purpose: Enable multi-domain hosting for different branches.
Schema Change:
ALTER TABLE branches ADD COLUMN domain VARCHAR(255) NULL;
Use Cases:
- Branch-specific domain routing
- Multi-tenant deployment support
- Custom branding per branch
12. Permission Policy Framework (20250328010857_PermissionPolicies.php
)
Purpose: Implement fine-grained authorization policies.
New Table:
CREATE TABLE permission_policies (
id INT(11) AUTO_INCREMENT PRIMARY KEY,
permission_id INT(11) NOT NULL,
policy_class VARCHAR(255) NOT NULL,
policy_method VARCHAR(255) NOT NULL,
FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE
);
Features:
- Custom authorization logic per permission
- Dynamic policy class/method binding
- Enhanced security model integration
13. Settings Consolidation (20250415203922_ConvertAppSettingsToSingleRecord.php
)
Purpose: Reserved for future application settings optimization.
Status: Migration created but functionality disabled pending further analysis.
Changes:
// Migration exists but returns early - no changes implemented
public function change(): void
{
return; // Disabled - optimization pending
}
Note: This migration was created to optimize application settings but was disabled before deployment to allow for additional design consideration.
Migration Patterns
1. Schema Evolution Pattern
class ExampleMigration extends BaseMigration
{
public bool $autoId = false; // Control auto-increment behavior
public function up()
{
// Forward migration logic
$this->table('example_table')
->addColumn('new_field', 'string', [
'limit' => 255,
'null' => false,
'default' => 'default_value'
])
->addIndex(['new_field'])
->update();
}
public function down()
{
// Rollback logic (when supported)
$this->table('example_table')
->removeColumn('new_field')
->update();
}
}
2. Data Migration Pattern
public function up()
{
// Schema changes first
$this->table('members')
->addColumn('new_status', 'string', ['limit' => 20])
->update();
// Data transformation
$this->execute("
UPDATE members
SET new_status = CASE
WHEN old_field = 'active' THEN 'verified'
WHEN old_field = 'inactive' THEN 'pending'
ELSE 'unknown'
END
");
// Remove old column
$this->table('members')
->removeColumn('old_field')
->update();
}
3. Seed Integration Pattern
require_once __DIR__ . '/../Seeds/InitWarrantsSeed.php';
class Warrants extends BaseMigration
{
public function up()
{
// Create tables
$this->createWarrantTables();
// Seed initial data
$seed = new InitWarrantsSeed();
$seed->setAdapter($this->getAdapter());
$seed->run();
}
}
Migration Best Practices
1. Schema Design
- Consistent Naming: Follow CakePHP conventions for table and column names
- Proper Indexes: Add indexes for foreign keys and frequently queried columns
- Data Types: Use appropriate data types and lengths
- Constraints: Implement foreign key constraints and validation rules
2. Migration Safety
- Backwards Compatibility: Avoid breaking changes in production environments
- Data Preservation: Always preserve existing data during schema changes
- Testing: Test migrations on development and staging before production
- Rollback Plans: Design reversible migrations where possible
3. Performance Considerations
- Index Creation: Create indexes during off-peak hours for large tables
- Batch Processing: Process large data migrations in batches
- Lock Minimization: Minimize table locks during migration execution
- Resource Monitoring: Monitor system resources during migration execution
4. Documentation Standards
- Clear Comments: Document the purpose and impact of each migration
- Change Descriptions: Explain what changed and why
- Dependencies: Note any dependencies on previous migrations
- Rollback Notes: Document rollback procedures and limitations
Migration Execution
Development Environment
# Generate new migration
bin/cake bake migration AddNewFeature
# Run pending migrations
bin/cake migrations migrate
# Check migration status
bin/cake migrations status
# Rollback last migration (if supported)
bin/cake migrations rollback
Production Environment
# Pre-migration backup
mysqldump kmp_production > backup_before_migration.sql
# Run migrations with confirmation
bin/cake migrations migrate --no-interaction
# Verify migration success
bin/cake migrations status
# Run post-migration verification tests
bin/cake test
Migration Dependencies
Plugin Migrations
Plugin migrations are managed separately but coordinate with core schema:
# Officers plugin migrations
bin/cake migrations migrate -p Officers
# Awards plugin migrations
bin/cake migrations migrate -p Awards
# Activities plugin migrations
bin/cake migrations migrate -p Activities
Migration Order
- Core Schema: Foundation tables and relationships
- Plugin Tables: Plugin-specific table creation
- Cross-Plugin Relations: Foreign keys between core and plugin tables
- Data Population: Initial seed data and configuration
- Index Optimization: Performance indexes and constraints
Schema Validation
Automated Validation
// Schema consistency checks
bin/cake schema_check validate
// Foreign key integrity verification
bin/cake schema_check foreign_keys
// Index optimization analysis
bin/cake schema_check indexes
Manual Validation
- Referential Integrity: Verify all foreign key relationships
- Data Consistency: Check for orphaned records and invalid states
- Performance Metrics: Analyze query performance after migrations
- Backup Verification: Ensure backup and restore procedures work
Troubleshooting
Common Migration Issues
- Foreign Key Conflicts:
- Check for orphaned records before adding constraints
- Use data cleanup migrations to resolve inconsistencies
- Index Creation Failures:
- Verify column data types and lengths
- Check for duplicate or conflicting indexes
- Data Type Mismatches:
- Ensure data compatibility before type changes
- Use gradual migration approach for large tables
- Plugin Integration Issues:
- Coordinate plugin and core migrations
- Verify plugin loading order and dependencies
Recovery Procedures
- Migration Rollback: Use database backup and selective rollback
- Data Recovery: Restore from pre-migration backups
- Partial Failure: Complete manual data corrections and re-run
- Schema Corruption: Restore schema from migration history
Future Migration Strategy
Planned Enhancements
- Multi-Tenant Support: Schema modifications for tenant isolation
- API Integration: Schema changes for external API compatibility
- Performance Optimization: Index and query optimization migrations
- Feature Extensions: Plugin-specific schema enhancements
Migration Framework Evolution
- Automated Testing: Integration with automated migration testing
- Performance Monitoring: Built-in performance impact analysis
- Rollback Improvements: Enhanced rollback capability and safety
- Documentation Generation: Automatic schema documentation updates
This migration documentation reflects the complete evolution of the KMP database schema. For specific implementation details, refer to the individual migration files in app/config/Migrations/
and coordinate with the Database Schema Documentation.