Files
invoice-master-poc-v2/docs/dashboard-design-spec.md
Yaojia Wang a564ac9d70 WIP
2026-02-01 18:51:54 +01:00

18 KiB

Dashboard Design Specification

Overview

Dashboard 是用户进入系统后的第一个页面,用于快速了解:

  • 数据标注质量和进度
  • 当前模型状态和性能
  • 系统最近发生的活动

目标用户:使用文档标注系统的客户,需要监控文档处理状态、标注质量和模型训练进度。


1. UI Layout

1.1 Overall Structure

+------------------------------------------------------------------+
|  Header: Logo + Navigation + User Menu                            |
+------------------------------------------------------------------+
|                                                                    |
|  Stats Cards Row (4 cards, equal width)                           |
|                                                                    |
|  +---------------------------+  +------------------------------+  |
|  | Data Quality Panel (50%)  |  | Active Model Panel (50%)     |  |
|  +---------------------------+  +------------------------------+  |
|                                                                    |
|  +--------------------------------------------------------------+  |
|  | Recent Activity Panel (full width)                            |  |
|  +--------------------------------------------------------------+  |
|                                                                    |
|  +--------------------------------------------------------------+  |
|  | System Status Bar (full width)                                |  |
|  +--------------------------------------------------------------+  |
+------------------------------------------------------------------+

1.2 Responsive Breakpoints

Breakpoint Layout
Desktop (>1200px) 4 cards row, 2-column panels
Tablet (768-1200px) 2x2 cards, 2-column panels
Mobile (<768px) 1 card per row, stacked panels

2. Component Specifications

2.1 Stats Cards Row

4 个等宽卡片,显示核心统计数据。

+-------------+ +-------------+ +-------------+ +-------------+
|   [icon]    | |   [icon]    | |   [icon]    | |   [icon]    |
|     38      | |     25      | |      8      | |      5      |
| Total Docs  | |  Complete   | | Incomplete  | |   Pending   |
+-------------+ +-------------+ +-------------+ +-------------+
Card Icon Value Label Color Click Action
Total Documents FileText total_documents "Total Documents" Gray Navigate to Documents page
Complete CheckCircle annotation_complete "Complete" Green Navigate to Documents (filter: complete)
Incomplete AlertCircle annotation_incomplete "Incomplete" Orange Navigate to Documents (filter: incomplete)
Pending Clock pending "Pending" Blue Navigate to Documents (filter: pending)

Card Design:

  • Background: White with subtle border
  • Icon: 24px, positioned top-left
  • Value: 32px bold font
  • Label: 14px muted color
  • Hover: Slight shadow elevation
  • Padding: 16px

2.2 Data Quality Panel

左侧面板,显示标注完整度和质量指标。

+---------------------------+
| DATA QUALITY              |
| +-----------+             |
| |           |             |
| |   78%     |  Annotation |
| |           |  Complete   |
| +-----------+             |
|                           |
| Complete: 25              |
| Incomplete: 8             |
| Pending: 5                |
|                           |
| [View Incomplete Docs]    |
+---------------------------+

Components:

Element Spec
Title "DATA QUALITY", 14px uppercase, muted
Progress Ring 120px diameter, stroke width 12px
Percentage 36px bold, centered in ring
Label "Annotation Complete", 14px, below ring
Stats List 14px, icon + label + value per row
Action Button Text button, primary color

Progress Ring Colors:

  • Complete portion: Green (#22C55E)
  • Remaining: Gray (#E5E7EB)

Completeness Calculation:

completeness_rate = annotation_complete / (annotation_complete + annotation_incomplete) * 100

2.3 Active Model Panel

右侧面板,显示当前生产模型信息。

+-------------------------------+
| ACTIVE MODEL                  |
|                               |
| v1.2.0 - Invoice Model        |
| ----------------------------- |
|                               |
| mAP        Precision  Recall  |
| 95.1%      94%       92%      |
|                               |
| Activated: 2024-01-20         |
| Documents: 500                |
|                               |
| [Training] Run-2024-02 [====] |
+-------------------------------+

Components:

Element Spec
Title "ACTIVE MODEL", 14px uppercase, muted
Version + Name 18px bold (version) + 16px regular (name)
Divider 1px border, full width
Metrics Row 3 columns, equal width
Metric Value 24px bold
Metric Label 12px muted, below value
Info Rows 14px, label: value format
Training Indicator Shows when training is running

Metric Colors:

  • mAP >= 90%: Green
  • mAP 80-90%: Yellow
  • mAP < 80%: Red

Empty State (No Active Model):

+-------------------------------+
| ACTIVE MODEL                  |
|                               |
|    [icon: Model]              |
|    No Active Model            |
|                               |
|    Train and activate a       |
|    model to see stats here    |
|                               |
|    [Go to Training]           |
+-------------------------------+

Training In Progress:

| Training: Run-2024-02         |
| [=========>          ] 45%    |
| Started 2 hours ago           |

2.4 Recent Activity Panel

全宽面板,显示最近 10 条系统活动。

+--------------------------------------------------------------+
| RECENT ACTIVITY                                     [See All] |
+--------------------------------------------------------------+
| [rocket] Activated model v1.2.0                    2 hours ago|
| [check]  Training complete: Run-2024-01, mAP 95.1%   yesterday|
| [edit]   Modified INV-001.pdf invoice_number         yesterday|
| [doc]    Uploaded INV-005.pdf                        2 days ago|
| [doc]    Uploaded INV-004.pdf                        2 days ago|
| [x]      Training failed: Run-2024-00                3 days ago|
+--------------------------------------------------------------+

Activity Item Layout:

[Icon] [Description]                              [Timestamp]
Element Spec
Icon 16px, color based on type
Description 14px, truncate if too long
Timestamp 12px muted, right-aligned
Row Height 40px
Hover Background highlight

Activity Types and Icons:

Type Icon Color Description Format
document_uploaded FileText Blue "Uploaded {filename}"
annotation_modified Edit Orange "Modified {filename} {field_name}"
training_completed CheckCircle Green "Training complete: {task_name}, mAP {mAP}%"
training_failed XCircle Red "Training failed: {task_name}"
model_activated Rocket Purple "Activated model {version}"

Timestamp Formatting:

  • < 1 minute: "just now"
  • < 1 hour: "{n} minutes ago"
  • < 24 hours: "{n} hours ago"
  • < 7 days: "yesterday" / "{n} days ago"
  • = 7 days: "Jan 15" (date format)

Empty State:

+--------------------------------------------------------------+
| RECENT ACTIVITY                                               |
|                                                              |
|              [icon: Activity]                                 |
|              No recent activity                              |
|                                                              |
|    Start by uploading documents or creating training jobs    |
+--------------------------------------------------------------+

2.5 System Status Bar

底部状态栏,显示系统健康状态。

+--------------------------------------------------------------+
| Backend API: [*] Online   Database: [*] Connected   GPU: [*] Available |
+--------------------------------------------------------------+
Status Icon Color
Online/Connected/Available Filled circle Green
Degraded/Slow Filled circle Yellow
Offline/Error/Unavailable Filled circle Red

3. API Endpoints

3.1 Dashboard Statistics

GET /api/v1/admin/dashboard/stats

Response:

{
  "total_documents": 38,
  "annotation_complete": 25,
  "annotation_incomplete": 8,
  "pending": 5,
  "completeness_rate": 75.76
}

Calculation Logic:

# annotation_complete: labeled documents with core fields
SELECT COUNT(*) FROM admin_documents d
WHERE d.status = 'labeled'
AND EXISTS (
    SELECT 1 FROM admin_annotations a
    WHERE a.document_id = d.document_id
    AND a.class_id IN (0, 3)  -- invoice_number OR ocr_number
)
AND EXISTS (
    SELECT 1 FROM admin_annotations a
    WHERE a.document_id = d.document_id
    AND a.class_id IN (4, 5)  -- bankgiro OR plusgiro
)

# annotation_incomplete: labeled but missing core fields
SELECT COUNT(*) FROM admin_documents d
WHERE d.status = 'labeled'
AND NOT (/* above conditions */)

# pending: pending + auto_labeling
SELECT COUNT(*) FROM admin_documents
WHERE status IN ('pending', 'auto_labeling')

3.2 Active Model Info

GET /api/v1/admin/dashboard/active-model

Response (with active model):

{
  "model": {
    "version_id": "uuid",
    "version": "1.2.0",
    "name": "Invoice Model",
    "metrics_mAP": 0.951,
    "metrics_precision": 0.94,
    "metrics_recall": 0.92,
    "document_count": 500,
    "activated_at": "2024-01-20T15:00:00Z"
  },
  "running_training": {
    "task_id": "uuid",
    "name": "Run-2024-02",
    "status": "running",
    "started_at": "2024-01-25T10:00:00Z",
    "progress": 45
  }
}

Response (no active model):

{
  "model": null,
  "running_training": null
}

3.3 Recent Activity

GET /api/v1/admin/dashboard/activity?limit=10

Response:

{
  "activities": [
    {
      "type": "model_activated",
      "description": "Activated model v1.2.0",
      "timestamp": "2024-01-25T12:00:00Z",
      "metadata": {
        "version_id": "uuid",
        "version": "1.2.0"
      }
    },
    {
      "type": "training_completed",
      "description": "Training complete: Run-2024-01, mAP 95.1%",
      "timestamp": "2024-01-24T18:30:00Z",
      "metadata": {
        "task_id": "uuid",
        "task_name": "Run-2024-01",
        "mAP": 0.951
      }
    }
  ]
}

Activity Aggregation Query:

-- Union all activity sources, ordered by timestamp DESC, limit 10
(
  SELECT 'document_uploaded' as type,
         filename as entity_name,
         created_at as timestamp,
         document_id as entity_id
  FROM admin_documents
  ORDER BY created_at DESC
  LIMIT 10
)
UNION ALL
(
  SELECT 'annotation_modified' as type,
         -- join to get filename and field name
         ...
  FROM annotation_history
  ORDER BY created_at DESC
  LIMIT 10
)
UNION ALL
(
  SELECT CASE WHEN status = 'completed' THEN 'training_completed'
              WHEN status = 'failed' THEN 'training_failed' END as type,
         name as entity_name,
         completed_at as timestamp,
         task_id as entity_id
  FROM training_tasks
  WHERE status IN ('completed', 'failed')
  ORDER BY completed_at DESC
  LIMIT 10
)
UNION ALL
(
  SELECT 'model_activated' as type,
         version as entity_name,
         activated_at as timestamp,
         version_id as entity_id
  FROM model_versions
  WHERE activated_at IS NOT NULL
  ORDER BY activated_at DESC
  LIMIT 10
)
ORDER BY timestamp DESC
LIMIT 10

4. UX Interactions

4.1 Loading States

Component Loading State
Stats Cards Skeleton placeholder (gray boxes)
Data Quality Ring Skeleton circle
Active Model Skeleton lines
Recent Activity Skeleton list items (5 rows)

Loading Duration Thresholds:

  • < 300ms: No loading state shown
  • 300ms - 3s: Show skeleton
  • 3s: Show skeleton + "Taking longer than expected" message

4.2 Error States

Error Type Display
API Error Toast notification + retry button in affected panel
Network Error Full page overlay with retry option
Partial Failure Show available data, error badge on failed sections

4.3 Refresh Behavior

Trigger Behavior
Page Load Fetch all data
Manual Refresh Button in header, refetch all
Auto Refresh Every 30 seconds for activity panel
Focus Return Refetch if page was hidden > 5 minutes

4.4 Click Actions

Element Action
Total Documents card Navigate to /documents
Complete card Navigate to /documents?filter=complete
Incomplete card Navigate to /documents?filter=incomplete
Pending card Navigate to /documents?filter=pending
"View Incomplete Docs" button Navigate to /documents?filter=incomplete
Activity item Navigate to related entity
"Go to Training" button Navigate to /training
Active Model version Navigate to /models/{version_id}

4.5 Tooltips

Element Tooltip Content
Completeness % "25 of 33 labeled documents have complete annotations"
mAP metric "Mean Average Precision at IoU 0.5"
Precision metric "Proportion of correct positive predictions"
Recall metric "Proportion of actual positives correctly identified"
Incomplete count "Documents labeled but missing invoice_number/ocr_number or bankgiro/plusgiro"

5. Data Model

5.1 TypeScript Types

// Dashboard Stats
interface DashboardStats {
  total_documents: number;
  annotation_complete: number;
  annotation_incomplete: number;
  pending: number;
  completeness_rate: number;
}

// Active Model
interface ActiveModelInfo {
  model: ModelVersion | null;
  running_training: RunningTraining | null;
}

interface ModelVersion {
  version_id: string;
  version: string;
  name: string;
  metrics_mAP: number;
  metrics_precision: number;
  metrics_recall: number;
  document_count: number;
  activated_at: string;
}

interface RunningTraining {
  task_id: string;
  name: string;
  status: 'running';
  started_at: string;
  progress: number;
}

// Activity
interface Activity {
  type: ActivityType;
  description: string;
  timestamp: string;
  metadata: Record<string, unknown>;
}

type ActivityType =
  | 'document_uploaded'
  | 'annotation_modified'
  | 'training_completed'
  | 'training_failed'
  | 'model_activated';

// Activity Response
interface ActivityResponse {
  activities: Activity[];
}

5.2 React Query Hooks

// useDashboardStats
const useDashboardStats = () => {
  return useQuery({
    queryKey: ['dashboard', 'stats'],
    queryFn: () => api.get('/admin/dashboard/stats'),
    refetchInterval: 30000, // 30 seconds
  });
};

// useActiveModel
const useActiveModel = () => {
  return useQuery({
    queryKey: ['dashboard', 'active-model'],
    queryFn: () => api.get('/admin/dashboard/active-model'),
    refetchInterval: 60000, // 1 minute
  });
};

// useRecentActivity
const useRecentActivity = (limit = 10) => {
  return useQuery({
    queryKey: ['dashboard', 'activity', limit],
    queryFn: () => api.get(`/admin/dashboard/activity?limit=${limit}`),
    refetchInterval: 30000,
  });
};

6. Annotation Completeness Definition

6.1 Core Fields

A document is complete when it has annotations for:

Requirement Fields Logic
Identifier invoice_number (class_id=0) OR ocr_number (class_id=3) At least one
Payment Account bankgiro (class_id=4) OR plusgiro (class_id=5) At least one

6.2 Status Categories

Category Criteria
Complete status=labeled AND has identifier AND has payment account
Incomplete status=labeled AND (missing identifier OR missing payment account)
Pending status IN (pending, auto_labeling)

6.3 Filter Implementation

-- Complete documents
WHERE status = 'labeled'
AND document_id IN (
  SELECT document_id FROM admin_annotations WHERE class_id IN (0, 3)
)
AND document_id IN (
  SELECT document_id FROM admin_annotations WHERE class_id IN (4, 5)
)

-- Incomplete documents
WHERE status = 'labeled'
AND (
  document_id NOT IN (
    SELECT document_id FROM admin_annotations WHERE class_id IN (0, 3)
  )
  OR document_id NOT IN (
    SELECT document_id FROM admin_annotations WHERE class_id IN (4, 5)
  )
)

7. Implementation Checklist

Backend

  • Create /api/v1/admin/dashboard/stats endpoint
  • Create /api/v1/admin/dashboard/active-model endpoint
  • Create /api/v1/admin/dashboard/activity endpoint
  • Add completeness calculation logic to document repository
  • Implement activity aggregation query

Frontend

  • Create DashboardOverview component
  • Create StatsCard component
  • Create DataQualityPanel component with progress ring
  • Create ActiveModelPanel component
  • Create RecentActivityPanel component
  • Create SystemStatusBar component
  • Add React Query hooks for dashboard data
  • Implement loading skeletons
  • Implement error states
  • Add navigation actions
  • Add tooltips

Testing

  • Unit tests for completeness calculation
  • Unit tests for activity aggregation
  • Integration tests for dashboard endpoints
  • E2E tests for dashboard interactions