connect(); foreach([ 'users'=>['user_email_verified_at'=>'DATETIME NULL'], 'club_dues'=>['recorded_by'=>'BIGINT UNSIGNED NULL'], 'club_payments'=>['recorded_by'=>'BIGINT UNSIGNED NULL','payment_method'=>"VARCHAR(20) NOT NULL DEFAULT 'unspecified'",'payment_reference'=>"VARCHAR(100) NOT NULL DEFAULT ''"], ] as $table=>$columns){ $existing=$db->query('SHOW COLUMNS FROM `'.$table.'`')->fetchAll(PDO::FETCH_COLUMN); foreach($columns as $column=>$definition)if(!in_array($column,$existing,true))$db->exec('ALTER TABLE `'.$table.'` ADD COLUMN `'.$column.'` '.$definition); } // Mandatory audit writes must participate in financial transactions. $db->exec('ALTER TABLE journal ENGINE=InnoDB'); $db->exec('ALTER TABLE journal MODIFY journal_entry TEXT NULL'); foreach(['club_dues','club_payments'] as $table){ $stmt=$db->prepare("SELECT COUNT(*) FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=? AND COLUMN_NAME='recorded_by' AND REFERENCED_TABLE_NAME='users'");$stmt->execute([$table]); if(!(int)$stmt->fetchColumn())$db->exec('ALTER TABLE `'.$table.'` ADD FOREIGN KEY (recorded_by) REFERENCES users(user_serial) ON DELETE RESTRICT'); } foreach(explode(';',file_get_contents(__DIR__.'/../migrations/003_production.sql')) as $sql)if(trim($sql))$db->exec($sql); require __DIR__.'/../views/view_users.php';$db->exec(str_replace('create view','CREATE OR REPLACE VIEW',$SQL)); echo "Production safeguards schema is ready. Existing emails remain unverified until ownership is proven.\n";