feat(ai-analysis): 添加业务分析共享契约
This commit is contained in:
238
packages/shared/src/analysis.ts
Normal file
238
packages/shared/src/analysis.ts
Normal 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;
|
||||
};
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './enums';
|
||||
export * from './types';
|
||||
export * from './agent';
|
||||
export * from './analysis';
|
||||
|
||||
Reference in New Issue
Block a user