<?php

declare(strict_types=1);

// B/C isolated fixture. Default mode is metadata/COUNT only, with no business HTTP or DML.
$stage = 'bootstrap';
set_exception_handler(static function (Throwable $error) use (&$stage): void {
    $info = $error instanceof PDOException ? $error->errorInfo : [];
    fwrite(STDERR, 'N3_WEIGHT_BC_FAILED ' . get_class($error)
        . ' stage=' . $stage . ' sqlstate='
        . (string)($info[0] ?? $error->getCode()) . PHP_EOL);
    exit(2);
});
$variant = (string)getenv('POC_VARIANT');
if (!in_array($variant, ['B', 'C'], true)) {
    throw new RuntimeException('Only isolated B/C allowed');
}
$isDm = $variant === 'C';
$root = $isDm ? '/tmp/zhct-ai-http-20260929.3XDj3w'
    : '/tmp/zhct-http-ai-macos.x2CCZX';
$base = $isDm ? 'http://127.0.0.1:18102' : 'http://127.0.0.1:18101';
$pid = $isDm ? 53772 : 13127;
$port = $isDm ? 18102 : 18101;
$expectedServiceSha = 'db3aa5841eaa647eb1c1ec423325edd98910827819ea7e4d1e892d5d324e2d00';
$expectedModelSha = 'a088d81d1fdebb902d5c52de882f0820efe8021ba70b43c2e436a945b6d93958';
$servicePath = $root . '/app/store/service/weight/StaffWeight.php';
$modelPath = $root . '/app/store/model/weight/StaffWeight.php';
$actualAutoloadRoot = $isDm
    ? '/tmp/zhct-dm-poc-20260928.fcpiiN/ai_api'
    : '/Users/wiscourper/Documents/workspace/local/dm8-full-acceptance.fF5yTy/ai_api';
$sourceReady = is_file($servicePath) && is_file($modelPath)
    && hash_equals($expectedServiceSha, (string)hash_file('sha256', $servicePath))
    && hash_equals($expectedServiceSha, (string)hash_file('sha256',
        $actualAutoloadRoot . '/app/store/service/weight/StaffWeight.php'))
    && hash_equals($expectedModelSha, (string)hash_file('sha256', $modelPath))
    && hash_equals($expectedModelSha, (string)hash_file('sha256',
        $actualAutoloadRoot . '/app/store/model/weight/StaffWeight.php'));
$env = [];
if ($isDm) {
    foreach (explode("\0", (string)@file_get_contents('/proc/53772/environ')) as $item) {
        $parts = explode('=', $item, 2);
        if (count($parts) === 2) $env[$parts[0]] = $parts[1];
    }
    if (($env['POC_TARGET_ROOT'] ?? '') !== $root
        || ($env['POC_BASE_URL'] ?? '') !== $base
        || ($env['POC_DIALECT'] ?? '') !== 'dm'
        || ($env['POC_AI_HOST'] ?? '') !== '127.0.0.1'
        || ($env['POC_AI_PORT'] ?? '') !== '5238'
        || ($env['POC_AI_SCHEMA'] ?? '') !== 'AIZHCT_APP'
        || ($env['POC_AI_USER'] ?? '') !== 'AIZHCT_APP') {
        throw new RuntimeException('Unapproved C AI boundary');
    }
    $cmdline = str_replace("\0", ' ', (string)@file_get_contents('/proc/53772/cmdline'));
    if (strpos($cmdline, '-S 127.0.0.1:18102') === false
        || strpos($cmdline, $root . '/public') === false) {
        throw new RuntimeException('C HTTP process identity mismatch');
    }
    $db = new PDO('dm:host=127.0.0.1;port=5238;schema=AIZHCT_APP',
        $env['POC_AI_USER'], $env['POC_AI_PASSWORD'],
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_CASE => PDO::CASE_LOWER]);
    if ((string)$db->query("SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') FROM DUAL")
        ->fetchColumn() !== 'AIZHCT_APP') {
        throw new RuntimeException('C actual schema mismatch');
    }
} else {
    $localPath = '/Users/wiscourper/Documents/workspace/zhct/zhctproject/ai_api/.env.local';
    if (realpath((string)getenv('POC_MYSQL_LOCAL_ENV')) !== realpath($localPath)) {
        throw new RuntimeException('Only code local DB allowed');
    }
    $local = parse_ini_file($localPath, true, INI_SCANNER_RAW);
    if (!is_array($local) || !isset($local['DATABASE'], $local['DATABASE_ZHCT'])) {
        throw new RuntimeException('Code local two-business-DB config absent');
    }
    if (trim((string)shell_exec('lsof -nP -iTCP:18101 -sTCP:LISTEN -t 2>/dev/null'))
        !== (string)$pid) {
        throw new RuntimeException('B listener changed');
    }
    $process = (string)shell_exec('ps eww -p ' . $pid . ' -o command=');
    if (strpos($process, $root . '/public') === false
        || strpos($process, 'php -S 127.0.0.1:18101') === false) {
        throw new RuntimeException('B process identity mismatch');
    }
    $expected = ['POC_TARGET_ROOT' => $root, 'POC_BASE_URL' => $base,
        'POC_DIALECT' => 'mysql'];
    foreach (['DATABASE' => 'POC_AI_', 'DATABASE_ZHCT' => 'POC_'] as $section => $prefix) {
        foreach (['HOSTNAME' => 'HOST', 'HOSTPORT' => 'PORT',
            'DATABASE' => 'SCHEMA', 'USERNAME' => 'USER',
            'PASSWORD' => 'PASSWORD'] as $from => $to) {
            $expected[$prefix . $to] = (string)$local[$section][$from];
        }
    }
    foreach ($expected as $key => $value) {
        $pattern = '/(?:^|\s)' . preg_quote($key, '/') . '=([^\s]*)/';
        if (!preg_match($pattern, $process, $match) || $match[1] !== $value) {
            throw new RuntimeException('B HTTP DB differs from code local');
        }
        $env[$key] = $match[1];
    }
    if (preg_match('/(?:^|\s)PHP_CLI_SERVER_WORKERS=([^\s]*)/', $process, $workers)) {
        $env['PHP_CLI_SERVER_WORKERS'] = $workers[1];
    }
    $x = $local['DATABASE'];
    $db = new PDO('mysql:host=' . $x['HOSTNAME'] . ';port=' . ($x['HOSTPORT'] ?? 3306)
        . ';dbname=' . $x['DATABASE'] . ';charset=utf8', $x['USERNAME'],
        $x['PASSWORD'], [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_CASE => PDO::CASE_LOWER, PDO::ATTR_TIMEOUT => 5]);
    if ((string)$db->query('SELECT DATABASE()')->fetchColumn() !== (string)$x['DATABASE']) {
        throw new RuntimeException('B effective AI schema mismatch');
    }
}
$stage = 'http_boundary';
$boundaryRaw = @file_get_contents($base . '/__poc_boundary', false,
    stream_context_create(['http' => ['timeout' => 5]]));
$boundary = is_string($boundaryRaw) ? json_decode($boundaryRaw, true) : null;
unset($boundaryRaw);
if (!is_array($boundary) || empty($boundary['external_stubs'])) {
    throw new RuntimeException('External integration isolation absent');
}
$table = static function (string $short) use ($isDm): string {
    return $isDm ? 'YOSHOP_' . strtoupper($short) : 'yoshop_' . $short;
};
$count = static function (string $sql, array $args = []) use ($db): int {
    $stmt = $db->prepare($sql);
    $stmt->execute($args);
    return (int)$stmt->fetchColumn();
};
$rows = static function (string $sql, array $args = []) use ($db): array {
    $stmt = $db->prepare($sql);
    $stmt->execute($args);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
};
$needed = [
    'store' => ['STORE_ID'],
    'store_user' => ['STORE_USER_ID','USER_NAME','PASSWORD','REAL_NAME','IS_SUPER',
        'STORE_ID','IS_DELETE','CREATE_BY','CREATE_TIME','UPDATE_TIME'],
    'store_user_role' => ['ID','STORE_USER_ID'],
    'staff' => ['ID','NAME','STORE_ID','HEIGHT','WEIGHT','GENDER','BIRTHDAY',
        'PHONE','IS_DELETE'],
    'staff_weight' => ['ID','STAFF_ID','SET_DATE','HEIGHT','WEIGHT',
        'BODY_FAT_RATE','BMI','ENERGY_VALUE','WEIGHT_STATUS','STORE_ID',
        'IS_DELETE','CREATE_BY'],
    'meal' => ['ID','STAFF_ID'],
    'meal_infos' => ['ID','STAFF_ID'],
    'meal_recommend' => ['ID','STAFF_ID'],
];
$tableOk = [];
$triggerCounts = [];
foreach ($needed as $short => $columns) {
    $stage = 'metadata_' . $short;
    $name = $table($short);
    if ($isDm) {
        $exists = $count('SELECT COUNT(*) FROM USER_TABLES WHERE TABLE_NAME=?', [$name]) === 1;
        $metadataSql = 'SELECT COLUMN_NAME FROM USER_TAB_COLUMNS WHERE TABLE_NAME=?';
        $triggerSql = 'SELECT COUNT(*) FROM USER_TRIGGERS'
            . " WHERE TABLE_NAME=? AND STATUS='ENABLED'";
    } else {
        $exists = $count('SELECT COUNT(*) FROM information_schema.TABLES'
            . ' WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=?', [$name]) === 1;
        $metadataSql = 'SELECT COLUMN_NAME FROM information_schema.COLUMNS'
            . ' WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=?';
        $triggerSql = 'SELECT COUNT(*) FROM information_schema.TRIGGERS'
            . ' WHERE TRIGGER_SCHEMA=DATABASE() AND EVENT_OBJECT_TABLE=?';
    }
    $columnOk = false;
    $triggerCounts[$short] = null;
    if ($exists) {
        $stmt = $db->prepare($metadataSql);
        $stmt->execute([$name]);
        $actual = array_map('strtoupper', $stmt->fetchAll(PDO::FETCH_COLUMN));
        $columnOk = count(array_diff($columns, $actual)) === 0;
        $triggerCounts[$short] = $count($triggerSql, [$name]);
    }
    $tableOk[$short] = $exists && $columnOk;
}
$marker = 'CDXPARNUW' . strtoupper(bin2hex(random_bytes(4)));
$markerZero = $tableOk['store_user'] && $tableOk['staff'] && $tableOk['staff_weight']
    && $count('SELECT COUNT(*) FROM ' . $table('store_user') . ' WHERE USER_NAME=?', [$marker]) === 0
    && $count('SELECT COUNT(*) FROM ' . $table('staff') . ' WHERE NAME=?', [$marker]) === 0
    && $count('SELECT COUNT(*) FROM ' . $table('staff_weight') . ' WHERE CREATE_BY=?', [$marker]) === 0;
$storeOne = $tableOk['store']
    && $count('SELECT COUNT(*) FROM ' . $table('store') . ' WHERE STORE_ID=?', [10001]) === 1;
$singleWorker = !isset($env['PHP_CLI_SERVER_WORKERS'])
    || (int)$env['PHP_CLI_SERVER_WORKERS'] <= 1;
$pass = $sourceReady && $markerZero && $storeOne
    && !in_array(false, $tableOk, true)
    && array_sum(array_map('intval', $triggerCounts)) === 0
    && $singleWorker;
$stage = 'preflight_complete';
if (!$pass || (string)getenv('POC_APPROVED_WEIGHT_BC_WRITE') !== '1') {
    echo json_encode(['suite' => 'ai-store-n3-weight-' . $variant,
        'mode' => 'read-only-preflight', 'source_ready' => $sourceReady,
        'tables_and_columns' => $tableOk, 'enabled_trigger_counts' => $triggerCounts,
        'new_marker_zero' => $markerZero, 'store_unique' => $storeOne,
        'external_stubs' => true, 'single_worker' => $singleWorker],
        JSON_UNESCAPED_SLASHES) . PHP_EOL;
    exit($pass ? 0 : 1);
}

foreach ($env as $key => $value) {
    if (strpos($key, 'POC_') === 0) putenv($key . '=' . $value);
}
define('TP_ENV', 'poc');
define('BUSINESS', 'aizhct');
define('ENTERPRISE_NO', '10001');
require $root . '/vendor/autoload.php';
(new \think\App($root))->setEnvName('poc')->initialize();
$assert = static function (bool $ok, string $message): void {
    if (!$ok) throw new RuntimeException($message);
};
$token = $marker . 'TOKEN' . strtoupper(bin2hex(random_bytes(8)));
$dates = ['2026-09-28', '2026-09-29', '2026-09-30'];
$values = [
    '2026-09-28' => ['weight' => '60.00', 'body_fat_rate' => '20.00',
        'bmi' => '20.00', 'energy_value' => '123.40'],
    '2026-09-29' => ['weight' => '60.25', 'body_fat_rate' => '20.25',
        'bmi' => '20.25', 'energy_value' => '123.65'],
    '2026-09-30' => ['weight' => '60.50', 'body_fat_rate' => '20.50',
        'bmi' => '20.50', 'energy_value' => '123.90'],
];
$operatorId = 0;
$staffId = 0;
$weightIds = [];
$unsettled = false;
$results = [];
$cleanup = [];
$failure = '';
$request = static function (string $route, array $params) use ($base, $token): array {
    $context = stream_context_create(['http' => [
        'method' => 'POST',
        'header' => "Content-Type: application/json;charset=utf-8\r\n"
            . 'Access-Token: ' . $token . "\r\nConnection: close\r\n",
        'content' => json_encode($params, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
        'timeout' => 60, 'ignore_errors' => true,
    ]]);
    $started = microtime(true);
    $raw = @file_get_contents($base . '/index.php?s=/store/' . $route, false, $context);
    preg_match('/HTTP\/\S+\s+(\d+)/', $http_response_header[0] ?? '', $match);
    $json = is_string($raw) ? json_decode($raw, true) : null;
    unset($raw);
    return ['http' => (int)($match[1] ?? 0), 'complete' => is_array($json),
        'status' => is_array($json) ? (int)($json['status'] ?? -1) : -1,
        'data' => is_array($json) ? ($json['data'] ?? null) : null,
        'elapsed_ms' => (int)round((microtime(true) - $started) * 1000)];
};
$dateFormat = static function ($value): string {
    if (!is_string($value)) return gettype($value);
    if (preg_match('/^\d{4}-\d{2}-\d{2}$/D', $value)) return 'date_only';
    if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/D', $value))
        return 'datetime_seconds';
    if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+$/D', $value))
        return 'datetime_fractional';
    return 'other_string';
};
try {
    $stage = 'synthetic_operator_insert';
    $db->prepare('INSERT INTO ' . $table('store_user')
        . ' (USER_NAME,PASSWORD,REAL_NAME,IS_SUPER,IS_DELETE,STORE_ID,CREATE_BY,CREATE_TIME,UPDATE_TIME)'
        . ' VALUES (?,?,?,1,0,10001,?,?,?)')
        ->execute([$marker, '!disabled-' . strtoupper(bin2hex(random_bytes(12))),
            $marker, $marker, time(), time()]);
    $owned = $rows('SELECT STORE_USER_ID FROM ' . $table('store_user')
        . ' WHERE USER_NAME=?', [$marker]);
    $assert(count($owned) === 1, 'Synthetic operator ambiguous');
    $operatorId = (int)$owned[0]['store_user_id'];
    $assert($operatorId > 0, 'Synthetic operator ID invalid');
    $payload = ['user' => ['store_user_id' => $operatorId, 'store_id' => 10001,
        'user_name' => $marker, 'real_name' => $marker, 'is_super' => 1],
        'store_id' => 10001, 'is_login' => true];

    $stage = 'synthetic_staff_insert';
    $db->prepare('INSERT INTO ' . $table('staff')
        . ' (NAME,STORE_ID,HEIGHT,WEIGHT,GENDER,BIRTHDAY,PHONE,IS_DELETE)'
        . " VALUES (?,10001,170,60,1,'1990-01-01','',0)")
        ->execute([$marker]);
    $owned = $rows('SELECT ID FROM ' . $table('staff') . ' WHERE NAME=?', [$marker]);
    $assert(count($owned) === 1, 'Synthetic staff ambiguous');
    $staffId = (int)$owned[0]['id'];
    $assert($staffId > 0, 'Synthetic staff ID invalid');
    $assert($count('SELECT COUNT(*) FROM ' . $table('meal_recommend')
        . ' WHERE STAFF_ID=?', [$staffId]) === 0, 'Synthetic recommendation preexists');

    $stage = 'synthetic_weight_insert';
    foreach ($dates as $day) {
        $v = $values[$day];
        $db->prepare('INSERT INTO ' . $table('staff_weight')
            . ' (STAFF_ID,HEIGHT,WEIGHT,BODY_FAT_RATE,BMI,ENERGY_VALUE,'
            . ' WEIGHT_STATUS,SET_DATE,STORE_ID,IS_DELETE,CREATE_BY)'
            . ' VALUES (?,170.00,?,?,?,?,0,?,10001,0,?)')
            ->execute([$staffId, $v['weight'], $v['body_fat_rate'],
                $v['bmi'], $v['energy_value'], $day, $marker]);
        $owned = $rows('SELECT ID FROM ' . $table('staff_weight')
            . ' WHERE STAFF_ID=? AND SET_DATE=? AND CREATE_BY=?',
            [$staffId, $day, $marker]);
        $assert(count($owned) === 1, 'Synthetic weight day ambiguous');
        $weightIds[$day] = (int)$owned[0]['id'];
    }
    $assert(count($weightIds) === 3
        && $count('SELECT COUNT(*) FROM ' . $table('staff_weight')
            . ' WHERE STAFF_ID=? AND CREATE_BY=?', [$staffId, $marker]) === 3,
        'Three original-table weights incomplete');
    $results['fixture_three_dates'] = true;

    foreach (['weight.StaffWeight/list' => true,
        'weight.StaffWeight/echartsList' => false] as $route => $paginated) {
        $stage = 'http_' . $route;
        $assert(\think\facade\Cache::set($token, $payload, 60)
            && \think\facade\Cache::has($token), 'Synthetic token refresh failed');
        $params = ['staff_id' => $staffId, 'start_date' => $dates[0],
            'end_date' => $dates[2]];
        if ($paginated) $params += ['page_size' => 10, 'page' => 1];
        $response = $request($route, $params);
        if (!$response['complete']) {
            $unsettled = true;
            throw new RuntimeException('Weight HTTP outcome unsettled');
        }
        $assert($response['http'] === 200 && $response['status'] === 200
            && $response['elapsed_ms'] <= 60000, 'Weight HTTP business status failed');
        $data = $response['data'];
        $list = is_array($data) ? ($data['list'] ?? null) : null;
        $records = $paginated && is_array($list) ? ($list['data'] ?? null) : $list;
        $assert(is_array($records) && count($records) === 3,
            'Cross-day BETWEEN did not return all three records');
        $seen = [];
        $idTypes = [];
        $dateFormats = [];
        $fields = $paginated
            ? ['height', 'weight', 'body_fat_rate', 'bmi', 'energy_value']
            : ['height', 'weight', 'body_fat_rate'];
        $allFixedTwoStrings = true;
        foreach ($records as $row) {
            $assert(is_array($row), 'Weight response row not object');
            $idTypes[gettype($row['id'] ?? null)] = true;
            $dateFormats[$dateFormat($row['set_date'] ?? null)] = true;
            $day = is_string($row['set_date'] ?? null)
                ? substr($row['set_date'], 0, 10) : '';
            $assert(isset($values[$day]) && !isset($seen[$day]),
                'Weight response date missing/duplicate');
            $seen[$day] = true;
            foreach ($fields as $field) {
                $v = $row[$field] ?? null;
                if (!is_string($v)
                    || preg_match('/^-?[0-9]+\.[0-9]{2}$/D', $v) !== 1
                    || $v !== ($field === 'height' ? '170.00' : $values[$day][$field])) {
                    $allFixedTwoStrings = false;
                }
            }
        }
        $assert(count($seen) === 3 && $allFixedTwoStrings,
            'Weight decimal response type/scale/value mismatch');
        $results[$route] = [
            'http_business_200' => true,
            'three_dates_inclusive' => true,
            'decimal_field_count_per_row' => count($fields),
            'decimal_fields_fixed_two_strings' => $allFixedTwoStrings,
            'id_types' => array_keys($idTypes),
            'set_date_format_classes' => array_keys($dateFormats),
        ];
    }
} catch (Throwable $error) {
    $failure = get_class($error) . ':' . hash('sha256', $error->getMessage());
} finally {
    try {
        $cacheAbsent = false;
        try {
            \think\facade\Cache::delete($token);
            $cacheAbsent = !\think\facade\Cache::has($token);
        } catch (Throwable $cacheError) {
            $cleanup['cache_error_class'] = get_class($cacheError);
        }
        $cleanup['cache_absent'] = $cacheAbsent;
        $barrierComplete = true;
        if ($unsettled) {
            $raw = @file_get_contents($base . '/__poc_boundary', false,
                stream_context_create(['http' => ['method' => 'GET',
                    'header' => "Connection: close\r\n", 'timeout' => 30,
                    'ignore_errors' => true]]));
            $barrier = is_string($raw) ? json_decode($raw, true) : null;
            unset($raw);
            preg_match('/HTTP\/\S+\s+(\d+)/', $http_response_header[0] ?? '', $httpMatch);
            $cmdline = $isDm
                ? str_replace("\0", ' ', (string)@file_get_contents('/proc/53772/cmdline'))
                : (string)shell_exec('ps eww -p 13127 -o command=');
            $oneWorker = !isset($env['PHP_CLI_SERVER_WORKERS'])
                || (int)$env['PHP_CLI_SERVER_WORKERS'] <= 1;
            $barrierComplete = is_array($barrier) && !empty($barrier['external_stubs'])
                && (int)($httpMatch[1] ?? 0) === 200
                && strpos($cmdline, '-S 127.0.0.1:' . $port) !== false
                && $oneWorker;
            $cleanup['single_worker_barrier_complete'] = $barrierComplete;
        }
        if (!$cacheAbsent || !$barrierComplete) {
            $cleanup['deferred_actor_and_business_cleanup'] = true;
        } else {
            if ($operatorId <= 0) {
                $owned = $rows('SELECT STORE_USER_ID FROM ' . $table('store_user')
                    . ' WHERE USER_NAME=?', [$marker]);
                $assert(count($owned) <= 1, 'Synthetic operator ambiguous in cleanup');
                if ($owned) $operatorId = (int)$owned[0]['store_user_id'];
            }
            if ($staffId <= 0) {
                $owned = $rows('SELECT ID FROM ' . $table('staff')
                    . ' WHERE NAME=?', [$marker]);
                $assert(count($owned) <= 1, 'Synthetic staff ambiguous in cleanup');
                if ($owned) $staffId = (int)$owned[0]['id'];
            }
            if ($staffId > 0) {
                $owned = $rows('SELECT ID,SET_DATE,CREATE_BY FROM ' . $table('staff_weight')
                    . ' WHERE STAFF_ID=?', [$staffId]);
                $assert(count($owned) <= 3, 'Unexpected weight children; cleanup refused');
                $seenDates = [];
                foreach ($owned as $row) {
                    $day = substr((string)$row['set_date'], 0, 10);
                    $assert(in_array($day, $dates, true)
                        && (string)$row['create_by'] === $marker
                        && !isset($seenDates[$day])
                        && (!isset($weightIds[$day])
                            || (int)$row['id'] === $weightIds[$day]),
                        'Unexpected synthetic weight row; cleanup refused');
                    $seenDates[$day] = true;
                }
                $assert($count('SELECT COUNT(*) FROM ' . $table('meal')
                    . ' WHERE STAFF_ID=?', [$staffId]) === 0
                    && $count('SELECT COUNT(*) FROM ' . $table('meal_infos')
                        . ' WHERE STAFF_ID=?', [$staffId]) === 0
                    && $count('SELECT COUNT(*) FROM ' . $table('meal_recommend')
                        . ' WHERE STAFF_ID=?', [$staffId]) === 0,
                    'Unexpected meal/recommend children; cleanup refused');
                foreach ($owned as $row) {
                    $db->prepare('DELETE FROM ' . $table('staff_weight')
                        . ' WHERE ID=? AND STAFF_ID=? AND CREATE_BY=?')
                        ->execute([(int)$row['id'], $staffId, $marker]);
                }
                $db->prepare('DELETE FROM ' . $table('staff')
                    . ' WHERE ID=? AND NAME=?')->execute([$staffId, $marker]);
            }
            if ($operatorId > 0) {
                $assert($count('SELECT COUNT(*) FROM ' . $table('store_user_role')
                    . ' WHERE STORE_USER_ID=?', [$operatorId]) === 0,
                    'Unexpected role relation; cleanup refused');
                $db->prepare('DELETE FROM ' . $table('store_user')
                    . ' WHERE STORE_USER_ID=? AND USER_NAME=?')
                    ->execute([$operatorId, $marker]);
            }
            $cleanup = array_merge($cleanup, [
                'operator_zero' => $count('SELECT COUNT(*) FROM ' . $table('store_user')
                    . ' WHERE USER_NAME=?', [$marker]) === 0,
                'staff_zero' => $count('SELECT COUNT(*) FROM ' . $table('staff')
                    . ' WHERE NAME=?', [$marker]) === 0,
                'weight_marker_zero' => $count('SELECT COUNT(*) FROM ' . $table('staff_weight')
                    . ' WHERE CREATE_BY=?', [$marker]) === 0,
                'meal_children_zero' => $staffId <= 0 || $count('SELECT COUNT(*) FROM '
                    . $table('meal') . ' WHERE STAFF_ID=?', [$staffId]) === 0,
                'recommend_zero' => $staffId <= 0 || $count('SELECT COUNT(*) FROM '
                    . $table('meal_recommend') . ' WHERE STAFF_ID=?', [$staffId]) === 0,
            ]);
        }
    } catch (Throwable $error) {
        $cleanup['error_class'] = get_class($error);
        $cleanup['error_sha256'] = hash('sha256', $error->getMessage());
    }
}
$clean = !in_array(false, $cleanup, true)
    && !isset($cleanup['error_class']) && !isset($cleanup['cache_error_class'])
    && empty($cleanup['deferred_actor_and_business_cleanup']);
echo json_encode(['suite' => 'ai-store-n3-weight-' . $variant,
    'marker' => $marker, 'results' => $results, 'failure' => $failure,
    'cleanup' => $cleanup], JSON_UNESCAPED_SLASHES) . PHP_EOL;
exit($failure === '' && $clean ? 0 : 1);
