95 lines
2.4 KiB
TypeScript
95 lines
2.4 KiB
TypeScript
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<RuleResponse[]> {
|
|
const rows = await findAllRules();
|
|
return rows.map(toResponse);
|
|
}
|
|
|
|
/** Get a single rule by key */
|
|
export async function getRuleByKey(ruleKey: string): Promise<RuleResponse | null> {
|
|
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<RuleResponse> {
|
|
// 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<RuleResponse[]> {
|
|
const results: RuleResponse[] = [];
|
|
for (const dto of rules) {
|
|
const result = await updateRule(dto, operatorId);
|
|
results.push(result);
|
|
}
|
|
return results;
|
|
}
|