新增 Business Analysis Agent 设计稿,明确 Semantic Layer、Metric Catalog、Analysis Strategy、Analysis Plan Processor、Metric Engine、统一 ChartSpec、Insight/Report/Evidence/Follow-up 和 Apple Vision 图表规范。 同步记录关键架构决策,约束 AI 只提出分析计划建议,系统校验规范化后执行,且不得绕过权限或直接生成 SQL。 Co-Authored-By: GPT-5 Codex <codex@openai.com>
744 lines
23 KiB
Markdown
744 lines
23 KiB
Markdown
# Business Analysis Agent Design
|
|
|
|
## Goal
|
|
|
|
Build a read-only Business Analysis Agent that lets users ask FTB business data questions in natural language and receive an Insight Card, a chart, an analysis report, explainable evidence, and safe follow-up options.
|
|
|
|
The first product surface is the AI Assistant business-data conversation. The same analysis engine will also be embedded in product, project, and version detail pages with the current page context pre-filled.
|
|
|
|
## Approved Direction
|
|
|
|
- Use a dedicated Business Analysis Agent instead of extending Prototype Decompose Agent or Risk Watch Agent.
|
|
- Use ECharts as the first chart renderer, but do not expose raw ECharts options as the platform contract.
|
|
- Define a platform Unified ChartSpec and render it through a frontend Chart Renderer.
|
|
- Use Apple Vision style visual rules: large whitespace, large radius, light shadow, translucent material, clear hierarchy, natural motion, and content-first charts.
|
|
- Default to the last 30 days only for time-window analysis when the user did not specify a time range. Current status, risk, and lifecycle questions must use their natural business scope instead of forcing last 30 days.
|
|
- Every answer must include a structured report, not only a chart.
|
|
- The Agent must not mutate business data, create drafts, change workflow state, or bypass permissions.
|
|
|
|
## Non-Goals
|
|
|
|
- No AI-generated SQL.
|
|
- No direct AI database access.
|
|
- No arbitrary dashboard builder in the first implementation.
|
|
- No automatic business actions such as creating meetings, assigning owners, or changing due dates.
|
|
- No colorful BI big-screen style, 3D effects, dense dashboards, or raw table dumps as the primary answer.
|
|
- No new AppData key as a source of truth.
|
|
|
|
## Core Architecture
|
|
|
|
```text
|
|
User question + optional page context
|
|
↓
|
|
Analysis Planner
|
|
↓
|
|
Semantic Layer
|
|
↓
|
|
Permission Scope Resolver
|
|
↓
|
|
Analysis Strategy
|
|
1. Template Strategy
|
|
2. Rule Composition Strategy (Deterministic)
|
|
3. AI Planning Strategy
|
|
↓
|
|
Analysis Plan Processor
|
|
- Validate: permission, metric, dimension, aggregation, time range, data scope
|
|
- Normalize: produce one standard AnalysisPlan shape
|
|
↓
|
|
Metric Engine
|
|
↓
|
|
Metric Result
|
|
├─ ChartSpec Builder
|
|
├─ Insight Engine
|
|
├─ Report Builder
|
|
└─ Follow-up Builder
|
|
↓
|
|
UI Composition
|
|
↓
|
|
Insight Card + Chart + Report + Evidence + Follow-ups
|
|
```
|
|
|
|
### Responsibility Boundaries
|
|
|
|
- **Analysis Planner** reads the question and current page context, then produces an initial intent.
|
|
- **Semantic Layer** maps business words such as "busy", "pressure", "risk", "delay", "efficiency", and "quality" to system-owned metrics and dimensions.
|
|
- **Permission Scope Resolver** converts the current user and page context into a queryable scope. It must never widen the user's existing data access.
|
|
- **Analysis Strategy** chooses how to build the analysis plan.
|
|
- **Analysis Plan Processor** validates and normalizes all plans, including AI-generated ones.
|
|
- **Metric Engine** executes deterministic relation-table queries and aggregations.
|
|
- **ChartSpec Builder**, **Insight Engine**, **Report Builder**, and **Follow-up Builder** consume the same Metric Result in parallel.
|
|
- **UI Composition** assembles the final response for chat and context-page surfaces.
|
|
|
|
## Analysis Strategy
|
|
|
|
### 1. Template Strategy
|
|
|
|
Use fixed high-frequency templates for stable MVP analyses such as requirement completion, version risk, member workload, department workload, and Bug distribution.
|
|
|
|
Template Strategy should be preferred whenever the user question cleanly matches a known template.
|
|
|
|
### 2. Rule Composition Strategy (Deterministic)
|
|
|
|
When no complete template matches, deterministic system rules may compose known semantic concepts, metrics, dimensions, and time policies.
|
|
|
|
Example:
|
|
|
|
```text
|
|
"最近两个月延期原因变化"
|
|
→ trend + delay_reason + month + project/version scope
|
|
```
|
|
|
|
This composition is not done by AI. It is a rule engine over the Semantic Layer and Metric Catalog.
|
|
|
|
### 3. AI Planning Strategy
|
|
|
|
When neither template nor deterministic rule composition covers the question, AI may generate an Analysis Plan proposal.
|
|
|
|
AI Planning constraints:
|
|
|
|
- AI only proposes an Analysis Plan.
|
|
- The plan may only use metrics, dimensions, filters, aggregations, and time policies exposed by the Semantic Layer and Metric Catalog.
|
|
- The plan must pass Analysis Plan Processor validation and normalization before execution.
|
|
- If the plan references an unsupported metric, dimension, aggregation, filter, or scope, the system rejects it and returns a clarification or unsupported-analysis response.
|
|
|
|
Enterprise principle: AI does not directly decide what the system executes. AI proposes; the system validates, normalizes, and executes.
|
|
|
|
## Semantic Layer
|
|
|
|
The Semantic Layer is the business vocabulary boundary between natural language and system metrics.
|
|
|
|
### First Semantic Concepts
|
|
|
|
| User wording | Semantic concept | Default interpretation |
|
|
|---|---|---|
|
|
| 忙 / 负载高 | `workload` | Open item count plus estimated or actual effort, with overtime as supporting evidence |
|
|
| 压力大 | `work_pressure` | Usually workload plus overdue and overtime; lower semantic confidence than "忙" |
|
|
| 风险高 | `release_risk` | Xiaobao summary, blockers, bugs, test completion, remaining time |
|
|
| 延期 | `delay` | Past planned end or expected release, or forecast release later than target |
|
|
| 效率 | `delivery_efficiency` | Completion volume per effort; fall back to completion trend if effort data is insufficient |
|
|
| 质量差 | `quality_risk` | Open bugs, critical bugs, failed cases, blocked cases, repeated test rounds |
|
|
| 需求完成 | `requirement_completion` | Requirement status plus version delivery progress |
|
|
|
|
### Semantic Confidence
|
|
|
|
Semantic parsing must produce an internal `semanticConfidence`.
|
|
|
|
- High confidence: direct wording maps clearly to one concept, such as "延期率" → `delay_rate`.
|
|
- Medium confidence: wording is common but may carry multiple business meanings, such as "压力最大" → `work_pressure`.
|
|
- Low confidence: wording is vague or could map to unrelated metrics.
|
|
|
|
UI display should use levels, not pseudo-precise numbers:
|
|
|
|
- `high`: proceed directly.
|
|
- `medium`: proceed but show the assumed interpretation in Data Scope.
|
|
- `low`: ask a clarification or show selectable interpretations.
|
|
|
|
Do not display "AI confidence 96%" as a primary user-facing claim. Internal scores may be kept for ranking candidate interpretations.
|
|
|
|
## Metric Catalog
|
|
|
|
Metric Catalog is the stable source of truth for what the Business Analysis Agent can measure.
|
|
|
|
```ts
|
|
type MetricId = string;
|
|
|
|
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';
|
|
|
|
type AnalysisType =
|
|
| 'ranking'
|
|
| 'trend'
|
|
| 'comparison'
|
|
| 'distribution'
|
|
| 'composition'
|
|
| 'correlation'
|
|
| 'breakdown'
|
|
| 'summary';
|
|
|
|
type TimePolicy =
|
|
| 'current_state'
|
|
| 'last_30_days'
|
|
| 'lifecycle'
|
|
| 'user_required'
|
|
| 'explicit_range';
|
|
|
|
type ChartKind =
|
|
| 'number_card'
|
|
| 'line_area'
|
|
| 'horizontal_bar'
|
|
| 'stacked_horizontal_bar'
|
|
| 'donut'
|
|
| 'table_preview';
|
|
|
|
type 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';
|
|
};
|
|
```
|
|
|
|
Metric versioning is required. If the formula or business calculation changes, increment `version`. Do not increment the metric version for pure chart styling, copy, or layout changes.
|
|
|
|
Metric Result and analysis reports must record:
|
|
|
|
```ts
|
|
type MetricRef = {
|
|
metricId: string;
|
|
version: number;
|
|
};
|
|
```
|
|
|
|
Historical reproducibility needs both:
|
|
|
|
- `metricRef`: which metric algorithm was used.
|
|
- `analysisSnapshot` or `resultSnapshot`: the aggregated result at the time, because live business rows may change later.
|
|
|
|
## Analysis Plan Processor
|
|
|
|
The Analysis Plan Processor replaces a narrow "validator" with a stronger validate-and-normalize boundary.
|
|
|
|
Normalized plan shape:
|
|
|
|
```ts
|
|
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' };
|
|
|
|
type 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' }>;
|
|
};
|
|
```
|
|
|
|
### Validate
|
|
|
|
It must check:
|
|
|
|
- Current user is allowed to access the requested scope.
|
|
- Metric exists and is active.
|
|
- Metric version exists or can resolve to current active version.
|
|
- Dimensions are supported by the metric.
|
|
- Analysis type is supported by the metric.
|
|
- Aggregation is legal for the metric and dimension.
|
|
- Time range is valid and within supported business bounds.
|
|
- Filters are known, typed, and compatible with the scope.
|
|
- Requested Top N is within system limits.
|
|
|
|
### Normalize
|
|
|
|
It converts all strategy outputs into the same `AnalysisPlan` shape.
|
|
|
|
Example:
|
|
|
|
```ts
|
|
// AI or user wording
|
|
{
|
|
time: '最近半年',
|
|
metric: '延期率'
|
|
}
|
|
|
|
// normalized
|
|
{
|
|
metricRef: { metricId: 'delay_rate', version: 1 },
|
|
analysisType: 'trend',
|
|
dimensions: ['month'],
|
|
timeRange: {
|
|
start: '2026-01-01',
|
|
end: '2026-06-30'
|
|
},
|
|
filters: {},
|
|
scope: { type: 'user_accessible' },
|
|
limit: 12
|
|
}
|
|
```
|
|
|
|
The Metric Engine only accepts normalized `AnalysisPlan`.
|
|
|
|
## Time Range Rules
|
|
|
|
1. If the user specifies a time range, use that exact range.
|
|
2. If the question asks current state or risk, use current state data instead of last 30 days.
|
|
3. If the question asks trend, throughput, efficiency, effort, or change and does not specify time, use last 30 days.
|
|
4. If the question asks comparison and does not specify a baseline, use last 30 days versus the previous 30 days.
|
|
5. If the question asks lifecycle totals, use the object lifecycle.
|
|
6. Every response must show the applied time scope, data cutoff time, permission scope, and whether the analysis is current-state, time-window, comparison, or lifecycle.
|
|
|
|
## Permissions
|
|
|
|
The Business Analysis Agent can only query data the current user can already access.
|
|
|
|
First implementation scope:
|
|
|
|
- AI Assistant global analysis is available to logged-in users.
|
|
- Normal users see only data related to themselves or contexts they can access.
|
|
- Users with `management:view`, system admin permissions, or project Owner/Admin governance can analyze their managed scope.
|
|
- Product, project, and version detail analysis follows the page's existing access rules and must not widen scope.
|
|
|
|
Natural language cannot bypass permission boundaries. If a user asks for a forbidden scope, return a no-permission response or an empty authorized result with clear Data Scope.
|
|
|
|
## MVP Analysis Templates
|
|
|
|
The MVP starts with fixed templates while preserving the three-layer Analysis Strategy for future flexibility.
|
|
|
|
| Group | Template | Default chart | Time policy | Default limit |
|
|
|---|---|---|---|---|
|
|
| Risk and progress | Version risk ranking | Horizontal bar + numeric card | Current state | Top 10 |
|
|
| Risk and progress | Project or version completion trend | Smooth line area | Last 30 days if unspecified | 30 points |
|
|
| Risk and progress | Overdue item distribution | Horizontal bar | Current state | Top 10 |
|
|
| Product and requirements | Product requirement status distribution | Donut + numeric card | Current state or explicit range | All statuses |
|
|
| Product and requirements | Requirement completion trend | Smooth line area | Last 30 days if unspecified | 30 points |
|
|
| Product and requirements | Requirement source/type composition | Donut | Last 30 days if unspecified | Top 8 + other |
|
|
| People and departments | Department workload ranking | Horizontal bar | Current state | Top 10 |
|
|
| People and departments | Member pending-work ranking | Horizontal bar | Current state | Top 10 |
|
|
| People and departments | Member effort ranking | Horizontal bar + numeric card | Last 30 days if unspecified | Top 10 |
|
|
| Quality | Bug severity distribution | Stacked horizontal bar | Current state | Top 10 |
|
|
| Quality | Test pass-rate trend | Smooth line area | Last 30 days if unspecified | 30 points |
|
|
| Effort | Overtime reason composition and ranking | Donut + horizontal bar | Last 30 days if unspecified | Top 8 |
|
|
|
|
Top N must be explicit in every ranking plan. Default is Top 10. The first implementation should cap user-requested limits to a safe maximum, such as Top 20.
|
|
|
|
## Metric Result
|
|
|
|
Metric Result is the reusable output of the Metric Engine. Chart, report, insight, export, and future dashboard cards consume this result in parallel.
|
|
|
|
```ts
|
|
type 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;
|
|
};
|
|
```
|
|
|
|
## Evidence
|
|
|
|
Evidence is clickable data proof, not only visual chips.
|
|
|
|
```ts
|
|
type 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>;
|
|
};
|
|
};
|
|
```
|
|
|
|
Examples:
|
|
|
|
- `未关闭 Bug / 18 / Bug Domain / click → Bug list filtered by open statuses`
|
|
- `阻塞任务 / 6 / DevTask Domain / click → DevTask list filtered by blocked`
|
|
- `测试通过率 / 62% / TestCase Domain / click → test case detail list`
|
|
|
|
## Unified ChartSpec
|
|
|
|
ChartSpec is platform-owned and renderer-agnostic. It is not an ECharts option object.
|
|
|
|
```ts
|
|
type 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';
|
|
};
|
|
```
|
|
|
|
Frontend `ChartRenderer` converts Unified ChartSpec into ECharts options. This keeps the contract stable if the renderer changes later.
|
|
|
|
## Apple Vision Chart Design System
|
|
|
|
### Overall
|
|
|
|
- White or deep neutral background.
|
|
- Large whitespace and clear hierarchy.
|
|
- Large rounded cards, light borders, soft shadows, and translucent material.
|
|
- Content first; numbers and conclusions lead the page.
|
|
- No blue gradient dashboard, no dense big-screen layout, no rainbow metrics, no 3D shine.
|
|
|
|
### Number Cards
|
|
|
|
The number is the hero.
|
|
|
|
Structure:
|
|
|
|
```text
|
|
238
|
|
已完成需求
|
|
↑ 12%
|
|
较上周期
|
|
```
|
|
|
|
Rules:
|
|
|
|
- Big number, small label.
|
|
- Comparison line is secondary.
|
|
- Risk or negative trend may use orange/red; normal values use a restrained single accent color.
|
|
|
|
### Line Charts
|
|
|
|
Use Apple Stocks-like style:
|
|
|
|
- Smooth curve.
|
|
- Subtle area gradient.
|
|
- Minimal axes and grid.
|
|
- Highlight peaks, drops, or anomaly points automatically.
|
|
- Do not draw heavy traditional grid lines.
|
|
|
|
### Bar Charts
|
|
|
|
Use horizontal bars for ranking:
|
|
|
|
```text
|
|
研发 ████████
|
|
产品 ██████
|
|
测试 ████
|
|
```
|
|
|
|
Rules:
|
|
|
|
- Single color by default.
|
|
- Rounded bar caps.
|
|
- Soft entrance animation.
|
|
- Values aligned for scanning.
|
|
- Use Top N; do not render 100 members in one chart.
|
|
|
|
### Donut and Composition Charts
|
|
|
|
- Use only when part-to-whole composition matters.
|
|
- Limit slices to Top 8 plus "其他".
|
|
- Use restrained semantic colors. Avoid five-color decoration unless categories need separation.
|
|
|
|
### Motion
|
|
|
|
- Entrance animation is soft and short.
|
|
- Tooltip follows pointer naturally.
|
|
- Hover reveals detail without moving layout.
|
|
- No dramatic loading animation or distracting particle effects.
|
|
|
|
## Insight, Report, and Follow-Ups
|
|
|
|
### Insight Card
|
|
|
|
Insight Card comes before the chart. It is one concise conclusion, such as:
|
|
|
|
```text
|
|
产品部延期事项最多,占当前延期事项的 49%。
|
|
```
|
|
|
|
It should include:
|
|
|
|
- Main conclusion.
|
|
- Main metric value.
|
|
- Trend or comparison if available.
|
|
- Confidence level if semantic or data confidence is not high.
|
|
|
|
```ts
|
|
type 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';
|
|
};
|
|
```
|
|
|
|
### Report Structure
|
|
|
|
Reports use a fixed structure:
|
|
|
|
1. Summary
|
|
2. Key Findings
|
|
3. Evidence
|
|
4. Suggestions
|
|
5. Data Scope
|
|
|
|
AI may write the prose, but it must only use Metric Result data, Evidence, and Data Scope.
|
|
|
|
```ts
|
|
type AnalysisReport = {
|
|
summary: string;
|
|
keyFindings: string[];
|
|
evidence: EvidenceItem[];
|
|
suggestions: string[];
|
|
dataScope: {
|
|
timeDescription: string;
|
|
permissionDescription: string;
|
|
metricFormulaDescription: string;
|
|
generatedAt: string;
|
|
};
|
|
};
|
|
```
|
|
|
|
### Follow-Up Types
|
|
|
|
```ts
|
|
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';
|
|
};
|
|
```
|
|
|
|
First version follow-ups are read-only:
|
|
|
|
- Follow-up question: "为什么延期?"
|
|
- Drilldown: "查看负责人", "查看 Bug 明细", "切到版本维度"
|
|
- Export: "导出分析报告"
|
|
|
|
Business-mutating follow-ups such as creating meetings, assigning owners, or changing plans are excluded from the MVP. They require explicit user confirmation and domain API design in a later phase.
|
|
|
|
## Data Confidence
|
|
|
|
Data confidence is separate from semantic confidence.
|
|
|
|
Display levels:
|
|
|
|
- `sufficient`: enough rows, current data, reliable plan dates or status facts.
|
|
- `partial`: some missing dates, sparse records, or incomplete evidence.
|
|
- `insufficient`: no usable rows or too few rows for the requested comparison.
|
|
|
|
Examples that lower data confidence:
|
|
|
|
- No planned end dates.
|
|
- Missing work activities.
|
|
- No historical baseline for comparison.
|
|
- Small sample size.
|
|
- Current user only has partial scope.
|
|
|
|
## No Data Strategy
|
|
|
|
If there is no data, do not let AI invent an explanation.
|
|
|
|
Return a structured no-data result:
|
|
|
|
- State what was requested.
|
|
- State why no result can be computed.
|
|
- Show the applied scope and time range.
|
|
- Suggest valid alternatives.
|
|
|
|
Example:
|
|
|
|
```text
|
|
没有找到 2025 年测试通过率数据。
|
|
可以改看 2026 年、当前版本测试完成情况,或按项目查看已有测试用例。
|
|
```
|
|
|
|
## API Shape
|
|
|
|
Initial endpoint:
|
|
|
|
```text
|
|
POST /api/v1/ai/analysis
|
|
```
|
|
|
|
Request:
|
|
|
|
```ts
|
|
type AnalysisRequest = {
|
|
question: string;
|
|
context?: {
|
|
surface: 'ai_assistant' | 'product_detail' | 'project_detail' | 'version_detail';
|
|
productId?: string;
|
|
projectId?: string;
|
|
versionId?: string;
|
|
};
|
|
};
|
|
```
|
|
|
|
Response:
|
|
|
|
```ts
|
|
type AnalysisResponse =
|
|
| {
|
|
ok: true;
|
|
plan: AnalysisPlan;
|
|
metricResult: MetricResult;
|
|
insight: InsightCard;
|
|
chart: UnifiedChartSpec;
|
|
report: AnalysisReport;
|
|
followUps: FollowUp[];
|
|
}
|
|
| {
|
|
ok: false;
|
|
code:
|
|
| 'NO_PERMISSION'
|
|
| 'UNSUPPORTED_ANALYSIS'
|
|
| 'AMBIGUOUS_INTENT'
|
|
| 'NO_DATA'
|
|
| 'AI_UNAVAILABLE'
|
|
| 'INVALID_PLAN';
|
|
message: string;
|
|
clarificationOptions?: Array<{ label: string; prompt: string }>;
|
|
dataScope?: DataScope;
|
|
};
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
- `NO_PERMISSION`: user asked for a scope outside authorized data.
|
|
- `UNSUPPORTED_ANALYSIS`: metric or dimension is not in the catalog.
|
|
- `AMBIGUOUS_INTENT`: semantic confidence is too low and multiple interpretations are plausible.
|
|
- `NO_DATA`: plan is valid but no rows exist in scope.
|
|
- `AI_UNAVAILABLE`: AI Planning or AI report generation failed; templates and deterministic reports can still work when possible.
|
|
- `INVALID_PLAN`: AI proposed or user requested an invalid plan after validation.
|
|
|
|
Fallback order:
|
|
|
|
1. Template or deterministic strategy with deterministic report.
|
|
2. AI report over Metric Result when provider is available.
|
|
3. Deterministic report summary if AI is unavailable.
|
|
4. Structured error/no-data response.
|
|
|
|
## Testing Strategy
|
|
|
|
### Unit Tests
|
|
|
|
- Semantic Layer maps known phrases to expected concepts and confidence levels.
|
|
- Metric Catalog rejects unknown metrics, unsupported dimensions, unsupported analysis types, and deprecated metrics.
|
|
- Analysis Strategy chooses Template before Rule Composition before AI Planning.
|
|
- Rule Composition produces deterministic plans for examples such as delay reason trend.
|
|
- Analysis Plan Processor validates and normalizes time ranges, scope, Top N, dimensions, and metric versions.
|
|
- No Data Strategy returns structured no-data responses.
|
|
- ChartSpec Builder emits renderer-agnostic ChartSpec, not raw ECharts options.
|
|
- Evidence items include source domain and drilldown filters when available.
|
|
|
|
### Service Tests
|
|
|
|
- Normal member cannot query all-company management scope.
|
|
- Project Owner/Admin can query managed project scope.
|
|
- Version detail context restricts analysis to current version.
|
|
- Current-state risk queries do not use last 30 days by default.
|
|
- Trend/effort/throughput queries use last 30 days when no range is specified.
|
|
- Comparison queries use last 30 days versus previous 30 days when no baseline is specified.
|
|
|
|
### Frontend Tests
|
|
|
|
- AI Assistant renders Insight Card, chart, report, evidence, and follow-ups.
|
|
- Product/project/version context passes correct IDs to the analysis endpoint.
|
|
- ChartRenderer converts Unified ChartSpec to ECharts options through a single renderer boundary.
|
|
- Long labels and Top N bars do not overflow on desktop or mobile.
|
|
- No-data and no-permission states render as clear non-chart answers.
|
|
|
|
### Visual QA
|
|
|
|
- Verify Apple Vision rules on light and dark backgrounds.
|
|
- Verify line charts have smooth curves, area gradient, minimal axes, and anomaly markers.
|
|
- Verify horizontal bars are single-color, rounded, and animated softly.
|
|
- Verify number cards make the number the primary visual element.
|
|
|
|
## Documentation Updates
|
|
|
|
This design affects:
|
|
|
|
- `docs/architecture.md`: add Business Analysis Agent layer.
|
|
- `docs/decisions.md`: add decision for Semantic Layer, Analysis Strategy, Metric Catalog, and unified ChartSpec.
|
|
- `docs/workflow.md`: add business analysis workflow.
|
|
- `docs/roadmap.md`: add V3 Business Analysis Agent stage.
|
|
- `docs/agent-spec.md`: add Business Analysis Agent contract summary.
|