ruleDefModel = new RuleDefModel(); $this->ruleActionModel = new RuleActionModel(); } public function index($ruleID = null) { try { if (!$ruleID || !is_numeric($ruleID)) { return $this->failValidationErrors('RuleID is required'); } $rule = $this->ruleDefModel->where('EndDate', null)->find((int) $ruleID); if (!$rule) { return $this->respond([ 'status' => 'failed', 'message' => 'Rule not found', 'data' => [], ], 404); } $rows = $this->ruleActionModel ->where('RuleID', (int) $ruleID) ->where('EndDate', null) ->orderBy('Seq', 'ASC') ->orderBy('RuleActionID', 'ASC') ->findAll(); return $this->respond([ 'status' => 'success', 'message' => 'fetch success', 'data' => $rows, ], 200); } catch (\Throwable $e) { log_message('error', 'RuleActionController::index error: ' . $e->getMessage()); return $this->failServerError('Something went wrong: ' . $e->getMessage()); } } public function create($ruleID = null) { $input = $this->request->getJSON(true) ?? []; if (!$ruleID || !is_numeric($ruleID)) { $ruleID = $input['RuleID'] ?? null; } if (!$ruleID || !is_numeric($ruleID)) { return $this->failValidationErrors('RuleID is required'); } $rule = $this->ruleDefModel->where('EndDate', null)->find((int) $ruleID); if (!$rule) { return $this->respond([ 'status' => 'failed', 'message' => 'Rule not found', 'data' => [], ], 404); } $validation = service('validation'); $validation->setRules([ 'Seq' => 'permit_empty|integer', 'ActionType' => 'required|max_length[50]', ]); if (!$validation->run($input)) { return $this->failValidationErrors($validation->getErrors()); } // Light validation for SET_RESULT params $actionType = strtoupper((string) $input['ActionType']); $params = $input['ActionParams'] ?? null; if ($actionType === 'SET_RESULT') { $decoded = is_array($params) ? $params : (is_string($params) ? json_decode($params, true) : null); if (!is_array($decoded)) { return $this->failValidationErrors(['ActionParams' => 'ActionParams must be JSON object for SET_RESULT']); } if (empty($decoded['testSiteID']) && empty($decoded['testSiteCode'])) { return $this->failValidationErrors(['ActionParams' => 'SET_RESULT requires testSiteID or testSiteCode']); } if (!array_key_exists('value', $decoded) && !array_key_exists('valueExpr', $decoded)) { return $this->failValidationErrors(['ActionParams' => 'SET_RESULT requires value or valueExpr']); } if (!empty($decoded['testSiteID']) && is_numeric($decoded['testSiteID'])) { $testDef = new TestDefSiteModel(); $exists = $testDef->where('EndDate', null)->find((int) $decoded['testSiteID']); if (!$exists) { return $this->failValidationErrors(['ActionParams' => 'testSiteID not found']); } } } try { if (is_array($params)) { $params = json_encode($params); } $id = $this->ruleActionModel->insert([ 'RuleID' => (int) $ruleID, 'Seq' => $input['Seq'] ?? 1, 'ActionType' => $input['ActionType'], 'ActionParams' => is_string($params) ? $params : null, ], true); return $this->respondCreated([ 'status' => 'success', 'message' => 'Action created successfully', 'data' => ['RuleActionID' => $id], ], 201); } catch (\Throwable $e) { log_message('error', 'RuleActionController::create error: ' . $e->getMessage()); return $this->failServerError('Something went wrong: ' . $e->getMessage()); } } public function update($ruleID = null, $actionID = null) { $input = $this->request->getJSON(true) ?? []; if (!$ruleID || !is_numeric($ruleID)) { $ruleID = $input['RuleID'] ?? null; } if (!$actionID || !is_numeric($actionID)) { $actionID = $input['RuleActionID'] ?? null; } if (!$ruleID || !is_numeric($ruleID) || !$actionID || !is_numeric($actionID)) { return $this->failValidationErrors('RuleID and RuleActionID are required'); } $rule = $this->ruleDefModel->where('EndDate', null)->find((int) $ruleID); if (!$rule) { return $this->respond([ 'status' => 'failed', 'message' => 'Rule not found', 'data' => [], ], 404); } $existing = $this->ruleActionModel->where('EndDate', null)->find((int) $actionID); if (!$existing || (int) ($existing['RuleID'] ?? 0) !== (int) $ruleID) { return $this->respond([ 'status' => 'failed', 'message' => 'Action not found', 'data' => [], ], 404); } $validation = service('validation'); $validation->setRules([ 'Seq' => 'permit_empty|integer', 'ActionType' => 'permit_empty|max_length[50]', ]); if (!$validation->run($input)) { return $this->failValidationErrors($validation->getErrors()); } try { $updateData = []; foreach (['Seq', 'ActionType', 'ActionParams'] as $field) { if (array_key_exists($field, $input)) { $updateData[$field] = $input[$field]; } } if (isset($updateData['ActionParams']) && is_array($updateData['ActionParams'])) { $updateData['ActionParams'] = json_encode($updateData['ActionParams']); } if (!empty($updateData)) { $this->ruleActionModel->update((int) $actionID, $updateData); } return $this->respond([ 'status' => 'success', 'message' => 'Action updated successfully', 'data' => ['RuleActionID' => (int) $actionID], ], 200); } catch (\Throwable $e) { log_message('error', 'RuleActionController::update error: ' . $e->getMessage()); return $this->failServerError('Something went wrong: ' . $e->getMessage()); } } public function delete($ruleID = null, $actionID = null) { try { if (!$ruleID || !is_numeric($ruleID) || !$actionID || !is_numeric($actionID)) { return $this->failValidationErrors('RuleID and RuleActionID are required'); } $existing = $this->ruleActionModel->where('EndDate', null)->find((int) $actionID); if (!$existing || (int) ($existing['RuleID'] ?? 0) !== (int) $ruleID) { return $this->respond([ 'status' => 'failed', 'message' => 'Action not found', 'data' => [], ], 404); } $this->ruleActionModel->delete((int) $actionID); return $this->respondDeleted([ 'status' => 'success', 'message' => 'Action deleted successfully', 'data' => ['RuleActionID' => (int) $actionID], ]); } catch (\Throwable $e) { log_message('error', 'RuleActionController::delete error: ' . $e->getMessage()); return $this->failServerError('Something went wrong: ' . $e->getMessage()); } } }