feat(ai-analysis): 添加业务分析共享契约

This commit is contained in:
2026-07-08 20:56:20 +08:00
parent 74c55df59b
commit b6b7ebf44f
2 changed files with 239 additions and 0 deletions

View File

@@ -0,0 +1,238 @@
export type AnalysisSurface = 'ai_assistant' | 'product_detail' | 'project_detail' | 'version_detail';
export type MetricId =
| 'version_risk_score'
| 'completion_trend'
| 'overdue_item_count'
| 'requirement_status_count'
| 'requirement_completion_count'
| 'requirement_source_count'
| 'department_workload'
| 'member_pending_work'
| 'member_effort_hours'
| 'bug_severity_count'
| 'test_pass_rate'
| 'overtime_reason_hours'
| 'delay_rate'
| 'delay_reason_count';
export type DimensionId =
| 'product'
| 'project'
| 'version'
| 'requirement_status'
| 'requirement_type'
| 'requirement_source'
| 'department'
| 'member'
| 'role'
| 'month'
| 'week'
| 'day'
| 'bug_severity'
| 'bug_status'
| 'test_status'
| 'delay_reason';
export type AnalysisType =
| 'ranking'
| 'trend'
| 'comparison'
| 'distribution'
| 'composition'
| 'correlation'
| 'breakdown'
| 'summary';
export type TimePolicy = 'current_state' | 'last_30_days' | 'lifecycle' | 'user_required' | 'explicit_range';
export type ChartKind =
| 'number_card'
| 'line_area'
| 'horizontal_bar'
| 'stacked_horizontal_bar'
| 'donut'
| 'table_preview';
export interface MetricRef {
metricId: MetricId;
version: number;
}
export interface MetricDefinition {
metricId: MetricId;
version: number;
name: string;
description: string;
formula: string;
owner: string;
supportedDimensions: DimensionId[];
supportedAnalysisTypes: AnalysisType[];
defaultChart: ChartKind;
defaultDimension?: DimensionId;
defaultTimePolicy: TimePolicy;
status: 'active' | 'deprecated';
}
export type DataScope =
| { type: 'self'; userId: string }
| { type: 'managed_projects'; projectIds: string[] }
| { type: 'product'; productId: string }
| { type: 'project'; projectId: string }
| { type: 'version'; versionId: string }
| { type: 'system'; reason: 'admin' | 'management_permission' };
export interface AnalysisPlan {
metricRef: MetricRef;
analysisType: AnalysisType;
dimensions: DimensionId[];
timeRange?: {
start: string;
end: string;
policy: TimePolicy;
};
filters: Record<string, string | number | boolean | string[] | number[]>;
scope: DataScope;
limit?: number;
sort?: Array<{ field: string; direction: 'asc' | 'desc' }>;
}
export interface EvidenceItem {
label: string;
value: string | number;
unit?: string;
sourceDomain:
| 'product'
| 'project'
| 'version'
| 'requirement'
| 'version_plan'
| 'dev_task'
| 'test_case'
| 'bug'
| 'work_activity'
| 'task_worklog'
| 'overtime'
| 'xiaobao';
sourceLabel?: string;
drilldown?: {
type: 'list' | 'detail';
target: string;
filters: Record<string, unknown>;
};
}
export interface MetricResult {
metricRef: MetricRef;
analysisType: AnalysisType;
columns: Array<{ id: string; label: string; type: 'string' | 'number' | 'date' | 'percent' }>;
rows: Array<Record<string, string | number | null>>;
totals?: Record<string, string | number>;
comparison?: {
baselineLabel: string;
currentLabel: string;
deltaValue?: number;
deltaPercent?: number;
};
evidence: EvidenceItem[];
dataScope: DataScope;
generatedAt: string;
}
export interface UnifiedChartSpec {
kind: ChartKind;
title: string;
subtitle?: string;
dataset: {
source: Array<Record<string, string | number | null>>;
x?: string;
y?: string;
series?: string;
value?: string;
label?: string;
};
encoding: {
x?: { field: string; label: string };
y?: { field: string; label: string };
value?: { field: string; label: string; unit?: string };
color?: { mode: 'single' | 'risk' | 'semantic'; field?: string };
};
annotations?: Array<{
type: 'outlier' | 'peak' | 'target' | 'threshold';
label: string;
value?: string | number;
field?: string;
}>;
stylePreset: 'apple_vision_light' | 'apple_vision_dark';
}
export interface InsightCard {
summary: string;
primaryValue?: {
label: string;
value: string | number;
unit?: string;
};
comparison?: {
label: string;
direction: 'up' | 'down' | 'flat';
value: string | number;
tone: 'positive' | 'negative' | 'neutral';
};
semanticConfidence: 'high' | 'medium' | 'low';
dataConfidence: 'sufficient' | 'partial' | 'insufficient';
}
export interface AnalysisReport {
summary: string;
keyFindings: string[];
evidence: EvidenceItem[];
suggestions: string[];
dataScope: {
timeDescription: string;
permissionDescription: string;
metricFormulaDescription: string;
generatedAt: string;
};
}
export type FollowUp =
| { type: 'question'; label: string; prompt: string }
| { type: 'drilldown'; label: string; target: string; filters: Record<string, unknown> }
| { type: 'export'; label: string; format: 'png' | 'pdf' | 'csv' };
export interface AnalysisRequest {
question: string;
context?: {
surface: AnalysisSurface;
productId?: string;
projectId?: string;
versionId?: string;
};
}
export type AnalysisErrorCode =
| 'NO_PERMISSION'
| 'UNSUPPORTED_ANALYSIS'
| 'AMBIGUOUS_INTENT'
| 'NO_DATA'
| 'AI_UNAVAILABLE'
| 'INVALID_PLAN';
export type AnalysisResponse =
| {
ok: true;
plan: AnalysisPlan;
metricResult: MetricResult;
insight: InsightCard;
chart: UnifiedChartSpec;
report: AnalysisReport;
followUps: FollowUp[];
}
| {
ok: false;
code: AnalysisErrorCode;
message: string;
clarificationOptions?: Array<{ label: string; prompt: string }>;
dataScope?: DataScope;
};

View File

@@ -1,3 +1,4 @@
export * from './enums';
export * from './types';
export * from './agent';
export * from './analysis';