Files
performance-evaluation-system/backend/src/services/ConfigService.ts
2026-04-11 11:51:54 +08:00

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;
}