tinyqc/app/Database/Seeds/CmodQcSeeder.php
mahdahar 87ff4c8d85 feat: Add user authentication system and secure all routes
- Implement AuthController with login/logout functionality
- Create UsersModel with bcrypt password hashing
- Add AuthFilter to protect all application routes
- Create login page with error handling
- Add users database migration with email/username fields
- Rename ResultComments to TestComments for consistency
- Update all routes to require authentication filter
- Enhance EntryApiController with comment deletion and better error handling
- Update seeder to include demo users and improved test data
- Fix BaseController to handle auth sessions properly
- Update entry views (daily/monthly) with new API endpoints
- Update layout with logout button and user info display
- Refactor control test index view for better organization
2026-02-09 11:12:12 +07:00

234 lines
12 KiB
PHP

<?php
namespace App\Database\Seeds;
use CodeIgniter\Database\Seeder;
class CmodQcSeeder extends Seeder
{
public function run()
{
$this->seedDepts();
$this->seedControls();
$this->seedTests();
$this->seedControlTests();
$this->seedResults();
$this->seedTestComments();
}
protected function seedDepts()
{
$depts = [
['dept_name' => 'Chemistry'],
['dept_name' => 'Hematology'],
['dept_name' => 'Immunology'],
['dept_name' => 'Urinalysis'],
];
$this->db->table('master_depts')->insertBatch($depts);
}
protected function seedControls()
{
$controls = [
['dept_id' => 1, 'control_name' => 'QC Normal Chemistry', 'lot' => 'QC2024001', 'producer' => 'BioRad', 'exp_date' => '2025-12-31'],
['dept_id' => 1, 'control_name' => 'QC High Chemistry', 'lot' => 'QC2024002', 'producer' => 'BioRad', 'exp_date' => '2025-12-31'],
['dept_id' => 2, 'control_name' => 'QC Normal Hema', 'lot' => 'QC2024003', 'producer' => 'Streck', 'exp_date' => '2025-11-30'],
['dept_id' => 2, 'control_name' => 'QC Low Hema', 'lot' => 'QC2024004', 'producer' => 'Streck', 'exp_date' => '2025-11-30'],
['dept_id' => 3, 'control_name' => 'QC Normal Immuno', 'lot' => 'QC2024005', 'producer' => 'Roche', 'exp_date' => '2025-10-31'],
['dept_id' => 4, 'control_name' => 'QC Normal Urine', 'lot' => 'QC2024006', 'producer' => 'Siemens', 'exp_date' => '2025-09-30'],
// January 2026 controls
['dept_id' => 1, 'control_name' => 'Trulab N', 'lot' => 'TN2026001', 'producer' => 'Trinity', 'exp_date' => '2026-12-31'],
['dept_id' => 1, 'control_name' => 'Trulab P', 'lot' => 'TP2026001', 'producer' => 'Trinity', 'exp_date' => '2026-12-31'],
['dept_id' => 1, 'control_name' => 'Cholestest', 'lot' => 'CT2026001', 'producer' => 'Roche', 'exp_date' => '2026-12-31'],
// February 2026 controls (new lots)
['dept_id' => 2, 'control_name' => 'QC Normal Hema', 'lot' => 'H202602', 'producer' => 'Streck', 'exp_date' => '2026-12-31'],
['dept_id' => 2, 'control_name' => 'QC Low Hema', 'lot' => 'HL202602', 'producer' => 'Streck', 'exp_date' => '2026-12-31'],
['dept_id' => 1, 'control_name' => 'Trulab N', 'lot' => 'TN202602', 'producer' => 'Trinity', 'exp_date' => '2026-12-31'],
];
$this->db->table('master_controls')->insertBatch($controls);
}
protected function seedTests()
{
$tests = [
['dept_id' => 1, 'test_code' => 'GLU', 'test_name' => 'Glucose', 'test_unit' => 'mg/dL', 'test_method' => 'GOD-PAP', 'cva' => 5, 'ba' => 3, 'tea' => 10],
['dept_id' => 1, 'test_code' => 'CRE', 'test_name' => 'Creatinine', 'test_unit' => 'mg/dL', 'test_method' => 'Jaffe', 'cva' => 4, 'ba' => 2, 'tea' => 8],
['dept_id' => 1, 'test_code' => 'BUN', 'test_name' => 'Urea Nitrogen', 'test_unit' => 'mg/dL', 'test_method' => 'UREASE', 'cva' => 5, 'ba' => 3, 'tea' => 12],
['dept_id' => 1, 'test_code' => 'CHOL', 'test_name' => 'Cholesterol', 'test_unit' => 'mg/dL', 'test_method' => 'CHOD-PAP', 'cva' => 6, 'ba' => 4, 'tea' => 15],
['dept_id' => 2, 'test_code' => 'WBC', 'test_name' => 'WBC', 'test_unit' => 'x10^3/uL', 'test_method' => 'Impedance', 'cva' => 8, 'ba' => 5, 'tea' => 20],
['dept_id' => 2, 'test_code' => 'RBC', 'test_name' => 'RBC', 'test_unit' => 'x10^6/uL', 'test_method' => 'Impedance', 'cva' => 3, 'ba' => 2, 'tea' => 8],
['dept_id' => 2, 'test_code' => 'HGB', 'test_name' => 'Hemoglobin', 'test_unit' => 'g/dL', 'test_method' => 'Cyanmethemoglobin', 'cva' => 2, 'ba' => 1, 'tea' => 5],
['dept_id' => 3, 'test_code' => 'TSH', 'test_name' => 'TSH', 'test_unit' => 'mIU/L', 'test_method' => 'ECLIA', 'cva' => 10, 'ba' => 6, 'tea' => 25],
['dept_id' => 3, 'test_code' => 'FT4', 'test_name' => 'Free T4', 'test_unit' => 'ng/dL', 'test_method' => 'ECLIA', 'cva' => 8, 'ba' => 5, 'tea' => 20],
['dept_id' => 4, 'test_code' => 'UP', 'test_name' => 'Urine Protein', 'test_unit' => 'mg/dL', 'test_method' => 'Dipstick', 'cva' => 10, 'ba' => 8, 'tea' => 30],
];
$this->db->table('master_tests')->insertBatch($tests);
}
protected function seedControlTests()
{
$controlTests = [
['control_id' => 1, 'test_id' => 1, 'mean' => 95, 'sd' => 5],
['control_id' => 1, 'test_id' => 2, 'mean' => 1.0, 'sd' => 0.05],
['control_id' => 1, 'test_id' => 3, 'mean' => 15, 'sd' => 1.2],
['control_id' => 2, 'test_id' => 1, 'mean' => 180, 'sd' => 12],
['control_id' => 2, 'test_id' => 2, 'mean' => 2.5, 'sd' => 0.15],
['control_id' => 2, 'test_id' => 4, 'mean' => 200, 'sd' => 15],
['control_id' => 3, 'test_id' => 5, 'mean' => 7.5, 'sd' => 0.6],
['control_id' => 3, 'test_id' => 6, 'mean' => 4.8, 'sd' => 0.2],
['control_id' => 3, 'test_id' => 7, 'mean' => 14.5, 'sd' => 0.5],
['control_id' => 4, 'test_id' => 5, 'mean' => 3.5, 'sd' => 0.3],
['control_id' => 4, 'test_id' => 6, 'mean' => 2.5, 'sd' => 0.15],
['control_id' => 5, 'test_id' => 8, 'mean' => 2.5, 'sd' => 0.3],
['control_id' => 5, 'test_id' => 9, 'mean' => 1.2, 'sd' => 0.1],
['control_id' => 6, 'test_id' => 10, 'mean' => 10, 'sd' => 1.5],
['control_id' => 1, 'test_id' => 4, 'mean' => 150, 'sd' => 10],
// New control-tests for January 2026
['control_id' => 7, 'test_id' => 1, 'mean' => 90, 'sd' => 4], // Trulab N - Glucose
['control_id' => 7, 'test_id' => 2, 'mean' => 0.9, 'sd' => 0.04], // Trulab N - Creatinine
['control_id' => 7, 'test_id' => 4, 'mean' => 145, 'sd' => 8], // Trulab N - Cholesterol
['control_id' => 8, 'test_id' => 1, 'mean' => 175, 'sd' => 10], // Trulab P - Glucose
['control_id' => 8, 'test_id' => 2, 'mean' => 2.4, 'sd' => 0.12], // Trulab P - Creatinine
['control_id' => 8, 'test_id' => 4, 'mean' => 195, 'sd' => 12], // Trulab P - Cholesterol
['control_id' => 9, 'test_id' => 4, 'mean' => 180, 'sd' => 10], // Cholestest - Cholesterol
// February 2026 control-tests
['control_id' => 10, 'test_id' => 5, 'mean' => 7.6, 'sd' => 0.5], // QC Normal Hema (Feb) - WBC
['control_id' => 10, 'test_id' => 6, 'mean' => 4.7, 'sd' => 0.2], // QC Normal Hema (Feb) - RBC
['control_id' => 10, 'test_id' => 7, 'mean' => 14.8, 'sd' => 0.4], // QC Normal Hema (Feb) - HGB
['control_id' => 11, 'test_id' => 5, 'mean' => 3.4, 'sd' => 0.25], // QC Low Hema (Feb) - WBC
['control_id' => 11, 'test_id' => 6, 'mean' => 2.4, 'sd' => 0.14], // QC Low Hema (Feb) - RBC
['control_id' => 12, 'test_id' => 1, 'mean' => 92, 'sd' => 4.2], // Trulab N (Feb) - Glucose
['control_id' => 12, 'test_id' => 2, 'mean' => 0.95, 'sd' => 0.05], // Trulab N (Feb) - Creatinine
['control_id' => 12, 'test_id' => 4, 'mean' => 148, 'sd' => 9], // Trulab N (Feb) - Cholesterol
];
$this->db->table('control_tests')->insertBatch($controlTests);
}
protected function seedResults()
{
$faker = \Faker\Factory::create();
$results = [];
$controlTests = $this->db->table('control_tests')->get()->getResultArray();
$resultCount = 0;
$maxResults = 150; // Increased for more test data
// January 2026 results (days 1-31)
foreach ($controlTests as $ct) {
$numResults = $faker->numberBetween(3, 5);
for ($i = 0; $i < $numResults && $resultCount < $maxResults; $i++) {
$day = $faker->numberBetween(1, 31);
$resDate = "2026-01-" . str_pad($day, 2, '0', STR_PAD_LEFT);
$value = $ct['mean'] + ($faker->randomFloat(2, -2.5, 2.5) * $ct['sd']);
$results[] = [
'control_id' => $ct['control_id'],
'test_id' => $ct['test_id'],
'res_date' => $resDate,
'res_value' => round($value, 2),
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
];
$resultCount++;
}
}
// February 2026 results (days 1-28)
foreach ($controlTests as $ct) {
$numResults = $faker->numberBetween(3, 5);
for ($i = 0; $i < $numResults && $resultCount < $maxResults; $i++) {
$day = $faker->numberBetween(1, 28);
$resDate = "2026-02-" . str_pad($day, 2, '0', STR_PAD_LEFT);
$value = $ct['mean'] + ($faker->randomFloat(2, -2.5, 2.5) * $ct['sd']);
$results[] = [
'control_id' => $ct['control_id'],
'test_id' => $ct['test_id'],
'res_date' => $resDate,
'res_value' => round($value, 2),
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
];
$resultCount++;
}
}
$this->db->table('results')->insertBatch($results);
}
protected function seedTestComments()
{
$faker = \Faker\Factory::create();
$comments = [];
// Get all tests
$tests = $this->db->table('master_tests')->get()->getResultArray();
// Comment templates for different test types
$commentTemplates = [
'QC stable throughout the period',
'Slight drift observed, monitoring continued',
'Calibration verified, values within range',
'Reagent lot changed, new QC run initiated',
'Instrument maintenance performed',
'Shift detected, corrective action taken',
'Control values consistent with previous lot',
'Temperature check completed, within specs',
'New lot validated successfully',
'Periodic check satisfactory',
];
// Generate comments for Jan 2026 (days 1-31)
foreach ($tests as $test) {
$numComments = $faker->numberBetween(3, 6);
$usedDates = [];
for ($i = 0; $i < $numComments; $i++) {
// Pick a random date in January
do {
$day = $faker->numberBetween(1, 31);
$dateKey = "2026-01-" . str_pad($day, 2, '0', STR_PAD_LEFT);
} while (in_array($dateKey, $usedDates));
$usedDates[] = $dateKey;
$comments[] = [
'test_id' => $test['test_id'],
'comment_date' => $dateKey,
'comment_text' => $faker->randomElement($commentTemplates),
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
];
}
}
// Generate comments for Feb 2026 (days 1-28)
foreach ($tests as $test) {
$numComments = $faker->numberBetween(2, 5);
$usedDates = [];
for ($i = 0; $i < $numComments; $i++) {
// Pick a random date in February
do {
$day = $faker->numberBetween(1, 28);
$dateKey = "2026-02-" . str_pad($day, 2, '0', STR_PAD_LEFT);
} while (in_array($dateKey, $usedDates));
$usedDates[] = $dateKey;
$comments[] = [
'test_id' => $test['test_id'],
'comment_date' => $dateKey,
'comment_text' => $faker->randomElement($commentTemplates) . ' (Feb)',
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
];
}
}
$this->db->table('test_comments')->insertBatch($comments);
}
}