Files
RiskAgent/src/knowledge/store.ts
T
freedakgmail c670b9e454 外包风险评估系统:领域引擎+前端+服务端持久化与生产部署
- 确定性领域引擎(分类/评分/分级/红线/费用/裁决)+LLM(通义千问)语言理解
- 6步评估向导、服务端草稿持久化(跨设备/编辑草稿保护)
- 工作流(草稿→风控→管理层)、RBAC、报告导出、校准、客户/费率/红线/最低工资管理
- 专业图标体系替换全部emoji、看板美化
- 生产化:API_BASE可配置(同源反代)、auth密钥惰性读取修复RBAC
- 444单测+204前端测试+51 e2e
2026-06-13 01:06:39 +08:00

83 lines
3.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 分行业知识库存储:按行业标识分区存储五类内容并校验完备性(Req 14.1, 14.4)。
*
* - 按行业标识分区存储 Indicator、权重模板、Redline、典型案例、追问话术五类内容(Req 14.1)。
* - 新增分区缺任一类内容时拒绝创建、抛出指明缺失类别的校验错误,
* 且保持已有分区不变(Req 14.4{@link IncompletePartitionError})。
*/
import type { Industry } from '../domain/common.js';
import type { IndustryPartition, KnowledgeBase } from '../domain/knowledge.js';
import { findMissingCategories } from './category.js';
import { IncompletePartitionError } from './errors.js';
/** 规范化行业标识用于分区键匹配(首尾空白不敏感)。 */
function normalizeIndustryId(industryId: Industry): string {
return industryId.trim();
}
/**
* 分行业知识库存储(Knowledge_BaseReq 14.1, 14.4)。
*
* 以行业标识为键登记 {@link IndustryPartition};新增分区前强制完备性校验,
* 校验不通过则拒绝并保持已有分区不变。
*/
export class KnowledgeBaseStore {
/** 以规范化行业标识为键的分区表。 */
private readonly partitions = new Map<string, IndustryPartition>();
/**
* @param initial 初始登记的行业分区集合(默认空)。
* @throws {IncompletePartitionError} 当任一初始分区缺少五类必备内容时。
*/
constructor(initial: readonly IndustryPartition[] = []) {
for (const partition of initial) {
this.addPartition(partition);
}
}
/**
* 新增一个行业分区(Req 14.1, 14.4)。
*
* 先做五类内容完备性校验:缺任一类则拒绝创建、抛出
* {@link IncompletePartitionError}(指明缺失类别),且不修改任何已有分区。
* 校验通过后按行业标识登记该分区(同一行业再次新增将覆盖其内容)。
*
* @throws {IncompletePartitionError} 当该分区缺少五类必备内容中的任一类时。
*/
addPartition(partition: IndustryPartition): void {
const missing = findMissingCategories(partition);
if (missing.length > 0) {
// 校验失败:拒绝创建,不改动 this.partitions(保持已有分区不变)。
throw new IncompletePartitionError(partition.industryId, missing);
}
this.partitions.set(normalizeIndustryId(partition.industryId), partition);
}
/**
* 判断是否存在与给定行业标识匹配的分区。
*/
has(industryId: Industry): boolean {
return this.partitions.has(normalizeIndustryId(industryId));
}
/**
* 按行业标识获取分区;不存在时返回 undefined。
*/
get(industryId: Industry): IndustryPartition | undefined {
return this.partitions.get(normalizeIndustryId(industryId));
}
/** 已登记分区数量。 */
get size(): number {
return this.partitions.size;
}
/**
* 导出当前知识库的不可变快照(Req 14.1)。
*/
snapshot(): KnowledgeBase {
return { partitions: [...this.partitions.values()] };
}
}