Skip to the content.

3.6 Data Seeding Documentation

Overview

The KMP data seeding system provides a comprehensive framework for populating the database with initial data, test data, and development data. The seeding system supports both initial application setup and ongoing development workflows.

Seeding Framework

Technology Stack

Seed File Structure

<?php
declare(strict_types=1);

use Migrations\BaseSeed;
use Cake\I18n\DateTime;

class ExampleSeed extends BaseSeed
{
    /**
     * Get data for seeding
     * @return array
     */
    public function getData(): array
    {
        return [
            [
                'name' => 'Example Name',
                'created' => DateTime::now(),
                'created_by' => 1,
            ]
        ];
    }
    
    /**
     * Run seeding process
     * @return void
     */
    public function run(): void
    {
        $data = $this->getData();
        $table = $this->table('example_table');
        $table->insert($data)->saveData();
    }
}

Seed Helper Functions

Core Utility Functions

The SeedHelpers class provides centralized lookup functions for referential integrity:

class SeedHelpers
{
    /**
     * Get role ID by name
     * @param string|null $name Role name
     * @return int|null Role ID or null if name is null
     */
    public static function getRoleId(?string $name): ?int
    {
        if ($name === null) {
            return null;
        }
        $rolesTable = TableRegistry::getTableLocator()->get('Roles');
        $role = $rolesTable->find()->where(['name' => $name])->firstOrFail();
        return $role->id;
    }
    
    /**
     * Get permission ID by name
     * @param string $name Permission name
     * @return int Permission ID
     */
    public static function getPermissionId(string $name): int
    {
        $permissionsTable = TableRegistry::getTableLocator()->get('Permissions');
        $permission = $permissionsTable->find()->where(['name' => $name])->firstOrFail();
        return $permission->id;
    }
    
    /**
     * Get member ID by email or SCA name
     * @param string $emailOrScaName Email address or SCA name
     * @return int Member ID
     */
    public static function getMemberId(string $emailOrScaName): int
    {
        $membersTable = TableRegistry::getTableLocator()->get('Members');
        $member = $membersTable->find()->where([
            'OR' => ['email_address' => $emailOrScaName, 'sca_name' => $emailOrScaName]
        ])->firstOrFail();
        return $member->id;
    }
    
    /**
     * Get branch ID by name
     * @param string|null $name Branch name
     * @return int|null Branch ID or null if name is null
     */
    public static function getBranchIdByName(?string $name): ?int
    {
        if ($name === null) {
            return null;
        }
        $branchesTable = TableRegistry::getTableLocator()->get('Branches');
        $branch = $branchesTable->find()->where(['name' => $name])->firstOrFail();
        return $branch->id;
    }
    
    /**
     * Get activity group ID by name
     * @param string $name Activity group name
     * @return int Activity group ID
     */
    public static function getActivityGroupId(string $name): int
    {
        $activityGroupsTable = TableRegistry::getTableLocator()->get('Activities.ActivityGroups');
        $activityGroup = $activityGroupsTable->find()->where(['name' => $name])->firstOrFail();
        return $activityGroup->id;
    }
}

Initialization Seeds

Master Seed Orchestrator

InitMigrationSeed.php

Coordinates the complete initial system setup:

class InitMigrationSeed extends BaseSeed
{
    public function run(): void
    {
        // Core organizational structure
        $this->call('InitBranchesSeed', ['source' => 'Seeds']);
        
        // Member management
        $this->call('InitMembersSeed', ['source' => 'Seeds']);
        
        // RBAC system
        $this->call('InitRolesSeed', ['source' => 'Seeds']);
        $this->call('InitPermissionsSeed', ['source' => 'Seeds']);
        $this->call('InitRolesPermissionsSeed', ['source' => 'Seeds']);
        
        // Role assignments
        $this->call('InitMemberRolesSeed', ['source' => 'Seeds']);
    }
}

Core System Seeds

InitBranchesSeed.php

Establishes the organizational hierarchy foundation:

class InitBranchesSeed extends BaseSeed
{
    public function getData(): array
    {
        return [
            [
                'name' => 'Kingdom',
                'location' => 'Kingdom',
                'parent_id' => null,
                'type' => 'Kingdom',
                'can_have_members' => true,
                'lft' => 1,          // Nested set left boundary
                'rght' => 18,        // Nested set right boundary
                'created' => DateTime::now(),
                'created_by' => 1,
            ]
        ];
    }
    
    public function run(): void
    {
        $data = $this->getData();
        $table = $this->table('branches');
        
        // Enable identity insert for controlled ID assignment
        $options = $table->getAdapter()->getOptions();
        $options['identity_insert'] = true;
        $table->getAdapter()->setOptions($options);
        
        $table->insert($data)->saveData();
    }
}

InitRolesSeed.php

Creates the fundamental role structure:

class InitRolesSeed extends BaseSeed
{
    public function getData(): array
    {
        return [
            // System administration
            [
                'name' => 'Super User',
                'is_system' => true,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            // Basic membership
            [
                'name' => 'Member',
                'is_system' => true,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            // Administrative roles
            [
                'name' => 'Branch Admin',
                'is_system' => false,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            // Officer roles
            [
                'name' => 'Branch Officer',
                'is_system' => false,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
        ];
    }
}

InitPermissionsSeed.php

Establishes the comprehensive permission framework:

class InitPermissionsSeed extends BaseSeed
{
    public function getData(): array
    {
        return [
            // Member management permissions
            [
                'name' => 'view members',
                'require_active_membership' => true,
                'require_active_background_check' => false,
                'require_min_age' => 0,
                'is_system' => false,
                'is_super_user' => false,
                'requires_warrant' => false,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            [
                'name' => 'edit members',
                'require_active_membership' => true,
                'require_active_background_check' => true,
                'require_min_age' => 18,
                'is_system' => false,
                'is_super_user' => false,
                'requires_warrant' => true,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            // Administrative permissions
            [
                'name' => 'admin interface',
                'require_active_membership' => true,
                'require_active_background_check' => true,
                'require_min_age' => 18,
                'is_system' => false,
                'is_super_user' => false,
                'requires_warrant' => true,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            // System permissions
            [
                'name' => 'super user access',
                'require_active_membership' => true,
                'require_active_background_check' => true,
                'require_min_age' => 21,
                'is_system' => true,
                'is_super_user' => true,
                'requires_warrant' => true,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
        ];
    }
}

InitMembersSeed.php

Creates the initial system administrator:

class InitMembersSeed extends BaseSeed
{
    public function getData(): array
    {
        // Generate secure password hash
        $hasher = new DefaultPasswordHasher();
        $defaultPassword = $hasher->hash('change_this_password');
        
        return [
            [
                'sca_name' => 'System Administrator',
                'first_name' => 'System',
                'last_name' => 'Administrator',
                'email_address' => 'admin@example.com',
                'password' => $defaultPassword,
                'status' => 'active',
                'warrantable' => true,
                'branch_id' => 1, // Kingdom branch
                'verified_date' => DateTime::now(),
                'verified_by' => 1,
                'additional_info' => json_encode([
                    'system_account' => true,
                    'initial_setup' => true
                ]),
                'created' => DateTime::now(),
                'created_by' => 1,
            ]
        ];
    }
}

Development Seeds

Master Development Seed

DevLoad.php

Coordinates comprehensive development data population:

class DevLoad extends BaseSeed
{
    public function run(): void
    {
        // Core organizational data
        $this->call('DevLoadBranchesSeed', ['source' => 'Seeds']);
        
        // RBAC system expansion
        $this->call('DevLoadRolesSeed', ['source' => 'Seeds']);
        $this->call('DevLoadPermissionsSeed', ['source' => 'Seeds']);
        $this->call('DevLoadPoliciesSeed', ['source' => 'Seeds']);
        
        // Member data
        $this->call('DevLoadMembersSeed', ['source' => 'Seeds']);
        $this->call('DevLoadMemberRolesSeed', ['source' => 'Seeds']);
        
        // Application configuration
        $this->call('DevLoadAppSettingsSeed', ['source' => 'Seeds']);
        
        // Role-permission assignments
        $this->call('DevLoadRolesPermissionsSeed', ['source' => 'Seeds']);
        
        // Plugin data
        $this->call('DevLoadActivityGroupsSeed', ['source' => 'Seeds']);
        $this->call('DevLoadActivitiesSeed', ['source' => 'Seeds']);
        $this->call('DevLoadDepartmentsSeed', ['source' => 'Seeds']);
        $this->call('DevLoadOfficesSeed', ['source' => 'Seeds']);
        $this->call('DevLoadOfficersSeed', ['source' => 'Seeds']);
        
        // Awards system
        $this->call('DevLoadAwardsDomainsSeed', ['source' => 'Seeds']);
        $this->call('DevLoadAwardsLevelsSeed', ['source' => 'Seeds']);
        $this->call('DevLoadAwardsAwardsSeed', ['source' => 'Seeds']);
        $this->call('DevLoadAwardsEventsSeed', ['source' => 'Seeds']);
        
        // Warrant system
        $this->call('DevLoadWarrantsSeed', ['source' => 'Seeds']);
    }
}

Organizational Development Data

DevLoadBranchesSeed.php

Creates a realistic branch hierarchy for development:

class DevLoadBranchesSeed extends BaseSeed
{
    public function getData(): array
    {
        return [
            // Principality level
            [
                'name' => 'Principality of Example',
                'location' => 'Central Region',
                'parent_id' => 1, // Kingdom
                'type' => 'Principality',
                'domain' => 'principality.example.com',
                'can_have_members' => true,
                'links' => json_encode([
                    'website' => 'https://principality.example.com',
                    'facebook' => 'https://facebook.com/principality'
                ]),
                'lft' => 2,
                'rght' => 17,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            // Local branch
            [
                'name' => 'Barony of Test',
                'location' => 'Test City, State',
                'parent_id' => 2, // Principality
                'type' => 'Local',
                'domain' => 'barony.example.com',
                'can_have_members' => true,
                'links' => json_encode([
                    'website' => 'https://barony.example.com',
                    'calendar' => 'https://calendar.google.com/calendar/...',
                    'newsletter' => 'https://newsletter.example.com'
                ]),
                'lft' => 3,
                'rght' => 10,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            // College branch
            [
                'name' => 'College of Example University',
                'location' => 'University Town, State',
                'parent_id' => 2, // Principality
                'type' => 'College',
                'can_have_members' => true,
                'lft' => 11,
                'rght' => 16,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            // Household
            [
                'name' => 'Household of Example',
                'location' => 'Various Locations',
                'parent_id' => 3, // Barony
                'type' => 'Household',
                'can_have_members' => true,
                'lft' => 4,
                'rght' => 9,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
        ];
    }
}

Member Development Data

DevLoadMembersSeed.php

Creates diverse member profiles for testing:

class DevLoadMembersSeed extends BaseSeed
{
    public function getData(): array
    {
        $hasher = new DefaultPasswordHasher();
        $defaultPassword = $hasher->hash('password123');
        
        return [
            // Branch Officer example
            [
                'sca_name' => 'Aethelmearc Herald',
                'first_name' => 'John',
                'last_name' => 'Smith',
                'email_address' => 'herald@example.com',
                'password' => $defaultPassword,
                'membership_number' => 'KM123456',
                'membership_expires_on' => DateTime::now()->addYear(1),
                'branch_id' => SeedHelpers::getBranchIdByName('Barony of Test'),
                'background_check_expires_on' => DateTime::now()->addYear(2),
                'status' => 'active',
                'warrantable' => true,
                'title' => 'Lord',
                'pronouns' => 'he/him',
                'pronunciation' => 'ETH-el-mark HAIR-ald',
                'birth_month' => 6,
                'birth_year' => 1985,
                'additional_info' => json_encode([
                    'emergency_contact' => [
                        'name' => 'Jane Smith',
                        'phone' => '555-0123',
                        'relationship' => 'spouse'
                    ],
                    'interests' => ['heraldry', 'scribal arts', 'teaching']
                ]),
                'verified_date' => DateTime::now(),
                'verified_by' => 1,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            // College member example
            [
                'sca_name' => 'Collegium Student',
                'first_name' => 'Sarah',
                'last_name' => 'Johnson',
                'email_address' => 'student@university.edu',
                'password' => $defaultPassword,
                'membership_number' => 'KM789012',
                'membership_expires_on' => DateTime::now()->addMonths(6),
                'branch_id' => SeedHelpers::getBranchIdByName('College of Example University'),
                'status' => 'active',
                'warrantable' => false,
                'pronouns' => 'she/her',
                'birth_month' => 3,
                'birth_year' => 2000,
                'additional_info' => json_encode([
                    'student_status' => true,
                    'graduation_year' => 2024,
                    'interests' => ['archery', 'dancing', 'cooking']
                ]),
                'verified_date' => DateTime::now(),
                'verified_by' => 1,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            // Minor with parent
            [
                'sca_name' => 'Young Page',
                'first_name' => 'Alex',
                'last_name' => 'Smith',
                'email_address' => 'parent@example.com', // Parent's email
                'password' => $defaultPassword,
                'branch_id' => SeedHelpers::getBranchIdByName('Barony of Test'),
                'parent_id' => SeedHelpers::getMemberId('herald@example.com'),
                'status' => 'active',
                'warrantable' => false,
                'pronouns' => 'they/them',
                'birth_month' => 8,
                'birth_year' => 2010,
                'additional_info' => json_encode([
                    'minor_account' => true,
                    'interests' => ['youth combat', 'arts and crafts']
                ]),
                'verified_date' => DateTime::now(),
                'verified_by' => 1,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
        ];
    }
}

Plugin-Specific Seeds

Officers Plugin Seeds

DevLoadDepartmentsSeed.php

Creates organizational departments:

class DevLoadDepartmentsSeed extends BaseSeed
{
    public function getData(): array
    {
        return [
            [
                'name' => 'Operations',
                'description' => 'Core operational offices and administration',
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            [
                'name' => 'Arts & Sciences',
                'description' => 'Arts, sciences, and educational activities',
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            [
                'name' => 'Martial Activities',
                'description' => 'Combat sports and martial activities',
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
        ];
    }
}

DevLoadOfficesSeed.php

Creates office position definitions:

class DevLoadOfficesSeed extends BaseSeed
{
    public function getData(): array
    {
        return [
            // Core required offices
            [
                'name' => 'Branch Officer',
                'department_id' => SeedHelpers::getDepartmentId('Operations'),
                'requires_warrant' => true,
                'required_office' => true,
                'only_one_per_branch' => true,
                'grants_role_id' => SeedHelpers::getRoleId('Branch Officer'),
                'term_length' => 24,
                'applicable_branch_types' => json_encode(['Local', 'College']),
                'default_contact_address' => 'officer@{branch.domain}',
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            [
                'name' => 'Deputy Branch Officer',
                'department_id' => SeedHelpers::getDepartmentId('Operations'),
                'deputy_to_id' => SeedHelpers::getOfficeId('Branch Officer'),
                'reports_to_id' => SeedHelpers::getOfficeId('Branch Officer'),
                'requires_warrant' => false,
                'term_length' => 24,
                'applicable_branch_types' => json_encode(['Local', 'College']),
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            [
                'name' => 'Herald',
                'department_id' => SeedHelpers::getDepartmentId('Arts & Sciences'),
                'requires_warrant' => true,
                'required_office' => true,
                'reports_to_id' => SeedHelpers::getOfficeId('Branch Officer'),
                'term_length' => 12,
                'applicable_branch_types' => json_encode(['Local', 'College']),
                'default_contact_address' => 'herald@{branch.domain}',
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
        ];
    }
}

Awards Plugin Seeds

DevLoadAwardsLevelsSeed.php

Creates award precedence hierarchy:

class DevLoadAwardsLevelsSeed extends BaseSeed
{
    public function getData(): array
    {
        return [
            [
                'name' => 'Kingdom Level',
                'precedence' => 1000,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            [
                'name' => 'Principality Level',
                'precedence' => 800,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            [
                'name' => 'Baronial Level',
                'precedence' => 600,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            [
                'name' => 'Local Level',
                'precedence' => 400,
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
        ];
    }
}

DevLoadAwardsAwardsSeed.php

Creates sample awards with classification:

class DevLoadAwardsAwardsSeed extends BaseSeed
{
    public function getData(): array
    {
        return [
            // Service award
            [
                'name' => 'Award of Arms',
                'abbreviation' => 'AoA',
                'description' => 'Recognition of exceptional service to the Kingdom',
                'domain_id' => SeedHelpers::getAwardsDomainId('Service'),
                'level_id' => SeedHelpers::getAwardsLevelId('Kingdom Level'),
                'branch_id' => SeedHelpers::getBranchIdByName('Kingdom'),
                'charter' => 'Charter text here...',
                'specialties' => json_encode([
                    'service_types' => ['event_steward', 'officer', 'teaching']
                ]),
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            // Arts & Sciences award
            [
                'name' => 'Order of the Laurel',
                'abbreviation' => 'OL',
                'description' => 'Recognition of exceptional skill in the Arts and Sciences',
                'domain_id' => SeedHelpers::getAwardsDomainId('Arts & Sciences'),
                'level_id' => SeedHelpers::getAwardsLevelId('Kingdom Level'),
                'branch_id' => SeedHelpers::getBranchIdByName('Kingdom'),
                'charter' => 'Charter text here...',
                'specialties' => json_encode([
                    'arts_sciences' => ['cooking', 'scribal', 'clothing', 'research']
                ]),
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
        ];
    }
}

Activities Plugin Seeds

DevLoadActivitiesSeed.php

Creates activity definitions with authorization requirements:

class DevLoadActivitiesSeed extends BaseSeed
{
    public function getData(): array
    {
        return [
            [
                'name' => 'Youth Combat Marshal',
                'description' => 'Authorization to marshal youth combat activities',
                'activity_group_id' => SeedHelpers::getActivityGroupId('Youth Combat'),
                'grants_role_id' => SeedHelpers::getRoleId('Youth Marshal'),
                'permission_id' => SeedHelpers::getPermissionId('marshal youth combat'),
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
            
            [
                'name' => 'Archery Marshal',
                'description' => 'Authorization to marshal archery activities',
                'activity_group_id' => SeedHelpers::getActivityGroupId('Target Archery'),
                'grants_role_id' => SeedHelpers::getRoleId('Archery Marshal'),
                'permission_id' => SeedHelpers::getPermissionId('marshal archery'),
                'created' => DateTime::now(),
                'created_by' => 1,
            ],
        ];
    }
}

Configuration Seeds

Application Settings

DevLoadAppSettingsSeed.php

Populates application configuration:

class DevLoadAppSettingsSeed extends BaseSeed
{
    public function getData(): array
    {
        return [
            // Core application settings
            [
                'name' => 'application.title',
                'value' => 'Kingdom Activity Management System',
                'required' => true,
                'created' => DateTime::now(),
            ],
            
            [
                'name' => 'application.version',
                'value' => '3.0.0-dev',
                'required' => true,
                'created' => DateTime::now(),
            ],
            
            // GitHub integration settings
            [
                'name' => 'github.repository_owner',
                'value' => 'kingdom-org',
                'required' => false,
                'created' => DateTime::now(),
            ],
            
            [
                'name' => 'github.repository_name',
                'value' => 'feedback',
                'required' => false,
                'created' => DateTime::now(),
            ],
            
            // Email configuration
            [
                'name' => 'email.from_address',
                'value' => 'noreply@kingdom.example.com',
                'required' => true,
                'created' => DateTime::now(),
            ],
            
            // Features toggles
            [
                'name' => 'features.github_issue_submitter',
                'value' => 'true',
                'required' => false,
                'created' => DateTime::now(),
            ],
        ];
    }
}

Seeding Execution

Command Line Interface

# Run all development seeds
bin/cake seed run DevLoad

# Run specific seed
bin/cake seed run DevLoadMembersSeed

# Run initialization seeds (production setup)
bin/cake seed run InitMigrationSeed

# Plugin-specific seeding
bin/cake seed run -p Officers DevLoadOfficersSeed
bin/cake seed run -p Awards DevLoadAwardsAwardsSeed
bin/cake seed run -p Activities DevLoadActivitiesSeed

Environment-Specific Seeding

Development Environment

// Complete development data set
$this->call('DevLoad');

Testing Environment

// Minimal test fixtures
$this->call('TestDataSeed');

Production Environment

// Only essential initialization data
$this->call('InitMigrationSeed');

Advanced Seeding Patterns

1. Referential Integrity Management

public function getData(): array
{
    $data = [];
    
    // Get dependent record IDs
    $branchId = SeedHelpers::getBranchIdByName('Kingdom');
    $roleId = SeedHelpers::getRoleId('Super User');
    $memberId = SeedHelpers::getMemberId('admin@example.com');
    
    return [
        [
            'member_id' => $memberId,
            'role_id' => $roleId,
            'branch_id' => $branchId,
            'start_on' => DateTime::now(),
            'expires_on' => DateTime::now()->addYear(1),
            'status' => 'current',
            'created' => DateTime::now(),
            'created_by' => $memberId,
        ]
    ];
}

2. Conditional Seeding

public function run(): void
{
    $branchesTable = $this->getAdapter()->getConnection()
        ->query('SELECT COUNT(*) as count FROM branches')
        ->fetch();
    
    if ($branchesTable['count'] == 0) {
        // Only seed if no branches exist
        $data = $this->getData();
        $this->table('branches')->insert($data)->saveData();
    }
}

3. Batch Seeding for Large Datasets

public function run(): void
{
    $batchSize = 1000;
    $data = $this->getData();
    $batches = array_chunk($data, $batchSize);
    
    foreach ($batches as $batch) {
        $this->table('large_table')->insert($batch)->saveData();
    }
}

4. JSON Field Seeding

public function getData(): array
{
    return [
        [
            'name' => 'Complex Configuration',
            'json_field' => json_encode([
                'nested' => [
                    'configuration' => 'value',
                    'options' => ['option1', 'option2']
                ],
                'feature_flags' => [
                    'new_feature' => true,
                    'beta_feature' => false
                ]
            ]),
            'created' => DateTime::now(),
        ]
    ];
}

Testing Integration

Fixture Generation from Seeds

class MembersFixture extends TestFixture
{
    public function init(): void
    {
        // Use seed data for test fixtures
        $seed = new DevLoadMembersSeed();
        $this->records = $seed->getData();
        parent::init();
    }
}

Seed Validation Tests

class SeedValidationTest extends TestCase
{
    public function testSeedDataIntegrity()
    {
        $seed = new DevLoadMembersSeed();
        $data = $seed->getData();
        
        foreach ($data as $record) {
            $this->assertNotEmpty($record['sca_name']);
            $this->assertNotEmpty($record['email_address']);
            $this->assertTrue(filter_var($record['email_address'], FILTER_VALIDATE_EMAIL));
        }
    }
}

Best Practices

1. Data Consistency

2. Environment Awareness

3. Performance Optimization

4. Maintenance


This seeding documentation provides comprehensive guidance for populating the KMP database with initial and development data. For implementation details, refer to the specific seed files in app/config/Seeds/ and the Migration Documentation.