feat: govern knowledge assets and source citations
This commit is contained in:
@@ -77,6 +77,7 @@ export type VectorIndexStatus = {
|
||||
qdrantDimension?: number;
|
||||
qdrantPoints?: number;
|
||||
fragments: number;
|
||||
ungovernedFragments: number;
|
||||
embeddedFragments: number;
|
||||
embeddingModel?: string;
|
||||
embeddingDimension?: number;
|
||||
|
||||
@@ -82,6 +82,384 @@ export type ProcessingRetryResponse = {
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type QualityAsset = {
|
||||
id: number;
|
||||
knowledgeId: number;
|
||||
attachmentId?: number;
|
||||
docId: string;
|
||||
sourceName: string;
|
||||
sourceType: string;
|
||||
sourceAuthority: string;
|
||||
sourceVersion: string;
|
||||
dataClass: string;
|
||||
lifecycleStatus: string;
|
||||
indexStatus: string;
|
||||
applicableRegion?: string;
|
||||
applicableProject?: string;
|
||||
applicableRole?: string;
|
||||
effectiveFrom?: string;
|
||||
effectiveTo?: string;
|
||||
currentVersionId: number;
|
||||
semanticAnalysisStatus: 'PENDING' | 'PROCESSING' | 'COMPLETE' | 'NOT_REQUIRED' | 'FAILED' | 'DEAD_LETTER';
|
||||
semanticLastError?: string;
|
||||
semanticRetryCount: number;
|
||||
issueCount: number;
|
||||
blockingIssueCount: number;
|
||||
updateTime: string;
|
||||
};
|
||||
|
||||
export type QualityIssue = {
|
||||
id: number;
|
||||
reasonCode: string;
|
||||
severity: 'INFO' | 'WARNING' | 'ERROR' | 'CRITICAL';
|
||||
gateType: 'HARD' | 'SOFT';
|
||||
evidenceJson: string;
|
||||
recommendedAction: string;
|
||||
detectorType: string;
|
||||
detectorVersion: string;
|
||||
status: string;
|
||||
createTime: string;
|
||||
};
|
||||
|
||||
export type QualityPrivacyPreview = {
|
||||
versionId: number;
|
||||
privacyStatus: 'NOT_PROCESSED' | 'CLEAN' | 'REDACTED' | 'BLOCKED';
|
||||
redactionPolicyVersion?: string;
|
||||
redactionSummaryJson?: string;
|
||||
redactedSourceName?: string;
|
||||
redactedContentPreview?: string;
|
||||
};
|
||||
|
||||
export type QualityConflict = {
|
||||
id: number;
|
||||
conflictType: 'POLARITY' | 'VALUE' | 'APPLICABILITY';
|
||||
status: 'PENDING_REVIEW' | 'CONFIRMED' | 'FALSE_POSITIVE' | 'RESOLVED';
|
||||
leftText: string;
|
||||
rightText: string;
|
||||
leftAssetId: number;
|
||||
leftSourceName: string;
|
||||
rightAssetId: number;
|
||||
rightSourceName: string;
|
||||
evidenceJson: string;
|
||||
reviewNote?: string;
|
||||
createTime: string;
|
||||
};
|
||||
|
||||
export type QualityReviewRequest = {
|
||||
reason: string;
|
||||
usageType: string;
|
||||
sourceAuthority: string;
|
||||
sourceVersion: string;
|
||||
applicableRegion?: string;
|
||||
applicableProject?: string;
|
||||
applicableRole?: string;
|
||||
effectiveFrom?: string;
|
||||
effectiveTo?: string;
|
||||
acceptedReasonCodes: string[];
|
||||
supersedesAssetId?: number;
|
||||
};
|
||||
|
||||
export type QualityPublishResult = {
|
||||
assetId: number;
|
||||
versionId: number;
|
||||
lifecycleStatus: string;
|
||||
indexStatus: string;
|
||||
fragments: number;
|
||||
reviewId?: number;
|
||||
};
|
||||
|
||||
export type LegacyStageResult = {
|
||||
discovered: number;
|
||||
staged: number;
|
||||
reparsed: number;
|
||||
quarantined: number;
|
||||
stagedAssetIds: number[];
|
||||
failedAttachmentIds: number[];
|
||||
nextCursor: number;
|
||||
moreAvailable: boolean;
|
||||
};
|
||||
|
||||
export type LegacyStagePreview = {
|
||||
discovered: number;
|
||||
sourceAvailable: number;
|
||||
sourceUnavailable: number;
|
||||
nextCursor: number;
|
||||
moreAvailable: boolean;
|
||||
};
|
||||
|
||||
export type KnowledgeGlossaryTerm = {
|
||||
id: number;
|
||||
term: string;
|
||||
canonicalTerm: string;
|
||||
aliases: string[];
|
||||
definition?: string;
|
||||
applicableRegion?: string;
|
||||
applicableProject?: string;
|
||||
applicableRole?: string;
|
||||
versionNo: number;
|
||||
status: 'DRAFT' | 'ACTIVE' | 'REJECTED' | 'DEPRECATED';
|
||||
reviewerId?: number;
|
||||
reviewReason?: string;
|
||||
reviewedTime?: string;
|
||||
createBy?: number;
|
||||
createTime: string;
|
||||
updateTime: string;
|
||||
};
|
||||
|
||||
export type KnowledgeGlossaryDraft = {
|
||||
term: string;
|
||||
canonicalTerm: string;
|
||||
aliases: string[];
|
||||
definition?: string;
|
||||
applicableRegion?: string;
|
||||
applicableProject?: string;
|
||||
applicableRole?: string;
|
||||
};
|
||||
|
||||
export type ProcessingRuleStatus = 'DRAFT' | 'SHADOW' | 'PAUSED' | 'RETIRED';
|
||||
|
||||
export type ProcessingRule = {
|
||||
id: number;
|
||||
ruleCode: string;
|
||||
versionNo: number;
|
||||
stage: string;
|
||||
riskClass: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
|
||||
action: 'FLAG' | 'REVIEW' | 'QUARANTINE';
|
||||
implementationType: 'DETERMINISTIC' | 'STATISTICAL' | 'LLM_ASSISTED';
|
||||
scope: Record<string, unknown>;
|
||||
config: Record<string, unknown>;
|
||||
status: ProcessingRuleStatus;
|
||||
ownerId: number;
|
||||
supersedesRuleId?: number;
|
||||
shadowStartedTime?: string;
|
||||
retiredTime?: string;
|
||||
createTime: string;
|
||||
updateTime: string;
|
||||
};
|
||||
|
||||
export type ProcessingRuleDraft = {
|
||||
ruleCode: string;
|
||||
stage: string;
|
||||
riskClass: ProcessingRule['riskClass'];
|
||||
action: ProcessingRule['action'];
|
||||
implementationType: ProcessingRule['implementationType'];
|
||||
scope: Record<string, unknown>;
|
||||
config: Record<string, unknown>;
|
||||
supersedesRuleId?: number;
|
||||
};
|
||||
|
||||
export type ProcessingRuleMetrics = {
|
||||
ruleId: number;
|
||||
sampleCount: number;
|
||||
matchedCount: number;
|
||||
falseAllowCount: number;
|
||||
falseBlockCount: number;
|
||||
agreementRate: number;
|
||||
falseAllowRate: number;
|
||||
falseBlockRate: number;
|
||||
};
|
||||
|
||||
export type RuleReviewSample = {
|
||||
id: number;
|
||||
ruleId: number;
|
||||
sourceEvaluationId?: number;
|
||||
assetId?: number;
|
||||
versionId?: number;
|
||||
sampleKey: string;
|
||||
samplingStrategy: 'RANDOM' | 'RISK_WEIGHTED' | 'MISMATCH' | 'MANUAL';
|
||||
status: 'PENDING' | 'REVIEWED';
|
||||
reviewResult?: 'CONFIRMED' | 'FALSE_ALLOW' | 'FALSE_BLOCK' | 'NOT_APPLICABLE';
|
||||
reviewNote?: string;
|
||||
sampledBy: number;
|
||||
sampledTime: string;
|
||||
reviewedBy?: number;
|
||||
reviewedTime?: string;
|
||||
};
|
||||
|
||||
export type RuleSamplingResult = {
|
||||
runId?: string;
|
||||
candidateCount: number;
|
||||
eligibleCount: number;
|
||||
createdCount: number;
|
||||
mismatchCount: number;
|
||||
};
|
||||
|
||||
export type GoldenDatasetStatus = 'DRAFT' | 'FROZEN' | 'RETIRED';
|
||||
|
||||
export type GoldenDataset = {
|
||||
id: number;
|
||||
datasetCode: string;
|
||||
versionNo: number;
|
||||
name: string;
|
||||
description?: string;
|
||||
status: GoldenDatasetStatus;
|
||||
sampleCount: number;
|
||||
contentHash?: string;
|
||||
ownerId: number;
|
||||
frozenBy?: number;
|
||||
frozenTime?: string;
|
||||
createTime: string;
|
||||
updateTime: string;
|
||||
};
|
||||
|
||||
export type GoldenDatasetDraft = {
|
||||
datasetCode: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
};
|
||||
|
||||
export type GoldenSample = {
|
||||
id: number;
|
||||
datasetId: number;
|
||||
sampleKey: string;
|
||||
riskClass: ProcessingRule['riskClass'];
|
||||
expectedDecision: 'PASS' | 'REVIEW' | 'BLOCK';
|
||||
reasonCodes: string[];
|
||||
evidenceRef: string;
|
||||
assetId?: number;
|
||||
versionId?: number;
|
||||
createdBy: number;
|
||||
createTime: string;
|
||||
};
|
||||
|
||||
export type GoldenSampleDraft = {
|
||||
sampleKey: string;
|
||||
riskClass: GoldenSample['riskClass'];
|
||||
expectedDecision: GoldenSample['expectedDecision'];
|
||||
reasonCodes: string[];
|
||||
evidenceRef: string;
|
||||
assetId?: number;
|
||||
versionId?: number;
|
||||
};
|
||||
|
||||
export type AcceptanceProfileStatus = 'DRAFT' | 'FROZEN' | 'RETIRED';
|
||||
|
||||
export type AcceptanceProfile = {
|
||||
id: number;
|
||||
ruleId: number;
|
||||
versionNo: number;
|
||||
riskClass: ProcessingRule['riskClass'];
|
||||
minTotalSamples: number;
|
||||
minGoldenSamples: number;
|
||||
minReviewedSamples: number;
|
||||
minAgreementRate: number;
|
||||
maxFalseAllowRate: number;
|
||||
maxFalseBlockRate: number;
|
||||
minReviewCoverageRate: number;
|
||||
status: AcceptanceProfileStatus;
|
||||
ownerId: number;
|
||||
freezeReason?: string;
|
||||
frozenBy?: number;
|
||||
frozenTime?: string;
|
||||
createTime: string;
|
||||
updateTime: string;
|
||||
};
|
||||
|
||||
export type AcceptanceProfileDraft = Pick<
|
||||
AcceptanceProfile,
|
||||
| 'minTotalSamples'
|
||||
| 'minGoldenSamples'
|
||||
| 'minReviewedSamples'
|
||||
| 'minAgreementRate'
|
||||
| 'maxFalseAllowRate'
|
||||
| 'maxFalseBlockRate'
|
||||
| 'minReviewCoverageRate'
|
||||
>;
|
||||
|
||||
export type RuleReadiness = {
|
||||
evidenceReady: boolean;
|
||||
enforcementEnabled: boolean;
|
||||
ruleStatus: ProcessingRuleStatus;
|
||||
riskClass: ProcessingRule['riskClass'];
|
||||
profile?: AcceptanceProfile;
|
||||
metrics: {
|
||||
totalSamples: number;
|
||||
goldenSamples: number;
|
||||
matchedSamples: number;
|
||||
falseAllowCount: number;
|
||||
falseBlockCount: number;
|
||||
reviewedSamples: number;
|
||||
pendingMismatchReviews: number;
|
||||
agreementRate: number;
|
||||
falseAllowRate: number;
|
||||
falseBlockRate: number;
|
||||
reviewCoverageRate: number;
|
||||
};
|
||||
reasonCodes: string[];
|
||||
};
|
||||
|
||||
export type PipelineRun = {
|
||||
id: number;
|
||||
runId: string;
|
||||
assetId?: number;
|
||||
inputVersionId?: number;
|
||||
outputVersionId?: number;
|
||||
stage: string;
|
||||
processorName: string;
|
||||
processorVersion: string;
|
||||
triggerType: string;
|
||||
status: 'RUNNING' | 'SUCCEEDED' | 'FAILED' | 'CANCELLED';
|
||||
metrics: Record<string, unknown>;
|
||||
errorCode?: string;
|
||||
errorMessage?: string;
|
||||
requestedBy: number;
|
||||
startedTime: string;
|
||||
endedTime?: string;
|
||||
};
|
||||
|
||||
export type QualityIndexHealth = {
|
||||
pending: number;
|
||||
processing: number;
|
||||
failed: number;
|
||||
deadLetter: number;
|
||||
oldestPendingSeconds: number;
|
||||
staleAssets: number;
|
||||
vectorMatched: boolean;
|
||||
mysqlFragments?: number;
|
||||
ungovernedFragments?: number;
|
||||
qdrantPoints?: number;
|
||||
vectorMessage: string;
|
||||
healthy: boolean;
|
||||
};
|
||||
|
||||
export type QualitySnapshot = {
|
||||
totalAssets: number;
|
||||
reviewPending: number;
|
||||
quarantined: number;
|
||||
published: number;
|
||||
deprecated: number;
|
||||
openHardFindings: number;
|
||||
openSoftFindings: number;
|
||||
semanticDeadLetter: number;
|
||||
pendingDuplicateReviews: number;
|
||||
pendingConflictReviews: number;
|
||||
untraceablePublished: number;
|
||||
expiredPublished: number;
|
||||
publishedOpenFindings: number;
|
||||
publishedMembershipGap: number;
|
||||
publishedFragmentGap: number;
|
||||
successfulQueries24h: number;
|
||||
queriesMissingEvidence24h: number;
|
||||
traceabilityRate: number;
|
||||
queryEvidenceCoverage24h: number;
|
||||
indexHealth: QualityIndexHealth;
|
||||
healthy: boolean;
|
||||
};
|
||||
|
||||
export type QualityAlert = {
|
||||
id: number;
|
||||
alertCode: string;
|
||||
severity: 'WARNING' | 'ERROR' | 'CRITICAL';
|
||||
status: 'OPEN' | 'RESOLVED';
|
||||
message: string;
|
||||
evidenceJson?: string;
|
||||
occurrenceCount: number;
|
||||
firstSeenTime: string;
|
||||
lastSeenTime: string;
|
||||
resolvedTime?: string;
|
||||
detectorVersion: string;
|
||||
};
|
||||
|
||||
export type LocalImportRequest = {
|
||||
directory: string;
|
||||
category: string;
|
||||
@@ -128,6 +506,281 @@ export function retryProcessingTask(id: number): Promise<ApiResult<ProcessingRet
|
||||
});
|
||||
}
|
||||
|
||||
export function listQualityAssets(status = 'REVIEW_PENDING', limit = 100): Promise<ApiResult<QualityAsset[]>> {
|
||||
return request({
|
||||
url: '/api/knowledge/quality/assets',
|
||||
method: 'get',
|
||||
params: { status, limit }
|
||||
});
|
||||
}
|
||||
|
||||
export function listQualityIssues(assetId: number): Promise<ApiResult<QualityIssue[]>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/assets/${assetId}/issues`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
export function getQualityPrivacyPreview(assetId: number): Promise<ApiResult<QualityPrivacyPreview>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/assets/${assetId}/privacy-preview`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
export function listQualityConflicts(assetId: number): Promise<ApiResult<QualityConflict[]>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/assets/${assetId}/conflicts`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
export function reviewQualityConflict(
|
||||
conflictId: number,
|
||||
data: { decision: 'CONFIRMED' | 'FALSE_POSITIVE' | 'RESOLVED'; note: string }
|
||||
): Promise<ApiResult<{ conflictId: number; status: string }>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/conflicts/${conflictId}/review`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function getQualityIndexHealth(): Promise<ApiResult<QualityIndexHealth>> {
|
||||
return request({
|
||||
url: '/api/knowledge/quality/index-health',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
export function getQualityMetrics(): Promise<ApiResult<QualitySnapshot>> {
|
||||
return request({
|
||||
url: '/api/knowledge/quality/metrics',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
export function listQualityAlerts(includeResolved = false, limit = 100): Promise<ApiResult<QualityAlert[]>> {
|
||||
return request({
|
||||
url: '/api/knowledge/quality/alerts',
|
||||
method: 'get',
|
||||
params: { includeResolved, limit }
|
||||
});
|
||||
}
|
||||
|
||||
export function publishQualityAsset(assetId: number, data: QualityReviewRequest): Promise<ApiResult<QualityPublishResult>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/assets/${assetId}/publish`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function withdrawQualityAsset(assetId: number, reason: string): Promise<ApiResult<QualityPublishResult>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/assets/${assetId}/withdraw`,
|
||||
method: 'post',
|
||||
data: { reason }
|
||||
});
|
||||
}
|
||||
|
||||
export function stageLegacyQualityAssets(limit = 50, afterAttachmentId = 0): Promise<ApiResult<LegacyStageResult>> {
|
||||
return request({
|
||||
url: '/api/knowledge/quality/legacy/stage',
|
||||
method: 'post',
|
||||
params: { limit, afterAttachmentId },
|
||||
headers: { repeatSubmit: false }
|
||||
});
|
||||
}
|
||||
|
||||
export function previewLegacyQualityAssets(limit = 50, afterAttachmentId = 0): Promise<ApiResult<LegacyStagePreview>> {
|
||||
return request({
|
||||
url: '/api/knowledge/quality/legacy/preview',
|
||||
method: 'get',
|
||||
params: { limit, afterAttachmentId }
|
||||
});
|
||||
}
|
||||
|
||||
export function listKnowledgeGlossary(status: KnowledgeGlossaryTerm['status'] = 'ACTIVE', limit = 200): Promise<ApiResult<KnowledgeGlossaryTerm[]>> {
|
||||
return request({
|
||||
url: '/api/knowledge/quality/glossary',
|
||||
method: 'get',
|
||||
params: { status, limit }
|
||||
});
|
||||
}
|
||||
|
||||
export function createKnowledgeGlossaryDraft(data: KnowledgeGlossaryDraft): Promise<ApiResult<KnowledgeGlossaryTerm>> {
|
||||
return request({
|
||||
url: '/api/knowledge/quality/glossary',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function approveKnowledgeGlossary(id: number, reason: string): Promise<ApiResult<KnowledgeGlossaryTerm>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/glossary/${id}/approve`,
|
||||
method: 'post',
|
||||
data: { reason }
|
||||
});
|
||||
}
|
||||
|
||||
export function deprecateKnowledgeGlossary(id: number, reason: string): Promise<ApiResult<KnowledgeGlossaryTerm>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/glossary/${id}/deprecate`,
|
||||
method: 'post',
|
||||
data: { reason }
|
||||
});
|
||||
}
|
||||
|
||||
export function rejectKnowledgeGlossary(id: number, reason: string): Promise<ApiResult<KnowledgeGlossaryTerm>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/glossary/${id}/reject`,
|
||||
method: 'post',
|
||||
data: { reason }
|
||||
});
|
||||
}
|
||||
|
||||
export function listProcessingRules(status: ProcessingRuleStatus = 'SHADOW', limit = 100): Promise<ApiResult<ProcessingRule[]>> {
|
||||
return request({
|
||||
url: '/api/knowledge/quality/rules',
|
||||
method: 'get',
|
||||
params: { status, limit }
|
||||
});
|
||||
}
|
||||
|
||||
export function createProcessingRuleDraft(data: ProcessingRuleDraft): Promise<ApiResult<ProcessingRule>> {
|
||||
return request({
|
||||
url: '/api/knowledge/quality/rules',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function transitionProcessingRule(ruleId: number, targetStatus: ProcessingRuleStatus, reason: string): Promise<ApiResult<ProcessingRule>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/rules/${ruleId}/status`,
|
||||
method: 'post',
|
||||
data: { targetStatus, reason }
|
||||
});
|
||||
}
|
||||
|
||||
export function getProcessingRuleMetrics(ruleId: number): Promise<ApiResult<ProcessingRuleMetrics>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/rules/${ruleId}/metrics`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
export function listRuleReviewSamples(
|
||||
ruleId: number,
|
||||
status: RuleReviewSample['status'] = 'PENDING',
|
||||
limit = 100
|
||||
): Promise<ApiResult<RuleReviewSample[]>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/rules/${ruleId}/samples`,
|
||||
method: 'get',
|
||||
params: { status, limit }
|
||||
});
|
||||
}
|
||||
|
||||
export function reviewRuleSample(
|
||||
sampleId: number,
|
||||
data: { result: NonNullable<RuleReviewSample['reviewResult']>; note: string }
|
||||
): Promise<ApiResult<RuleReviewSample>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/rules/samples/${sampleId}/review`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function scheduleRuleReviewSamples(limit = 200): Promise<ApiResult<RuleSamplingResult>> {
|
||||
return request({
|
||||
url: '/api/knowledge/quality/rules/samples/schedule',
|
||||
method: 'post',
|
||||
params: { limit },
|
||||
headers: { repeatSubmit: false }
|
||||
});
|
||||
}
|
||||
|
||||
export function listPipelineRuns(status = 'ALL', limit = 50): Promise<ApiResult<PipelineRun[]>> {
|
||||
return request({
|
||||
url: '/api/knowledge/quality/pipeline-runs',
|
||||
method: 'get',
|
||||
params: { status, limit }
|
||||
});
|
||||
}
|
||||
|
||||
export function listGoldenDatasets(status: GoldenDatasetStatus = 'DRAFT', limit = 100): Promise<ApiResult<GoldenDataset[]>> {
|
||||
return request({
|
||||
url: '/api/knowledge/quality/golden-datasets',
|
||||
method: 'get',
|
||||
params: { status, limit }
|
||||
});
|
||||
}
|
||||
|
||||
export function createGoldenDatasetDraft(data: GoldenDatasetDraft): Promise<ApiResult<GoldenDataset>> {
|
||||
return request({
|
||||
url: '/api/knowledge/quality/golden-datasets',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function listGoldenSamples(datasetId: number, limit = 200): Promise<ApiResult<GoldenSample[]>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/golden-datasets/${datasetId}/samples`,
|
||||
method: 'get',
|
||||
params: { limit }
|
||||
});
|
||||
}
|
||||
|
||||
export function addGoldenSample(datasetId: number, data: GoldenSampleDraft): Promise<ApiResult<GoldenSample>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/golden-datasets/${datasetId}/samples`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function freezeGoldenDataset(datasetId: number): Promise<ApiResult<GoldenDataset>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/golden-datasets/${datasetId}/freeze`,
|
||||
method: 'post'
|
||||
});
|
||||
}
|
||||
|
||||
export function listAcceptanceProfiles(ruleId: number): Promise<ApiResult<AcceptanceProfile[]>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/rules/${ruleId}/acceptance-profiles`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
export function createAcceptanceProfile(ruleId: number, data: AcceptanceProfileDraft): Promise<ApiResult<AcceptanceProfile>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/rules/${ruleId}/acceptance-profiles`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function freezeAcceptanceProfile(ruleId: number, profileId: number, reason: string): Promise<ApiResult<AcceptanceProfile>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/rules/${ruleId}/acceptance-profiles/${profileId}/freeze`,
|
||||
method: 'post',
|
||||
data: { reason }
|
||||
});
|
||||
}
|
||||
|
||||
export function getRuleReadiness(ruleId: number): Promise<ApiResult<RuleReadiness>> {
|
||||
return request({
|
||||
url: `/api/knowledge/quality/rules/${ruleId}/readiness`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
export function importLocalKnowledgeDocs(data: LocalImportRequest): Promise<ApiResult<LocalImportResponse>> {
|
||||
return request({
|
||||
url: '/api/knowledge/doc/import-local',
|
||||
|
||||
@@ -92,7 +92,10 @@ export type AnswerFeedbackItem = {
|
||||
position: string;
|
||||
source: string;
|
||||
reviewId?: number | null;
|
||||
requestId?: string | null;
|
||||
reviewStatus: string;
|
||||
reviewAction?: string | null;
|
||||
reviewNote?: string | null;
|
||||
reviewer?: string | null;
|
||||
reviewedTime?: string | null;
|
||||
createTime: string;
|
||||
@@ -102,6 +105,7 @@ export type AnswerFeedbackItem = {
|
||||
export type AnswerFeedbackReviewResponse = {
|
||||
id: number;
|
||||
reviewStatus: string;
|
||||
reviewAction: 'KEEP' | 'WITHDRAW';
|
||||
reviewer?: string | null;
|
||||
reviewedTime?: string | null;
|
||||
};
|
||||
@@ -194,10 +198,14 @@ export function listAnswerFeedback(status = '待复核', limit = 50): Promise<Ap
|
||||
});
|
||||
}
|
||||
|
||||
export function reviewAnswerFeedback(id: number): Promise<ApiResult<AnswerFeedbackReviewResponse>> {
|
||||
export function reviewAnswerFeedback(
|
||||
id: number,
|
||||
data: { action: 'KEEP' | 'WITHDRAW'; note: string }
|
||||
): Promise<ApiResult<AnswerFeedbackReviewResponse>> {
|
||||
return request({
|
||||
url: `/api/knowledge/answer-feedback/${id}/review`,
|
||||
method: 'post',
|
||||
data,
|
||||
headers: { repeatSubmit: false }
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user