📋 概述

本文档详细分析VoiceHelper系统的数据结构设计、API接口规范、数据流转机制和最佳实践。涵盖类型定义、接口设计、数据验证和错误处理等关键方面。

🏗️ 核心数据结构设计

用户与认证数据结构

classDiagram
    class User {
        +string user_id
        +string username
        +string email
        +string nickname
        +string avatar_url
        +UserStatus status
        +UserPreferences preferences
        +datetime created_at
        +datetime updated_at
        +datetime last_login
        +validateEmail() boolean
        +updateProfile(data: UserProfile) void
        +hasPermission(permission: string) boolean
    }
    
    class UserPreferences {
        +string language
        +ThemeMode theme
        +VoiceSettings voice_settings
        +NotificationSettings notifications
        +PrivacySettings privacy
        +updateVoiceSetting(key: string, value: any) void
        +resetToDefaults() void
    }
    
    class VoiceSettings {
        +string preferred_voice
        +float speech_rate
        +float volume
        +boolean auto_play
        +boolean voice_activation
        +AudioQuality audio_quality
        +validateSettings() ValidationResult
    }
    
    class AuthToken {
        +string token
        +string refresh_token
        +datetime expires_at
        +datetime refresh_expires_at
        +string[] scopes
        +boolean is_valid
        +refresh() AuthToken
        +revoke() void
    }
    
    User ||--|| UserPreferences : contains
    UserPreferences ||--|| VoiceSettings : includes
    User ||--o{ AuthToken : has_multiple
    
    class UserStatus {
        <<enumeration>>
        ACTIVE
        INACTIVE
        BANNED
        PENDING_VERIFICATION
    }
    
    class ThemeMode {
        <<enumeration>>
        LIGHT
        DARK
        AUTO
    }

TypeScript接口定义

/**
 * 用户数据结构 - 系统用户的完整信息模型
 */
export interface User {
  /** 用户唯一标识符,UUID格式 */
  user_id: string;
  
  /** 用户名,用于登录,3-20字符,唯一 */
  username: string;
  
  /** 邮箱地址,用于通知和密码重置 */
  email: string;
  
  /** 显示昵称,可包含中文和特殊字符 */
  nickname?: string;
  
  /** 头像URL,支持多种图片格式 */
  avatar_url?: string;
  
  /** 账户状态枚举 */
  status: UserStatus;
  
  /** 用户偏好设置 */
  preferences: UserPreferences;
  
  /** 账户创建时间,ISO 8601格式 */
  created_at: string;
  
  /** 最后更新时间,ISO 8601格式 */
  updated_at: string;
  
  /** 最后登录时间,可为空 */
  last_login?: string;
  
  /** 用户角色列表,用于权限控制 */
  roles: string[];
  
  /** 租户ID,支持多租户架构 */
  tenant_id?: string;
}

/**
 * 用户偏好设置 - 个性化配置选项
 */
export interface UserPreferences {
  /** 界面语言代码,遵循BCP 47标准 */
  language: string;
  
  /** 主题模式选择 */
  theme: 'light' | 'dark' | 'auto';
  
  /** 语音交互设置 */
  voice_settings: VoiceSettings;
  
  /** 通知设置 */
  notification_settings: NotificationSettings;
  
  /** 隐私设置 */
  privacy_settings: PrivacySettings;
  
  /** 可访问性设置 */
  accessibility: AccessibilitySettings;
  
  /** 自定义字段,支持扩展 */
  custom_fields?: Record<string, any>;
}

/**
 * 语音设置 - 语音交互相关配置
 */
export interface VoiceSettings {
  /** 偏好的语音ID,如 'zh-CN-XiaoxiaoNeural' */
  preferred_voice: string;
  
  /** 语音播放速率,范围 0.5-2.0 */
  speech_rate: number;
  
  /** 音量大小,范围 0.0-1.0 */
  volume: number;
  
  /** 是否自动播放AI回复 */
  auto_play: boolean;
  
  /** 是否启用语音激活(免按键) */
  voice_activation: boolean;
  
  /** 音频质量设置 */
  audio_quality: 'low' | 'medium' | 'high';
  
  /** 噪声抑制级别 */
  noise_suppression: 'off' | 'low' | 'medium' | 'high';
  
  /** 回声消除开关 */
  echo_cancellation: boolean;
  
  /** 自动增益控制 */
  auto_gain_control: boolean;
}

/**
 * JWT认证令牌结构
 */
export interface AuthToken {
  /** 访问令牌,用于API认证 */
  access_token: string;
  
  /** 刷新令牌,用于获取新的访问令牌 */
  refresh_token: string;
  
  /** 令牌类型,通常为 'Bearer' */
  token_type: string;
  
  /** 访问令牌过期时间(秒) */
  expires_in: number;
  
  /** 刷新令牌过期时间(秒) */
  refresh_expires_in: number;
  
  /** 令牌权限范围 */
  scope: string[];
  
  /** 令牌签发时间戳 */
  issued_at: number;
  
  /** 签发者标识 */
  issuer: string;
}

对话与消息数据结构

classDiagram
    class Conversation {
        +string conversation_id
        +string user_id
        +string title
        +ConversationStatus status
        +datetime created_at
        +datetime updated_at
        +int message_count
        +ConversationMetadata metadata
        +Message[] messages
        +addMessage(message: Message) void
        +updateStatus(status: ConversationStatus) void
        +getLatestMessage() Message
        +calculateDuration() number
    }
    
    class Message {
        +string message_id
        +string conversation_id
        +MessageRole role
        +string content
        +ContentType content_type
        +datetime created_at
        +MessageMetadata metadata
        +Attachment[] attachments
        +ToolCall[] tool_calls
        +Reference[] references
        +validateContent() boolean
        +extractEntities() Entity[]
        +calculateTokenCount() number
    }
    
    class MessageMetadata {
        +number response_time_ms
        +string model_used
        +TokenCount token_count
        +number confidence_score
        +EmotionAnalysis emotion
        +IntentAnalysis intent
        +string[] tags
        +updateMetrics(metrics: any) void
    }
    
    class Reference {
        +string reference_id
        +ReferenceType type
        +string title
        +string content
        +string url
        +number relevance_score
        +ReferenceMetadata metadata
        +validateReference() boolean
    }
    
    class ToolCall {
        +string tool_call_id
        +string tool_name
        +Record parameters
        +ToolCallStatus status
        +ToolResult result
        +datetime created_at
        +execute() Promise~ToolResult~
        +cancel() void
    }
    
    Conversation ||--o{ Message : contains
    Message ||--|| MessageMetadata : has
    Message ||--o{ Reference : references
    Message ||--o{ ToolCall : triggers
    
    class MessageRole {
        <<enumeration>>
        USER
        ASSISTANT
        SYSTEM
        TOOL
    }
    
    class ContentType {
        <<enumeration>>
        TEXT
        AUDIO
        IMAGE
        FILE
        TOOL_CALL
        TOOL_RESULT
    }

TypeScript接口定义

/**
 * 对话数据结构 - 用户与AI的完整会话记录
 */
export interface Conversation {
  /** 对话唯一标识符 */
  conversation_id: string;
  
  /** 对话所属用户ID */
  user_id: string;
  
  /** 对话标题,可自动生成或用户设定 */
  title?: string;
  
  /** 对话状态 */
  status: 'active' | 'ended' | 'archived';
  
  /** 对话创建时间 */
  created_at: string;
  
  /** 对话最后更新时间 */
  updated_at: string;
  
  /** 对话结束时间,可为空 */
  ended_at?: string;
  
  /** 消息总数统计 */
  message_count: number;
  
  /** 对话元数据 */
  metadata: ConversationMetadata;
  
  /** 消息列表(可选,按需加载) */
  messages?: Message[];
}

/**
 * 对话元数据 - 对话的附加信息和统计
 */
export interface ConversationMetadata {
  /** 标签列表,用于分类和搜索 */
  tags?: string[];
  
  /** 对话分类 */
  category?: string;
  
  /** 优先级标记 */
  priority?: 'low' | 'normal' | 'high';
  
  /** 对话总时长(毫秒) */
  total_duration_ms?: number;
  
  /** 平均响应时间(毫秒) */
  avg_response_time_ms?: number;
  
  /** 使用的AI模型列表 */
  models_used?: string[];
  
  /** 语言代码 */
  language?: string;
  
  /** 是否包含语音交互 */
  has_voice_interaction?: boolean;
  
  /** 客户端类型 */
  client_type?: 'web' | 'mobile' | 'api' | 'miniprogram';
  
  /** 自定义字段 */
  custom_fields?: Record<string, any>;
}

/**
 * 消息数据结构 - 对话中的单条消息
 */
export interface Message {
  /** 消息唯一标识符 */
  message_id: string;
  
  /** 所属对话ID */
  conversation_id: string;
  
  /** 发送者用户ID,AI消息可为空 */
  user_id?: string;
  
  /** 消息角色 */
  role: 'user' | 'assistant' | 'system' | 'tool';
  
  /** 消息内容主体 */
  content: string;
  
  /** 内容类型 */
  content_type: 'text' | 'audio' | 'image' | 'file' | 'tool_call' | 'tool_result';
  
  /** 消息创建时间 */
  created_at: string;
  
  /** 消息元数据 */
  metadata?: MessageMetadata;
  
  /** 附件列表 */
  attachments?: Attachment[];
  
  /** 工具调用列表 */
  tool_calls?: ToolCall[];
  
  /** 引用资料列表 */
  references?: Reference[];
  
  /** 消息状态标记 */
  status?: 'sending' | 'sent' | 'delivered' | 'failed';
  
  /** 是否正在流式传输 */
  is_streaming?: boolean;
}

/**
 * 消息元数据 - 消息的性能指标和分析结果
 */
export interface MessageMetadata {
  /** 响应时间(毫秒) */
  response_time_ms?: number;
  
  /** 使用的AI模型 */
  model_used?: string;
  
  /** Token使用统计 */
  token_count?: {
    input: number;
    output: number;
    total: number;
  };
  
  /** AI回复的置信度分数 */
  confidence_score?: number;
  
  /** 情感分析结果 */
  emotion?: EmotionAnalysis;
  
  /** 意图识别结果 */
  intent?: IntentAnalysis;
  
  /** 语言检测结果 */
  detected_language?: string;
  
  /** 内容安全检查结果 */
  content_safety?: ContentSafetyResult;
  
  /** 消息来源信息 */
  source?: {
    client_type: string;
    client_version: string;
    ip_address?: string;
    user_agent?: string;
  };
}

/**
 * 引用资料结构 - RAG检索到的参考文档
 */
export interface Reference {
  /** 引用唯一标识符 */
  reference_id?: string;
  
  /** 引用类型 */
  type: 'document' | 'url' | 'conversation' | 'tool_result' | 'knowledge_graph';
  
  /** 文档或资源ID */
  id: string;
  
  /** 引用标题 */
  title?: string;
  
  /** 引用内容摘要 */
  content?: string;
  
  /** 引用URL链接 */
  url?: string;
  
  /** 引用来源 */
  source?: string;
  
  /** 相关性分数,0-1范围 */
  relevance_score?: number;
  
  /** 引用在原文中的位置 */
  position?: {
    start_index: number;
    end_index: number;
    page_number?: number;
    section?: string;
  };
  
  /** 引用元数据 */
  metadata?: Record<string, any>;
}

语音交互数据结构

classDiagram
    class VoiceSession {
        +string session_id
        +string user_id
        +string conversation_id
        +SessionStatus status
        +datetime created_at
        +datetime ended_at
        +VoiceSessionSettings settings
        +VoiceMetrics metrics
        +AudioChunk[] audio_chunks
        +startSession() void
        +endSession() void
        +updateMetrics(data: any) void
        +getTranscriptHistory() Transcript[]
    }
    
    class VoiceSessionSettings {
        +string language
        +string voice_id
        +int sample_rate
        +int channels
        +AudioFormat format
        +boolean vad_enabled
        +boolean noise_suppression
        +boolean echo_cancellation
        +validateSettings() boolean
        +optimizeForDevice() VoiceSessionSettings
    }
    
    class AudioChunk {
        +string chunk_id
        +string session_id
        +int sequence
        +ArrayBuffer data
        +long timestamp_ms
        +int duration_ms
        +boolean is_final
        +AudioQualityMetrics quality
        +process() ProcessedAudio
    }
    
    class TranscriptionResult {
        +string text
        +float confidence
        +string language
        +boolean is_final
        +TranscriptionAlternative[] alternatives
        +WordTimestamp[] word_timestamps
        +validateResult() boolean
        +getBestAlternative() string
    }
    
    class VoiceMetrics {
        +long total_duration_ms
        +long speech_duration_ms
        +long silence_duration_ms
        +int interruption_count
        +float average_latency_ms
        +float audio_quality_score
        +int packet_loss_count
        +calculateOverallScore() float
    }
    
    VoiceSession ||--|| VoiceSessionSettings : configured_with
    VoiceSession ||--o{ AudioChunk : contains
    VoiceSession ||--|| VoiceMetrics : tracks
    AudioChunk ||--|| TranscriptionResult : produces
    
    class SessionStatus {
        <<enumeration>>
        INITIALIZING
        ACTIVE
        PAUSED
        ENDED
        ERROR
    }
    
    class AudioFormat {
        <<enumeration>>
        PCM
        OPUS
        MP3
        WAV
        WEBM
    }

TypeScript接口定义

/**
 * 语音会话数据结构 - 实时语音交互的完整记录
 */
export interface VoiceSession {
  /** 会话唯一标识符 */
  session_id: string;
  
  /** 用户ID */
  user_id: string;
  
  /** 关联的对话ID,可选 */
  conversation_id?: string;
  
  /** 会话状态 */
  status: 'initializing' | 'active' | 'paused' | 'ended' | 'error';
  
  /** 会话创建时间 */
  created_at: string;
  
  /** 会话结束时间,可为空 */
  ended_at?: string;
  
  /** 语音会话设置 */
  settings: VoiceSessionSettings;
  
  /** 性能指标 */
  metrics?: VoiceMetrics;
  
  /** 转录历史记录 */
  transcripts?: TranscriptionRecord[];
  
  /** 错误信息,如果有的话 */
  error?: {
    code: string;
    message: string;
    timestamp: string;
  };
}

/**
 * 语音会话设置 - 音频处理和识别的配置参数
 */
export interface VoiceSessionSettings {
  /** 语言代码,如 'zh-CN' */
  language: string;
  
  /** 语音合成的声音ID */
  voice_id: string;
  
  /** 音频采样率,推荐16000Hz */
  sample_rate: number;
  
  /** 声道数,通常为1(单声道) */
  channels: number;
  
  /** 音频格式 */
  format: 'pcm' | 'opus' | 'mp3' | 'wav' | 'webm';
  
  /** 是否启用语音活动检测 */
  vad_enabled: boolean;
  
  /** 是否启用噪声抑制 */
  noise_suppression: boolean;
  
  /** 是否启用回声消除 */
  echo_cancellation: boolean;
  
  /** 自动增益控制 */
  auto_gain_control: boolean;
  
  /** 音频缓冲区大小(毫秒) */
  buffer_size_ms: number;
  
  /** 最小音频块大小(字节) */
  min_chunk_size: number;
  
  /** 最大音频块大小(字节) */
  max_chunk_size: number;
  
  /** 静音检测阈值(dB) */
  silence_threshold: number;
  
  /** 端点检测超时(毫秒) */
  endpoint_timeout_ms: number;
}

/**
 * 音频数据块 - 实时音频流的基本单元
 */
export interface AudioChunk {
  /** 音频块唯一标识符 */
  chunk_id: string;
  
  /** 所属会话ID */
  session_id: string;
  
  /** 序列号,保证顺序 */
  sequence: number;
  
  /** 音频二进制数据或Base64编码 */
  data: ArrayBuffer | string;
  
  /** 时间戳(毫秒) */
  timestamp_ms: number;
  
  /** 音频时长(毫秒) */
  duration_ms: number;
  
  /** 是否为最终音频块 */
  is_final: boolean;
  
  /** 音频质量指标 */
  quality_metrics?: {
    volume_level: number;
    signal_to_noise_ratio: number;
    clipping_detected: boolean;
  };
}

/**
 * 语音识别结果 - ASR系统的输出结果
 */
export interface TranscriptionResult {
  /** 识别出的文本内容 */
  text: string;
  
  /** 识别置信度,0-1范围 */
  confidence: number;
  
  /** 检测到的语言代码 */
  language: string;
  
  /** 是否为最终结果 */
  is_final: boolean;
  
  /** 备选识别结果 */
  alternatives?: Array<{
    text: string;
    confidence: number;
  }>;
  
  /** 词级时间戳 */
  word_timestamps?: Array<{
    word: string;
    start_time_ms: number;
    end_time_ms: number;
    confidence: number;
  }>;
  
  /** 说话人信息(如果支持) */
  speaker_info?: {
    speaker_id: string;
    gender: 'male' | 'female' | 'unknown';
    age_group: 'child' | 'adult' | 'elderly' | 'unknown';
  };
}

/**
 * 语音性能指标 - 语音交互质量的量化评估
 */
export interface VoiceMetrics {
  /** 会话总时长(毫秒) */
  total_duration_ms: number;
  
  /** 有效语音时长(毫秒) */
  speech_duration_ms: number;
  
  /** 静音时长(毫秒) */
  silence_duration_ms: number;
  
  /** 中断次数统计 */
  interruption_count: number;
  
  /** 平均延迟时间(毫秒) */
  average_latency_ms: number;
  
  /** 音频质量评分,0-1范围 */
  audio_quality_score: number;
  
  /** ASR性能指标 */
  asr_metrics: {
    recognition_accuracy: number;
    average_confidence: number;
    word_error_rate: number;
    processing_time_ms: number;
  };
  
  /** TTS性能指标 */
  tts_metrics: {
    synthesis_latency_ms: number;
    audio_quality: number;
    naturalness_score: number;
    pronunciation_accuracy: number;
  };
  
  /** 网络性能指标 */
  network_metrics: {
    packet_loss_rate: number;
    average_rtt_ms: number;
    bandwidth_utilization: number;
    connection_stability: number;
  };
}

🌐 API接口设计规范

RESTful API设计原则

graph TB
    subgraph "API设计层次"
        A[RESTful API设计原则]
        A --> B[资源导向设计]
        A --> C[HTTP动词语义]
        A --> D[统一响应格式]
        A --> E[版本控制策略]
        
        B --> B1[名词复数形式]
        B --> B2[层级资源路径]
        B --> B3[查询参数过滤]
        
        C --> C1[GET - 查询]
        C --> C2[POST - 创建]
        C --> C3[PUT - 更新]
        C --> C4[DELETE - 删除]
        
        D --> D1[标准状态码]
        D --> D2[错误消息格式]
        D --> D3[分页元数据]
        
        E --> E1[URL路径版本]
        E --> E2[Header版本]
        E --> E3[向后兼容]
    end
    
    style A fill:#e3f2fd
    style B fill:#f3e5f5
    style C fill:#e8f5e8
    style D fill:#fff3e0

核心API接口定义

1. 用户认证API

/**
 * 用户认证API接口定义
 */
export interface AuthAPI {
  /** 用户登录 */
  '/api/v1/auth/login': {
    POST: {
      body: {
        /** 用户名或邮箱 */
        username: string;
        /** 密码,需要客户端加密 */
        password: string;
        /** 验证码(可选) */
        captcha?: string;
        /** 记住登录状态 */
        remember_me?: boolean;
      };
      response: BaseResponse<{
        /** 用户信息 */
        user: User;
        /** 访问令牌 */
        access_token: string;
        /** 刷新令牌 */
        refresh_token: string;
        /** 过期时间(秒) */
        expires_in: number;
      }>;
    };
  };

  /** 刷新令牌 */
  '/api/v1/auth/refresh': {
    POST: {
      body: {
        /** 刷新令牌 */
        refresh_token: string;
      };
      response: BaseResponse<{
        /** 新的访问令牌 */
        access_token: string;
        /** 新的刷新令牌 */
        refresh_token: string;
        /** 过期时间 */
        expires_in: number;
      }>;
    };
  };

  /** 用户注销 */
  '/api/v1/auth/logout': {
    POST: {
      headers: {
        /** 认证令牌 */
        'Authorization': `Bearer ${string}`;
      };
      response: BaseResponse<{
        /** 注销消息 */
        message: string;
      }>;
    };
  };

  /** 获取当前用户信息 */
  '/api/v1/auth/me': {
    GET: {
      headers: {
        'Authorization': `Bearer ${string}`;
      };
      response: BaseResponse<User>;
    };
  };
}

2. 对话管理API

/**
 * 对话管理API接口定义
 */
export interface ConversationAPI {
  /** 获取对话列表 */
  '/api/v1/conversations': {
    GET: {
      headers: {
        'Authorization': `Bearer ${string}`;
      };
      params?: {
        /** 页码,从1开始 */
        page?: number;
        /** 每页大小,默认20 */
        page_size?: number;
        /** 状态过滤 */
        status?: 'active' | 'ended' | 'archived';
        /** 关键词搜索 */
        search?: string;
        /** 排序字段 */
        sort_by?: 'created_at' | 'updated_at' | 'message_count';
        /** 排序方向 */
        sort_order?: 'asc' | 'desc';
      };
      response: PaginatedResponse<Conversation>;
    };

    POST: {
      headers: {
        'Authorization': `Bearer ${string}`;
      };
      body: {
        /** 对话标题,可选 */
        title?: string;
        /** 初始消息,可选 */
        initial_message?: string;
        /** 对话类型 */
        type?: 'text' | 'voice' | 'mixed';
        /** 元数据 */
        metadata?: ConversationMetadata;
      };
      response: BaseResponse<Conversation>;
    };
  };

  /** 获取特定对话 */
  '/api/v1/conversations/{conversation_id}': {
    GET: {
      headers: {
        'Authorization': `Bearer ${string}`;
      };
      params: {
        conversation_id: string;
      };
      query?: {
        /** 是否包含消息列表 */
        include_messages?: boolean;
        /** 消息数量限制 */
        message_limit?: number;
      };
      response: BaseResponse<Conversation>;
    };

    PUT: {
      headers: {
        'Authorization': `Bearer ${string}`;
      };
      params: {
        conversation_id: string;
      };
      body: Partial<Pick<Conversation, 'title' | 'status' | 'metadata'>>;
      response: BaseResponse<Conversation>;
    };

    DELETE: {
      headers: {
        'Authorization': `Bearer ${string}`;
      };
      params: {
        conversation_id: string;
      };
      response: BaseResponse<{
        message: string;
        deleted_at: string;
      }>;
    };
  };
}

3. 流式聊天API

/**
 * 流式聊天API接口定义
 */
export interface ChatAPI {
  /** 流式聊天接口 */
  '/api/v1/chat/stream': {
    POST: {
      headers: {
        'Authorization': `Bearer ${string}`;
        'Content-Type': 'application/json';
        'Accept': 'text/event-stream';
        /** 请求ID,用于幂等性控制 */
        'X-Request-ID'?: string;
      };
      body: {
        /** 用户消息内容 */
        message: string;
        /** 对话ID,可选 */
        conversation_id?: string;
        /** 流ID,用于连接复用 */
        stream_id?: string;
        /** 请求ID,幂等性控制 */
        request_id?: string;
        /** AI模型选择 */
        model?: string;
        /** 生成温度 */
        temperature?: number;
        /** 最大生成长度 */
        max_tokens?: number;
        /** 检索配置 */
        retrieval_config?: {
          top_k?: number;
          threshold?: number;
          mode?: 'vector' | 'hybrid' | 'graph';
        };
        /** 上下文信息 */
        context?: {
          modality: 'text' | 'voice';
          timestamp: string;
          user_preferences?: UserPreferences;
        };
      };
      response: {
        /** SSE事件流 */
        'Content-Type': 'text/event-stream';
        /** 事件类型包括:
         * - retrieval_start: 检索开始
         * - retrieval_progress: 检索进度
         * - retrieval_result: 检索结果
         * - generation_start: 生成开始  
         * - generation_chunk: 生成片段
         * - generation_done: 生成完成
         * - stream_end: 流结束
         * - error: 错误信息
         */
        events: Array<{
          event: string;
          data: any;
          id?: string;
          retry?: number;
        }>;
      };
    };
  };

  /** 取消聊天请求 */
  '/api/v1/chat/cancel': {
    POST: {
      headers: {
        'Authorization': `Bearer ${string}`;
        'X-Request-ID': string;
      };
      body: {
        /** 要取消的请求ID */
        request_id: string;
        /** 取消原因 */
        reason?: string;
      };
      response: BaseResponse<{
        message: string;
        cancelled_at: string;
      }>;
    };
  };
}

4. 语音交互API

/**
 * 语音交互API接口定义
 */
export interface VoiceAPI {
  /** WebSocket语音流接口 */
  '/api/v2/voice/stream': {
    /** WebSocket升级请求 */
    WEBSOCKET: {
      query?: {
        /** 对话ID */
        conversation_id?: string;
        /** 语言代码 */
        language?: string;
        /** 语音配置 */
        voice_config?: string; // JSON编码的VoiceSessionSettings
      };
      headers: {
        'Authorization': `Bearer ${string}`;
        'Upgrade': 'websocket';
        'Connection': 'Upgrade';
        'Sec-WebSocket-Key': string;
        'Sec-WebSocket-Version': '13';
        'Sec-WebSocket-Protocol': 'voice-protocol-v2';
      };
      messages: {
        /** 发送消息格式 */
        send: 
          | {
              type: 'audio_chunk';
              session_id: string;
              audio_chunk: string; // Base64编码
              sequence: number;
              timestamp: number;
              is_final?: boolean;
            }
          | {
              type: 'control';
              action: 'start' | 'stop' | 'pause' | 'resume';
              session_id: string;
            }
          | {
              type: 'config_update';
              session_id: string;
              settings: Partial<VoiceSessionSettings>;
            };
        
        /** 接收消息格式 */
        receive:
          | {
              type: 'session_initialized';
              session_id: string;
              config: VoiceSessionSettings;
              server_time: number;
            }
          | {
              type: 'asr_partial';
              session_id: string;
              text: string;
              confidence: number;
              timestamp: number;
            }
          | {
              type: 'asr_final';
              session_id: string;
              text: string;
              confidence: number;
              timestamp: number;
            }
          | {
              type: 'llm_response_chunk';
              session_id: string;
              text: string;
              timestamp: number;
            }
          | {
              type: 'llm_response_final';
              session_id: string;
              text: string;
              references: Reference[];
              timestamp: number;
            }
          | {
              type: 'tts_start';
              session_id: string;
              text: string;
              timestamp: number;
            }
          | {
              type: 'tts_audio';
              session_id: string;
              audio_data: string; // Base64编码
              chunk_index: number;
              audio_format: string;
              sample_rate: number;
              timestamp: number;
            }
          | {
              type: 'tts_complete';
              session_id: string;
              total_chunks: number;
              timestamp: number;
            }
          | {
              type: 'error';
              session_id: string;
              error: string;
              code: string;
              timestamp: number;
            };
      };
    };
  };

  /** 获取语音会话状态 */
  '/api/v2/voice/sessions/{session_id}': {
    GET: {
      headers: {
        'Authorization': `Bearer ${string}`;
      };
      params: {
        session_id: string;
      };
      response: BaseResponse<VoiceSession>;
    };
  };

  /** 结束语音会话 */
  '/api/v2/voice/sessions/{session_id}/end': {
    POST: {
      headers: {
        'Authorization': `Bearer ${string}`;
      };
      params: {
        session_id: string;
      };
      body?: {
        reason?: string;
      };
      response: BaseResponse<{
        message: string;
        metrics: VoiceMetrics;
        ended_at: string;
      }>;
    };
  };
}

API响应格式标准

/**
 * 标准API响应格式 - 所有API的统一响应结构
 */
export interface BaseResponse<T = any> {
  /** 操作是否成功 */
  success: boolean;
  
  /** 响应数据,成功时包含 */
  data?: T;
  
  /** 错误信息,失败时包含 */
  error?: ErrorInfo;
  
  /** 消息描述 */
  message?: string;
  
  /** 响应时间戳,ISO 8601格式 */
  timestamp: string;
  
  /** 请求追踪ID */
  trace_id?: string;
  
  /** 请求ID,用于幂等性 */
  request_id?: string;
  
  /** API版本 */
  api_version?: string;
  
  /** 服务器信息 */
  server_info?: {
    node_id: string;
    version: string;
    region: string;
  };
}

/**
 * 分页响应格式
 */
export interface PaginatedResponse<T> extends BaseResponse<T[]> {
  /** 分页元数据 */
  pagination: {
    /** 当前页码 */
    page: number;
    
    /** 每页大小 */
    page_size: number;
    
    /** 总记录数 */
    total: number;
    
    /** 总页数 */
    total_pages: number;
    
    /** 是否有下一页 */
    has_next: boolean;
    
    /** 是否有上一页 */
    has_prev: boolean;
    
    /** 下一页URL */
    next_url?: string;
    
    /** 上一页URL */
    prev_url?: string;
  };
}

/**
 * 错误信息结构
 */
export interface ErrorInfo {
  /** 错误代码,用于程序化处理 */
  code: string;
  
  /** 错误消息,用户可读 */
  message: string;
  
  /** 详细信息,调试用 */
  details?: Record<string, any>;
  
  /** 错误堆栈,仅开发环境 */
  stack?: string;
  
  /** 相关字段,用于表单验证错误 */
  field?: string;
  
  /** 建议操作 */
  suggestions?: string[];
  
  /** 帮助链接 */
  help_url?: string;
}

/**
 * API错误代码枚举
 */
export enum APIErrorCode {
  // 通用错误 (1000-1999)
  INTERNAL_ERROR = 'INTERNAL_ERROR',
  INVALID_REQUEST = 'INVALID_REQUEST',
  VALIDATION_ERROR = 'VALIDATION_ERROR',
  RATE_LIMIT_EXCEEDED = 'RATE_LIMIT_EXCEEDED',
  
  // 认证错误 (2000-2999)
  AUTHENTICATION_REQUIRED = 'AUTHENTICATION_REQUIRED',
  INVALID_CREDENTIALS = 'INVALID_CREDENTIALS',
  TOKEN_EXPIRED = 'TOKEN_EXPIRED',
  TOKEN_INVALID = 'TOKEN_INVALID',
  PERMISSION_DENIED = 'PERMISSION_DENIED',
  
  // 资源错误 (3000-3999)
  RESOURCE_NOT_FOUND = 'RESOURCE_NOT_FOUND',
  RESOURCE_CONFLICT = 'RESOURCE_CONFLICT',
  RESOURCE_GONE = 'RESOURCE_GONE',
  
  // 业务逻辑错误 (4000-4999)
  CONVERSATION_NOT_FOUND = 'CONVERSATION_NOT_FOUND',
  MESSAGE_TOO_LONG = 'MESSAGE_TOO_LONG',
  QUOTA_EXCEEDED = 'QUOTA_EXCEEDED',
  
  // 语音相关错误 (5000-5999)
  VOICE_SESSION_NOT_FOUND = 'VOICE_SESSION_NOT_FOUND',
  AUDIO_FORMAT_UNSUPPORTED = 'AUDIO_FORMAT_UNSUPPORTED',
  ASR_PROCESSING_FAILED = 'ASR_PROCESSING_FAILED',
  TTS_SYNTHESIS_FAILED = 'TTS_SYNTHESIS_FAILED',
  
  // 外部服务错误 (6000-6999)
  LLM_SERVICE_UNAVAILABLE = 'LLM_SERVICE_UNAVAILABLE',
  DATABASE_CONNECTION_ERROR = 'DATABASE_CONNECTION_ERROR',
  CACHE_SERVICE_ERROR = 'CACHE_SERVICE_ERROR',
}

🔄 数据流转机制

请求处理流程图

sequenceDiagram
    participant Client as 客户端
    participant Gateway as API网关
    participant Auth as 认证服务
    participant Service as 业务服务
    participant Cache as 缓存层
    participant DB as 数据库
    
    Note over Client,DB: API请求完整处理流程
    
    Client->>Gateway: HTTP请求
    
    Gateway->>Gateway: 1.请求解析和验证
    Gateway->>Auth: 2.身份认证
    Auth-->>Gateway: 认证结果
    
    alt 认证失败
        Gateway-->>Client: 401 Unauthorized
    end
    
    Gateway->>Gateway: 3.权限检查
    
    alt 权限不足
        Gateway-->>Client: 403 Forbidden
    end
    
    Gateway->>Service: 4.路由到业务服务
    
    Service->>Cache: 5.检查缓存
    
    alt 缓存命中
        Cache-->>Service: 缓存数据
        Service-->>Gateway: 响应数据
    else 缓存未命中
        Service->>DB: 6.数据库查询
        DB-->>Service: 查询结果
        Service->>Cache: 7.更新缓存
        Service-->>Gateway: 响应数据
    end
    
    Gateway->>Gateway: 8.响应格式化
    Gateway-->>Client: JSON响应
    
    Note over Client,DB: 流程完成

数据验证机制

/**
 * 数据验证装饰器和工具函数
 */

// Zod schema定义示例
const UserCreateSchema = z.object({
  username: z.string()
    .min(3, '用户名至少3个字符')
    .max(20, '用户名最多20个字符')
    .regex(/^[a-zA-Z0-9_]+$/, '用户名只能包含字母、数字和下划线'),
  
  email: z.string()
    .email('无效的邮箱格式'),
  
  password: z.string()
    .min(8, '密码至少8个字符')
    .regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/, '密码必须包含大小写字母和数字'),
  
  preferences: z.object({
    language: z.enum(['zh-CN', 'en-US', 'ja-JP']),
    theme: z.enum(['light', 'dark', 'auto']),
    voice_settings: VoiceSettingsSchema.optional()
  }).optional()
});

/**
 * API验证中间件
 */
export function validateRequest<T>(schema: z.ZodSchema<T>) {
  return (req: Request, res: Response, next: NextFunction) => {
    try {
      // 验证请求体
      const validatedData = schema.parse(req.body);
      req.body = validatedData;
      next();
    } catch (error) {
      if (error instanceof z.ZodError) {
        const errorDetails = error.errors.map(err => ({
          field: err.path.join('.'),
          message: err.message,
          code: err.code
        }));
        
        return res.status(400).json({
          success: false,
          error: {
            code: 'VALIDATION_ERROR',
            message: '请求数据验证失败',
            details: errorDetails
          },
          timestamp: new Date().toISOString()
        });
      }
      
      next(error);
    }
  };
}

/**
 * 客户端数据验证Hook
 */
export function useFormValidation<T>(schema: z.ZodSchema<T>) {
  const [errors, setErrors] = useState<Record<string, string>>({});
  
  const validate = useCallback((data: unknown): data is T => {
    try {
      schema.parse(data);
      setErrors({});
      return true;
    } catch (error) {
      if (error instanceof z.ZodError) {
        const newErrors: Record<string, string> = {};
        error.errors.forEach(err => {
          const field = err.path.join('.');
          newErrors[field] = err.message;
        });
        setErrors(newErrors);
      }
      return false;
    }
  }, [schema]);
  
  const clearError = useCallback((field: string) => {
    setErrors(prev => {
      const newErrors = { ...prev };
      delete newErrors[field];
      return newErrors;
    });
  }, []);
  
  return {
    validate,
    errors,
    clearError,
    hasErrors: Object.keys(errors).length > 0
  };
}

🛡️ 安全与性能最佳实践

API安全措施

/**
 * API安全中间件集合
 */

// 1. 请求速率限制
export const rateLimitMiddleware = rateLimit({
  windowMs: 15 * 60 * 1000, // 15分钟
  max: 1000, // 每个IP最多1000次请求
  message: {
    error: {
      code: 'RATE_LIMIT_EXCEEDED',
      message: '请求频率超出限制,请稍后重试'
    }
  },
  standardHeaders: true,
  legacyHeaders: false,
});

// 2. CORS安全配置
export const corsOptions: CorsOptions = {
  origin: (origin, callback) => {
    const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(',') || [];
    
    if (!origin || allowedOrigins.includes(origin)) {
      callback(null, true);
    } else {
      callback(new Error('CORS policy violation'));
    }
  },
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: [
    'Origin',
    'X-Requested-With', 
    'Content-Type',
    'Accept',
    'Authorization',
    'X-Request-ID'
  ],
  exposedHeaders: ['X-Total-Count', 'X-Request-ID']
};

// 3. 安全头设置
export const securityHeaders = (req: Request, res: Response, next: NextFunction) => {
  res.setHeader('X-Frame-Options', 'DENY');
  res.setHeader('X-Content-Type-Options', 'nosniff');
  res.setHeader('X-XSS-Protection', '1; mode=block');
  res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
  res.setHeader('Permissions-Policy', 'geolocation=(), microphone=(), camera=()');
  
  if (req.secure) {
    res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
  }
  
  next();
};

// 4. 输入清理和转义
export function sanitizeInput(input: string): string {
  return input
    .trim()
    .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
    .replace(/javascript:/gi, '')
    .replace(/on\w+\s*=/gi, '');
}

// 5. SQL注入防护(使用参数化查询)
export class SecureDatabase {
  async findUser(userId: string): Promise<User | null> {
    // 使用参数化查询防止SQL注入
    const result = await this.db.query(
      'SELECT * FROM users WHERE user_id = $1',
      [userId]
    );
    return result.rows[0] || null;
  }
  
  async createConversation(data: CreateConversationData): Promise<Conversation> {
    // 输入验证和清理
    const sanitized = {
      title: sanitizeInput(data.title || ''),
      user_id: data.user_id,
      metadata: JSON.stringify(data.metadata || {})
    };
    
    const result = await this.db.query(
      'INSERT INTO conversations (user_id, title, metadata) VALUES ($1, $2, $3) RETURNING *',
      [sanitized.user_id, sanitized.title, sanitized.metadata]
    );
    
    return result.rows[0];
  }
}

性能优化策略

/**
 * API性能优化工具集
 */

// 1. 响应缓存机制
export class APICache {
  private cache = new Map<string, CacheEntry>();
  
  generateCacheKey(req: Request): string {
    const { method, path, query, user_id } = req;
    return `${method}:${path}:${JSON.stringify(query)}:${user_id}`;
  }
  
  async get(key: string): Promise<any> {
    const entry = this.cache.get(key);
    
    if (!entry || entry.expiresAt < Date.now()) {
      this.cache.delete(key);
      return null;
    }
    
    return entry.data;
  }
  
  set(key: string, data: any, ttlMs: number = 5 * 60 * 1000): void {
    this.cache.set(key, {
      data,
      expiresAt: Date.now() + ttlMs
    });
  }
  
  middleware() {
    return async (req: Request, res: Response, next: NextFunction) => {
      if (req.method !== 'GET') {
        return next();
      }
      
      const cacheKey = this.generateCacheKey(req);
      const cached = await this.get(cacheKey);
      
      if (cached) {
        res.setHeader('X-Cache', 'HIT');
        return res.json(cached);
      }
      
      // 拦截响应
      const originalJson = res.json;
      res.json = function(body: any) {
        if (res.statusCode === 200) {
          this.set(cacheKey, body);
        }
        res.setHeader('X-Cache', 'MISS');
        return originalJson.call(this, body);
      };
      
      next();
    };
  }
}

// 2. 数据库查询优化
export class QueryOptimizer {
  // 批量查询减少数据库往返
  async batchLoadUsers(userIds: string[]): Promise<Map<string, User>> {
    const users = await this.db.query(
      'SELECT * FROM users WHERE user_id = ANY($1)',
      [userIds]
    );
    
    const userMap = new Map<string, User>();
    users.rows.forEach(user => {
      userMap.set(user.user_id, user);
    });
    
    return userMap;
  }
  
  // 分页查询优化
  async paginateConversations(
    userId: string,
    page: number,
    pageSize: number
  ): Promise<PaginatedResult<Conversation>> {
    const offset = (page - 1) * pageSize;
    
    // 并行执行计数和数据查询
    const [countResult, dataResult] = await Promise.all([
      this.db.query(
        'SELECT COUNT(*) FROM conversations WHERE user_id = $1',
        [userId]
      ),
      this.db.query(
        `SELECT * FROM conversations 
         WHERE user_id = $1 
         ORDER BY updated_at DESC 
         LIMIT $2 OFFSET $3`,
        [userId, pageSize, offset]
      )
    ]);
    
    const total = parseInt(countResult.rows[0].count);
    
    return {
      data: dataResult.rows,
      pagination: {
        page,
        page_size: pageSize,
        total,
        total_pages: Math.ceil(total / pageSize),
        has_next: page * pageSize < total,
        has_prev: page > 1
      }
    };
  }
}

// 3. 流式响应优化
export class StreamOptimizer {
  async streamLargeDataset(
    query: string,
    params: any[],
    res: Response
  ): Promise<void> {
    res.writeHead(200, {
      'Content-Type': 'application/x-ndjson',
      'Transfer-Encoding': 'chunked'
    });
    
    const stream = this.db.query(new Cursor(query, params));
    
    for await (const batch of this.batchIterator(stream, 100)) {
      const chunk = batch.map(row => JSON.stringify(row)).join('\n') + '\n';
      res.write(chunk);
      
      // 允许其他操作执行
      await new Promise(resolve => setImmediate(resolve));
    }
    
    res.end();
  }
  
  private async* batchIterator<T>(
    stream: AsyncIterable<T>,
    batchSize: number
  ): AsyncGenerator<T[]> {
    let batch: T[] = [];
    
    for await (const item of stream) {
      batch.push(item);
      
      if (batch.length >= batchSize) {
        yield batch;
        batch = [];
      }
    }
    
    if (batch.length > 0) {
      yield batch;
    }
  }
}

这份数据结构与API设计分析涵盖了完整的数据模型定义、RESTful API规范、数据流转机制、安全措施和性能优化策略,为开发团队提供了构建稳健API系统的完整指南。