Files
api/services/nginx/app/classes/selfserve_schema_bootstrap.php
T

152 lines
6.2 KiB
PHP

<?php
namespace classes;
/**
* Ensures additive self-serve tables and columns exist.
*
* This project has no centralized migration runner, so the bootstrap must be
* idempotent and safe to call from runtime flows.
*/
class selfserve_schema_bootstrap
{
private static bool $initialized = false;
public static function ensureTables(): void
{
if (self::$initialized) {
return;
}
global $db;
$queries = [
"CREATE TABLE IF NOT EXISTS selfserve_machine_types (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description VARCHAR(255) NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
UNIQUE KEY uniq_selfserve_machine_types_name (name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
"CREATE TABLE IF NOT EXISTS selfserve_wash_sessions (
id INT AUTO_INCREMENT PRIMARY KEY,
lane_id INT NOT NULL,
department_id INT NOT NULL,
machine_type_id INT NULL,
customer_number INT NULL,
vehicle_id INT NULL,
vehicle_type_id INT NULL,
reg VARCHAR(255) NOT NULL,
status VARCHAR(64) NOT NULL DEFAULT 'PENDING_QUESTIONS',
allowed TINYINT(1) NOT NULL DEFAULT 0,
machine_relay_enabled TINYINT(1) NOT NULL DEFAULT 0,
machine_relay_enabled_at DATETIME NULL,
machine_start_triggered TINYINT(1) NOT NULL DEFAULT 0,
machine_start_triggered_at DATETIME NULL,
order_id INT NULL,
completed_at DATETIME NULL,
metadata_json JSON NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
INDEX idx_selfserve_wash_sessions_lane_reg (lane_id, reg),
INDEX idx_selfserve_wash_sessions_status (status),
INDEX idx_selfserve_wash_sessions_customer (customer_number),
INDEX idx_selfserve_wash_sessions_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
"CREATE TABLE IF NOT EXISTS selfserve_wash_session_answers (
id INT AUTO_INCREMENT PRIMARY KEY,
session_id INT NOT NULL,
question_id INT NOT NULL,
question_text VARCHAR(255) NOT NULL,
answer_value TINYINT(1) NOT NULL,
answered_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
UNIQUE KEY uniq_selfserve_wash_session_answer (session_id, question_id),
INDEX idx_selfserve_wash_session_answers_session (session_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
"CREATE TABLE IF NOT EXISTS selfserve_wash_session_tasks (
id INT AUTO_INCREMENT PRIMARY KEY,
session_id INT NOT NULL,
task_id INT NULL,
task_text VARCHAR(255) NOT NULL,
description VARCHAR(255) NULL,
services JSON NULL,
buttons JSON NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
INDEX idx_selfserve_wash_session_tasks_session (session_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
"CREATE TABLE IF NOT EXISTS selfserve_wash_session_events (
id INT AUTO_INCREMENT PRIMARY KEY,
session_id INT NOT NULL,
event_type VARCHAR(64) NOT NULL,
payload_json JSON NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_selfserve_wash_session_events_session (session_id),
INDEX idx_selfserve_wash_session_events_type (event_type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
];
foreach ($queries as $sql) {
$db->query($sql);
}
self::ensureColumn(
'department_lanes',
'machine_type_id',
'ALTER TABLE department_lanes ADD COLUMN machine_type_id INT NULL AFTER dynamic_image_id'
);
self::ensureColumn(
'department_selfserve_conditions',
'machine_type_id',
'ALTER TABLE department_selfserve_conditions ADD COLUMN machine_type_id INT NULL AFTER product'
);
self::ensureColumn(
'department_selfserve_tasks',
'machine_type_id',
'ALTER TABLE department_selfserve_tasks ADD COLUMN machine_type_id INT NULL AFTER product'
);
self::$initialized = true;
}
public static function tableHasColumn(string $table, string $column): bool
{
global $db;
$table = $db->escape_string($table);
$column = $db->escape_string($column);
$database = $db->escape_string($db->getDatabase());
$sql = "SELECT COUNT(*) AS c
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = '$database'
AND TABLE_NAME = '$table'
AND COLUMN_NAME = '$column'";
$result = $db->query($sql);
if (!$result) {
return false;
}
$row = $result->fetch_assoc();
return ((int)($row['c'] ?? 0)) > 0;
}
public static function ensureColumn(string $table, string $column, string $alterSql): void
{
global $db;
if (self::tableHasColumn($table, $column)) {
return;
}
$db->query($alterSql);
}
}