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