exec("CREATE TABLE IF NOT EXISTS maintenance_records ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, store_id VARCHAR(32) NOT NULL, store_name VARCHAR(160) NOT NULL, oven_id VARCHAR(32) NOT NULL, oven_name VARCHAR(160) NOT NULL, technician VARCHAR(120) NOT NULL, service_type VARCHAR(60) NOT NULL, parts_json JSON NULL, notes TEXT NULL, status VARCHAR(40) NOT NULL DEFAULT 'Concluída', created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"); } function seed_data(): array { return [ 'stores' => [ ['id' => 'lj-001', 'name' => 'Loja Centro', 'city' => 'São Paulo'], ['id' => 'lj-002', 'name' => 'Loja Norte', 'city' => 'Guarulhos'], ['id' => 'lj-003', 'name' => 'Loja Sul', 'city' => 'Santo André'], ], 'ovens' => [ ['id' => 'fn-101', 'store_id' => 'lj-001', 'name' => 'Forno Turbo 01', 'model' => 'FT-900'], ['id' => 'fn-102', 'store_id' => 'lj-001', 'name' => 'Forno Lastro 02', 'model' => 'FL-450'], ['id' => 'fn-201', 'store_id' => 'lj-002', 'name' => 'Forno Turbo 03', 'model' => 'FT-900'], ['id' => 'fn-301', 'store_id' => 'lj-003', 'name' => 'Forno Compacto 01', 'model' => 'FC-220'], ], 'parts' => [ ['id' => 'pc-01', 'name' => 'Resistência', 'sku' => 'RES-220'], ['id' => 'pc-02', 'name' => 'Termostato', 'sku' => 'TER-110'], ['id' => 'pc-03', 'name' => 'Sensor de temperatura', 'sku' => 'SEN-300'], ['id' => 'pc-04', 'name' => 'Correia do motor', 'sku' => 'COR-040'], ], ]; } function maintenance_rows(): array { $stmt = db()->query('SELECT * FROM maintenance_records ORDER BY created_at DESC, id DESC LIMIT 50'); $rows = $stmt->fetchAll(); foreach ($rows as &$row) { $row['parts'] = $row['parts_json'] ? json_decode((string)$row['parts_json'], true) : []; unset($row['parts_json']); } return $rows; } try { ensure_schema(); $method = $_SERVER['REQUEST_METHOD'] ?? 'GET'; $action = $_GET['action'] ?? 'bootstrap'; $seed = seed_data(); if ($method === 'GET' && $action === 'bootstrap') { respond($seed + ['maintenance' => maintenance_rows()]); } if ($method === 'GET' && $action === 'maintenance') { respond(['maintenance' => maintenance_rows()]); } if ($method === 'POST' && $action === 'maintenance') { $input = json_decode(file_get_contents('php://input') ?: '{}', true); if (!is_array($input)) { respond(['success' => false, 'error' => 'Payload inválido.'], 400); } $storeId = trim((string)($input['store_id'] ?? '')); $ovenId = trim((string)($input['oven_id'] ?? '')); $technician = trim((string)($input['technician'] ?? '')); $serviceType = trim((string)($input['service_type'] ?? '')); $notes = trim((string)($input['notes'] ?? '')); $parts = is_array($input['parts'] ?? null) ? array_values($input['parts']) : []; $store = null; foreach ($seed['stores'] as $candidate) { if ($candidate['id'] === $storeId) { $store = $candidate; break; } } $oven = null; foreach ($seed['ovens'] as $candidate) { if ($candidate['id'] === $ovenId && $candidate['store_id'] === $storeId) { $oven = $candidate; break; } } if (!$store || !$oven || $technician === '' || $serviceType === '' || count($parts) < 1) { respond(['success' => false, 'error' => 'Preencha loja, forno, técnico, tipo e pelo menos uma peça.'], 422); } $allowedParts = array_column($seed['parts'], null, 'id'); $cleanParts = []; foreach ($parts as $partId) { $partId = (string)$partId; if (isset($allowedParts[$partId])) { $cleanParts[] = $allowedParts[$partId]; } } if (!$cleanParts) { respond(['success' => false, 'error' => 'Selecione uma peça válida.'], 422); } $stmt = db()->prepare('INSERT INTO maintenance_records (store_id, store_name, oven_id, oven_name, technician, service_type, parts_json, notes, status) VALUES (:store_id, :store_name, :oven_id, :oven_name, :technician, :service_type, :parts_json, :notes, :status)'); $stmt->execute([ ':store_id' => $store['id'], ':store_name' => $store['name'], ':oven_id' => $oven['id'], ':oven_name' => $oven['name'], ':technician' => substr($technician, 0, 120), ':service_type' => substr($serviceType, 0, 60), ':parts_json' => json_encode($cleanParts, JSON_UNESCAPED_UNICODE), ':notes' => substr($notes, 0, 500), ':status' => 'Concluída', ]); respond(['success' => true, 'id' => (int)db()->lastInsertId(), 'maintenance' => maintenance_rows()], 201); } respond(['success' => false, 'error' => 'Rota não encontrada.'], 404); } catch (Throwable $e) { error_log('mock api error: ' . $e->getMessage()); respond(['success' => false, 'error' => 'Erro interno ao processar a API mock.'], 500); }