$stmt=$db->prepare("INSERT INTO users(user_name,user_first_name,user_last_name,user_email,user_password_hash,user_role) VALUES('testadmin','Test','Administrator','admin@example.test',?,'Administrator')");$stmt->execute([password_hash('Admin test password 123!',PASSWORD_DEFAULT)]);
$season=$db->prepare('INSERT INTO club_seasons(club_serial,season_name,starts_on,ends_on) VALUES(?,?,?,?)');
$due=$db->prepare('INSERT INTO club_dues(club_serial,membership_serial,season_serial,amount_cents,recorded_by) VALUES(?,?,?,?,1)');
for($i=1;$i<=31;$i++){$season->execute([$a,'Member season '.sprintf('%02d',$i),'2026-01-01','2026-12-31']);$due->execute([$a,$own,(int)$db->lastInsertId(),10000]);if(!$first)$first=(int)$db->lastInsertId();}
$pay=$db->prepare("INSERT INTO club_payments(due_serial,amount_cents,paid_on,request_key,payment_method,payment_reference,recorded_by) VALUES(?,100,'2026-01-01',?,'cash',?,1)");
$stmt=$db->prepare('INSERT INTO club_payment_reversals(payment_serial,reason,request_key,recorded_by) VALUES(?,?,?,1)');$stmt->execute([$reversed,'Own reversed receipt',bin2hex(random_bytes(32))]);
$stmt=$db->prepare('INSERT INTO club_due_adjustments(due_serial,amount_cents,corrected_amount_cents,reason,request_key,recorded_by) VALUES(?,5000,15000,?,?,1)');$stmt->execute([$first,'Own correction <script>unsafe</script>',bin2hex(random_bytes(32))]);
foreach([[$a,$neighbor,'NEIGHBOR-PRIVATE'],[$b,$foreign,'FOREIGN-PRIVATE']]as[$club,$membership,$marker]){$season->execute([$club,'Additional season '.$membership,'2026-01-01','2026-12-31']);$due->execute([$club,$membership,(int)$db->lastInsertId(),99999]);$pay->execute([(int)$db->lastInsertId(),bin2hex(random_bytes(32)),$marker]);}
$season->execute([$a,'Available new season','2026-01-01','2026-12-31']);
echo'{}';exit;
}
if($action==='sessionAge'){
$id=$argv[3]??'';if(!preg_match('/\A[a-zA-Z0-9,-]{16,128}\z/',$id))thrownewRuntimeException('Invalid test session.');
$user=(int)($_SESSION[Base::USER_SERIAL]??0);$stmt=$db->prepare('SELECT 1 FROM users WHERE user_serial=?');$stmt->execute([$user]);if(!$stmt->fetchColumn())thrownewRuntimeException('Owned test account required.');
if(($argv[3]??'')==='on')$db->exec("CREATE TRIGGER reject_mfa_test_audit BEFORE INSERT ON journal FOR EACH ROW SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='Test audit failure'");
else$db->exec('DROP TRIGGER IF EXISTS reject_mfa_test_audit');echo'{}';exit;
}
if($action==='mfaResetToken'){
$token=bin2hex(random_bytes(32));$stmt=$db->prepare('INSERT INTO password_resets(token_hash,user_serial,expires_at) VALUES(?,1,DATE_ADD(UTC_TIMESTAMP(),INTERVAL 1 HOUR))');$stmt->execute([hash('sha256',$token)]);echojson_encode(['token'=>$token]);exit;
}
if($action==='mfaState'){
$stmt=$db->prepare('SELECT user_serial FROM users WHERE user_email=?');$stmt->execute([$argv[3]]);$user=(int)$stmt->fetchColumn();
$stmt=$db->prepare('SELECT * FROM user_mfa WHERE user_serial=?');$stmt->execute([$user]);$factor=$stmt->fetch();
$stmt=$db->prepare('SELECT code_hash FROM mfa_recovery WHERE user_serial=?');$stmt->execute([$user]);echojson_encode(['factor'=>$factor,'recovery'=>$stmt->fetchAll(PDO::FETCH_COLUMN)]);exit;
}
if($action==='mfaCode'){
$stmt=$db->prepare('SELECT user_serial FROM users WHERE user_email=?');$stmt->execute([$argv[3]]);$user=(int)$stmt->fetchColumn();
$code=bin2hex(random_bytes(16));$stmt=$db->prepare('INSERT INTO mfa_recovery(user_serial,code_hash) VALUES(?,?)');$stmt->execute([$user,hash('sha256',$code)]);echojson_encode(['code'=>$code]);exit;
$result=[];foreach($db->query('SHOW FULL TABLES WHERE Table_type="BASE TABLE"')->fetchAll(PDO::FETCH_COLUMN)as$table){
$rows=array_map(staticfn($row)=>json_encode($row,JSON_THROW_ON_ERROR),$db->query('SELECT * FROM `'.str_replace('`','``',$table).'`')->fetchAll(PDO::FETCH_ASSOC));sort($rows,SORT_STRING);$result[$table]=hash('sha256',implode("\n",$rows));
}echojson_encode($result);exit;
}
if($action==='verifyEmail'){
$stmt=$db->prepare('UPDATE users SET user_email_verified_at=UTC_TIMESTAMP() WHERE user_name=?');$stmt->execute([$argv[3]??'']);echojson_encode(['verified'=>true]);exit;
if($action==='legacyTenantSchema'){$db->exec('ALTER TABLE club_memberships DROP COLUMN membership_role');$db->exec('ALTER TABLE clubs DROP INDEX club_name, ADD UNIQUE KEY club_name (club_name)');echo'{}';exit;}
if($action==='restoreTestSuper'){$db->exec("UPDATE users SET user_status='active' WHERE user_serial=1");echo'{}';exit;}
if($action==='seedTenantInvitation'){
$stmt=$db->prepare("INSERT INTO club_invitations(club_serial,invited_by,invite_email,expires_at,sent_at) VALUES(?,?,?,DATE_ADD(UTC_TIMESTAMP(),INTERVAL 1 DAY),UTC_TIMESTAMP())");$stmt->execute([(int)$argv[3],(int)$argv[4],$argv[5]]);echojson_encode(['invitation'=>(int)$db->lastInsertId()]);exit;
}
if($action==='demoteTenantAdmin'){
$stmt=$db->prepare("UPDATE club_memberships SET membership_role='member' WHERE membership_serial=?");$stmt->execute([(int)($argv[3]??0)]);echo'{}';exit;
$stmt=$db->prepare("INSERT INTO club_memberships(club_serial,user_serial,membership_status,joined_on) VALUES(?,?,'inactive','2026-01-01')");$stmt->execute([$club,$user]);$membership=(int)$db->lastInsertId();
$stmt=$db->prepare("INSERT INTO club_invitations(club_serial,invite_email,invited_by,expires_at,sent_at) SELECT ?,user_email,?,DATE_ADD(UTC_TIMESTAMP(),INTERVAL 1 DAY),UTC_TIMESTAMP() FROM users WHERE user_serial=?");$stmt->execute([$club,$inviter,$user]);echojson_encode(['membership'=>$membership,'invitation'=>(int)$db->lastInsertId()]);exit;
$ids=[];$hash=password_hash('Tenant test password 123!',PASSWORD_DEFAULT);
$insert=$db->prepare("INSERT INTO users(user_name,user_first_name,user_last_name,user_email,user_password_hash,user_role,user_email_verified_at) VALUES(?,?,?,?,?,?,UTC_TIMESTAMP())");
$db->exec("UPDATE users SET user_email_verified_at=NULL WHERE user_name='tenantunverified'");
$db->exec("INSERT INTO clubs(club_name) VALUES('Tenant Alpha')");$ids['clubA']=(int)$db->lastInsertId();$db->exec("INSERT INTO clubs(club_name) VALUES('Tenant Beta')");$ids['clubB']=(int)$db->lastInsertId();
$stmt=$db->prepare("INSERT INTO club_memberships(club_serial,user_serial,membership_role,joined_on) VALUES(?,?,?,'2026-01-01')");
$out=[];foreach(['alerts','popovers']as$table)$out[$table]=$db->query('SELECT * FROM '.$table.' ORDER BY 1')->fetchAll(PDO::FETCH_ASSOC);echojson_encode($out);exit;
$db->exec("INSERT INTO dropdowntypes(dropdowntype_name,dropdowntype_title,dropdowntype_table,dropdowntype_column) VALUES('Unsafe legacy','Unsafe legacy','*function','getSettings')");$type=(int)$db->lastInsertId();
$stmt=$db->prepare("INSERT INTO dropdowns(dropdown_dropdowntype,dropdown_value) VALUES(?,'Legacy')");$stmt->execute([$type]);echojson_encode(['dropdown'=>(int)$db->lastInsertId()]);exit;
}
if($action==='paging'){
$tip=$db->prepare('INSERT INTO popovers(popover_name,popover_title,popover_text) VALUES(?,?,?)');
$user=$db->prepare("INSERT INTO users(user_name,user_first_name,user_last_name,user_email,user_password_hash,user_role) VALUES(?,?,?,?,?,'User')");
$hash=password_hash('Paging test password!',PASSWORD_DEFAULT);