import pool from '../config/database'; import { findAllRules, findRuleByKey, upsertRule, RuleRow } from '../dao/ConfigDAO'; export interface RuleDTO { ruleKey: string; ruleValue: unknown; description?: string; effectiveCycle?: string; } export interface RuleResponse { ruleId: number; ruleKey: string; ruleValue: unknown; description: string | null; effectiveCycle: string | null; updatedBy: number | null; updatedAt: Date; } function toResponse(row: RuleRow): RuleResponse { let parsed: unknown; try { parsed = JSON.parse(row.rule_value); } catch { parsed = row.rule_value; } return { ruleId: row.rule_id, ruleKey: row.rule_key, ruleValue: parsed, description: row.description, effectiveCycle: row.effective_cycle, updatedBy: row.updated_by, updatedAt: row.updated_at, }; } /** Get all current rules */ export async function getAllRules(): Promise { const rows = await findAllRules(); return rows.map(toResponse); } /** Get a single rule by key */ export async function getRuleByKey(ruleKey: string): Promise { const row = await findRuleByKey(ruleKey); return row ? toResponse(row) : null; } /** * Update (or create) a rule and record the change in operation_log. * Requirements: 8.5, 8.6 */ export async function updateRule(dto: RuleDTO, operatorId: number): Promise { // Persist the rule await upsertRule({ ruleKey: dto.ruleKey, ruleValue: dto.ruleValue, description: dto.description, effectiveCycle: dto.effectiveCycle, updatedBy: operatorId, }); // Record operation log so changes are traceable (Requirement 8.6) await pool.query( `INSERT INTO operation_log (user_id, operation_type, target_type, operation_detail) VALUES (?, 'update_rule', 'config', ?)`, [ operatorId, JSON.stringify({ ruleKey: dto.ruleKey, ruleValue: dto.ruleValue, effectiveCycle: dto.effectiveCycle ?? null, }), ] ); const updated = await findRuleByKey(dto.ruleKey); return toResponse(updated!); } /** * Batch update multiple rules in a single operation. * Requirements: 8.5, 8.6 */ export async function updateRules(rules: RuleDTO[], operatorId: number): Promise { const results: RuleResponse[] = []; for (const dto of rules) { const result = await updateRule(dto, operatorId); results.push(result); } return results; }