外包风险评估系统:领域引擎+前端+服务端持久化与生产部署
- 确定性领域引擎(分类/评分/分级/红线/费用/裁决)+LLM(通义千问)语言理解 - 6步评估向导、服务端草稿持久化(跨设备/编辑草稿保护) - 工作流(草稿→风控→管理层)、RBAC、报告导出、校准、客户/费率/红线/最低工资管理 - 专业图标体系替换全部emoji、看板美化 - 生产化:API_BASE可配置(同源反代)、auth密钥惰性读取修复RBAC - 444单测+204前端测试+51 e2e
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* 分行业知识库存储:按行业标识分区存储五类内容并校验完备性(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_Base,Req 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()] };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user