-- InsightFlow Phase 3 - Database Schema -- 支持知识生长与多文件融合 -- 项目表 CREATE TABLE IF NOT EXISTS projects ( id TEXT PRIMARY KEY, name TEXT NOT NULL, description TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 文件/转录表 CREATE TABLE IF NOT EXISTS transcripts ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, filename TEXT, full_text TEXT, type TEXT DEFAULT 'audio', -- 'audio' 或 'document' created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id) ); -- 全局实体表(跨文件共享) CREATE TABLE IF NOT EXISTS entities ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, name TEXT NOT NULL, canonical_name TEXT, -- 规范名称(用于对齐) type TEXT, definition TEXT, aliases TEXT, -- JSON 数组:["别名1", "别名2"] embedding TEXT, -- JSON 数组:实体名称+定义的 embedding created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id) ); -- 实体提及表(文件中的具体位置) CREATE TABLE IF NOT EXISTS entity_mentions ( id TEXT PRIMARY KEY, entity_id TEXT NOT NULL, transcript_id TEXT NOT NULL, start_pos INTEGER, end_pos INTEGER, text_snippet TEXT, confidence REAL DEFAULT 1.0, FOREIGN KEY (entity_id) REFERENCES entities(id), FOREIGN KEY (transcript_id) REFERENCES transcripts(id) ); -- 实体关系表 CREATE TABLE IF NOT EXISTS entity_relations ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, source_entity_id TEXT NOT NULL, target_entity_id TEXT NOT NULL, relation_type TEXT, -- "belongs_to", "works_with", "depends_on" 等 evidence TEXT, -- 关系来源文本 transcript_id TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id), FOREIGN KEY (source_entity_id) REFERENCES entities(id), FOREIGN KEY (target_entity_id) REFERENCES entities(id) ); -- 术语表(项目级热词,用于 ASR 优化) CREATE TABLE IF NOT EXISTS glossary ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, term TEXT NOT NULL, pronunciation TEXT, -- 发音提示,如 "K8s" -> "Kubernetes" frequency INTEGER DEFAULT 1, FOREIGN KEY (project_id) REFERENCES projects(id) ); -- Phase 5: 属性模板表 CREATE TABLE IF NOT EXISTS attribute_templates ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, name TEXT NOT NULL, type TEXT NOT NULL, -- text/number/date/select/multiselect/boolean description TEXT, options TEXT, -- JSON 数组,用于 select/multiselect 类型 is_required INTEGER DEFAULT 0, default_value TEXT, sort_order INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id) ); -- Phase 5: 实体属性值表 CREATE TABLE IF NOT EXISTS entity_attributes ( id TEXT PRIMARY KEY, entity_id TEXT NOT NULL, template_id TEXT, name TEXT NOT NULL, type TEXT NOT NULL, -- text/number/date/select/multiselect value TEXT, -- 存储实际值 options TEXT, -- JSON 数组,用于 select/multiselect created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE, FOREIGN KEY (template_id) REFERENCES attribute_templates(id) ON DELETE SET NULL, UNIQUE(entity_id, name) ); -- Phase 5: 属性变更历史表 CREATE TABLE IF NOT EXISTS attribute_history ( id TEXT PRIMARY KEY, entity_id TEXT NOT NULL, template_id TEXT, attribute_name TEXT NOT NULL, old_value TEXT, new_value TEXT, changed_by TEXT, -- 用户ID或系统 changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, change_reason TEXT, FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE, FOREIGN KEY (template_id) REFERENCES attribute_templates(id) ON DELETE CASCADE ); -- 创建索引以提高查询性能 CREATE INDEX IF NOT EXISTS idx_entities_project ON entities(project_id); CREATE INDEX IF NOT EXISTS idx_entities_name ON entities(name); CREATE INDEX IF NOT EXISTS idx_transcripts_project ON transcripts(project_id); CREATE INDEX IF NOT EXISTS idx_mentions_entity ON entity_mentions(entity_id); CREATE INDEX IF NOT EXISTS idx_mentions_transcript ON entity_mentions(transcript_id); CREATE INDEX IF NOT EXISTS idx_relations_project ON entity_relations(project_id); CREATE INDEX IF NOT EXISTS idx_glossary_project ON glossary(project_id); -- Phase 5: 属性相关索引 CREATE INDEX IF NOT EXISTS idx_attr_templates_project ON attribute_templates(project_id); CREATE INDEX IF NOT EXISTS idx_entity_attributes_entity ON entity_attributes(entity_id); CREATE INDEX IF NOT EXISTS idx_entity_attributes_template ON entity_attributes(template_id); CREATE INDEX IF NOT EXISTS idx_attr_history_entity ON attribute_history(entity_id); -- Phase 7: 工作流相关表 -- 工作流配置表 CREATE TABLE IF NOT EXISTS workflows ( id TEXT PRIMARY KEY, name TEXT NOT NULL, description TEXT, workflow_type TEXT NOT NULL, -- auto_analyze, auto_align, auto_relation, scheduled_report, custom project_id TEXT NOT NULL, status TEXT DEFAULT 'active', -- active, paused, error, completed schedule TEXT, -- cron expression or interval minutes schedule_type TEXT DEFAULT 'manual', -- manual, cron, interval config TEXT, -- JSON: workflow specific configuration webhook_ids TEXT, -- JSON array of webhook config IDs is_active BOOLEAN DEFAULT 1, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_run_at TIMESTAMP, next_run_at TIMESTAMP, run_count INTEGER DEFAULT 0, success_count INTEGER DEFAULT 0, fail_count INTEGER DEFAULT 0, FOREIGN KEY (project_id) REFERENCES projects(id) ); -- 工作流任务表 CREATE TABLE IF NOT EXISTS workflow_tasks ( id TEXT PRIMARY KEY, workflow_id TEXT NOT NULL, name TEXT NOT NULL, task_type TEXT NOT NULL, -- analyze, align, discover_relations, notify, custom config TEXT, -- JSON: task specific configuration task_order INTEGER DEFAULT 0, depends_on TEXT, -- JSON array of task IDs timeout_seconds INTEGER DEFAULT 300, retry_count INTEGER DEFAULT 3, retry_delay INTEGER DEFAULT 5, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (workflow_id) REFERENCES workflows(id) ON DELETE CASCADE ); -- Webhook 配置表 CREATE TABLE IF NOT EXISTS webhook_configs ( id TEXT PRIMARY KEY, name TEXT NOT NULL, webhook_type TEXT NOT NULL, -- feishu, dingtalk, slack, custom url TEXT NOT NULL, secret TEXT, -- for signature verification headers TEXT, -- JSON: custom headers template TEXT, -- message template is_active BOOLEAN DEFAULT 1, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_used_at TIMESTAMP, success_count INTEGER DEFAULT 0, fail_count INTEGER DEFAULT 0 ); -- 工作流执行日志表 CREATE TABLE IF NOT EXISTS workflow_logs ( id TEXT PRIMARY KEY, workflow_id TEXT NOT NULL, task_id TEXT, -- NULL if workflow-level log status TEXT DEFAULT 'pending', -- pending, running, success, failed, cancelled start_time TIMESTAMP, end_time TIMESTAMP, duration_ms INTEGER, input_data TEXT, -- JSON: input parameters output_data TEXT, -- JSON: execution results error_message TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (workflow_id) REFERENCES workflows(id) ON DELETE CASCADE, FOREIGN KEY (task_id) REFERENCES workflow_tasks(id) ON DELETE SET NULL ); -- Phase 7: 工作流相关索引 CREATE INDEX IF NOT EXISTS idx_workflows_project ON workflows(project_id); CREATE INDEX IF NOT EXISTS idx_workflows_status ON workflows(status); CREATE INDEX IF NOT EXISTS idx_workflows_type ON workflows(workflow_type); CREATE INDEX IF NOT EXISTS idx_workflow_tasks_workflow ON workflow_tasks(workflow_id); CREATE INDEX IF NOT EXISTS idx_workflow_logs_workflow ON workflow_logs(workflow_id); CREATE INDEX IF NOT EXISTS idx_workflow_logs_task ON workflow_logs(task_id); CREATE INDEX IF NOT EXISTS idx_workflow_logs_status ON workflow_logs(status); CREATE INDEX IF NOT EXISTS idx_workflow_logs_created ON workflow_logs(created_at); -- Phase 7: 多模态支持相关表 -- 视频表 CREATE TABLE IF NOT EXISTS videos ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, filename TEXT NOT NULL, duration REAL, -- 视频时长(秒) fps REAL, -- 帧率 resolution TEXT, -- JSON: {"width": int, "height": int} audio_transcript_id TEXT, -- 关联的音频转录ID full_ocr_text TEXT, -- 所有帧OCR文本合并 extracted_entities TEXT, -- JSON: 提取的实体列表 extracted_relations TEXT, -- JSON: 提取的关系列表 status TEXT DEFAULT 'processing', -- processing, completed, failed created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id), FOREIGN KEY (audio_transcript_id) REFERENCES transcripts(id) ); -- 视频关键帧表 CREATE TABLE IF NOT EXISTS video_frames ( id TEXT PRIMARY KEY, video_id TEXT NOT NULL, frame_number INTEGER, timestamp REAL, -- 时间戳(秒) image_data BLOB, -- 帧图片数据(可选,可存储在OSS) image_url TEXT, -- 图片URL(如果存储在OSS) ocr_text TEXT, -- OCR识别文本 extracted_entities TEXT, -- JSON: 该帧提取的实体 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (video_id) REFERENCES videos(id) ON DELETE CASCADE ); -- 图片表 CREATE TABLE IF NOT EXISTS images ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, filename TEXT NOT NULL, image_data BLOB, -- 图片数据(可选) image_url TEXT, -- 图片URL ocr_text TEXT, -- OCR识别文本 description TEXT, -- 图片描述(LLM生成) extracted_entities TEXT, -- JSON: 提取的实体列表 extracted_relations TEXT, -- JSON: 提取的关系列表 status TEXT DEFAULT 'processing', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id) ); -- 多模态实体提及表 CREATE TABLE IF NOT EXISTS multimodal_mentions ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, entity_id TEXT NOT NULL, modality TEXT NOT NULL, -- audio, video, image, document source_id TEXT NOT NULL, -- transcript_id, video_id, image_id source_type TEXT NOT NULL, -- 来源类型 position TEXT, -- JSON: 位置信息 text_snippet TEXT, -- 提及的文本片段 confidence REAL DEFAULT 1.0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id), FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE ); -- 多模态实体关联表 CREATE TABLE IF NOT EXISTS multimodal_entity_links ( id TEXT PRIMARY KEY, entity_id TEXT NOT NULL, linked_entity_id TEXT NOT NULL, -- 关联的实体ID link_type TEXT NOT NULL, -- same_as, related_to, part_of confidence REAL DEFAULT 1.0, evidence TEXT, -- 关联证据 modalities TEXT, -- JSON: 涉及的模态列表 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE, FOREIGN KEY (linked_entity_id) REFERENCES entities(id) ON DELETE CASCADE ); -- 多模态相关索引 CREATE INDEX IF NOT EXISTS idx_videos_project ON videos(project_id); CREATE INDEX IF NOT EXISTS idx_videos_status ON videos(status); CREATE INDEX IF NOT EXISTS idx_video_frames_video ON video_frames(video_id); CREATE INDEX IF NOT EXISTS idx_images_project ON images(project_id); CREATE INDEX IF NOT EXISTS idx_images_status ON images(status); CREATE INDEX IF NOT EXISTS idx_multimodal_mentions_project ON multimodal_mentions(project_id); CREATE INDEX IF NOT EXISTS idx_multimodal_mentions_entity ON multimodal_mentions(entity_id); CREATE INDEX IF NOT EXISTS idx_multimodal_mentions_modality ON multimodal_mentions(modality); CREATE INDEX IF NOT EXISTS idx_multimodal_mentions_source ON multimodal_mentions(source_id); CREATE INDEX IF NOT EXISTS idx_multimodal_links_entity ON multimodal_entity_links(entity_id); CREATE INDEX IF NOT EXISTS idx_multimodal_links_linked ON multimodal_entity_links(linked_entity_id); -- Phase 7 Task 7: 插件与集成相关表 -- 插件配置表 CREATE TABLE IF NOT EXISTS plugins ( id TEXT PRIMARY KEY, name TEXT NOT NULL, plugin_type TEXT NOT NULL, -- chrome_extension, feishu_bot, dingtalk_bot, zapier, make, webdav, custom project_id TEXT, status TEXT DEFAULT 'active', -- active, inactive, error, pending config TEXT, -- JSON: plugin specific configuration created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_used_at TIMESTAMP, use_count INTEGER DEFAULT 0, FOREIGN KEY (project_id) REFERENCES projects(id) ); -- 插件详细配置表 CREATE TABLE IF NOT EXISTS plugin_configs ( id TEXT PRIMARY KEY, plugin_id TEXT NOT NULL, config_key TEXT NOT NULL, config_value TEXT, is_encrypted BOOLEAN DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (plugin_id) REFERENCES plugins(id) ON DELETE CASCADE, UNIQUE(plugin_id, config_key) ); -- 机器人会话表 CREATE TABLE IF NOT EXISTS bot_sessions ( id TEXT PRIMARY KEY, bot_type TEXT NOT NULL, -- feishu, dingtalk session_id TEXT NOT NULL, -- 群ID或会话ID session_name TEXT NOT NULL, project_id TEXT, webhook_url TEXT, secret TEXT, -- 签名密钥 is_active BOOLEAN DEFAULT 1, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_message_at TIMESTAMP, message_count INTEGER DEFAULT 0, FOREIGN KEY (project_id) REFERENCES projects(id) ); -- Webhook 端点表(Zapier/Make集成) CREATE TABLE IF NOT EXISTS webhook_endpoints ( id TEXT PRIMARY KEY, name TEXT NOT NULL, endpoint_type TEXT NOT NULL, -- zapier, make, custom endpoint_url TEXT NOT NULL, project_id TEXT, auth_type TEXT DEFAULT 'none', -- none, api_key, oauth, custom auth_config TEXT, -- JSON: authentication configuration trigger_events TEXT, -- JSON array: events that trigger this webhook is_active BOOLEAN DEFAULT 1, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_triggered_at TIMESTAMP, trigger_count INTEGER DEFAULT 0, FOREIGN KEY (project_id) REFERENCES projects(id) ); -- WebDAV 同步配置表 CREATE TABLE IF NOT EXISTS webdav_syncs ( id TEXT PRIMARY KEY, name TEXT NOT NULL, project_id TEXT NOT NULL, server_url TEXT NOT NULL, username TEXT NOT NULL, password TEXT NOT NULL, -- 建议加密存储 remote_path TEXT DEFAULT '/insightflow', sync_mode TEXT DEFAULT 'bidirectional', -- bidirectional, upload_only, download_only sync_interval INTEGER DEFAULT 3600, -- 秒 last_sync_at TIMESTAMP, last_sync_status TEXT DEFAULT 'pending', -- pending, success, failed last_sync_error TEXT, is_active BOOLEAN DEFAULT 1, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, sync_count INTEGER DEFAULT 0, FOREIGN KEY (project_id) REFERENCES projects(id) ); -- Chrome 扩展令牌表 CREATE TABLE IF NOT EXISTS chrome_extension_tokens ( id TEXT PRIMARY KEY, token_hash TEXT NOT NULL UNIQUE, -- SHA256 hash of the token user_id TEXT, project_id TEXT, name TEXT, permissions TEXT, -- JSON array: read, write, delete expires_at TIMESTAMP, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_used_at TIMESTAMP, use_count INTEGER DEFAULT 0, is_revoked BOOLEAN DEFAULT 0, FOREIGN KEY (project_id) REFERENCES projects(id) ); -- 插件相关索引 CREATE INDEX IF NOT EXISTS idx_plugins_project ON plugins(project_id); CREATE INDEX IF NOT EXISTS idx_plugins_type ON plugins(plugin_type); CREATE INDEX IF NOT EXISTS idx_plugins_status ON plugins(status); CREATE INDEX IF NOT EXISTS idx_plugin_configs_plugin ON plugin_configs(plugin_id); CREATE INDEX IF NOT EXISTS idx_bot_sessions_project ON bot_sessions(project_id); CREATE INDEX IF NOT EXISTS idx_bot_sessions_type ON bot_sessions(bot_type); CREATE INDEX IF NOT EXISTS idx_webhook_endpoints_project ON webhook_endpoints(project_id); CREATE INDEX IF NOT EXISTS idx_webhook_endpoints_type ON webhook_endpoints(endpoint_type); CREATE INDEX IF NOT EXISTS idx_webdav_syncs_project ON webdav_syncs(project_id); CREATE INDEX IF NOT EXISTS idx_chrome_tokens_project ON chrome_extension_tokens(project_id); CREATE INDEX IF NOT EXISTS idx_chrome_tokens_hash ON chrome_extension_tokens(token_hash); -- ============================================ -- Phase 7 Task 6: 高级搜索与发现 -- ============================================ -- 搜索索引表 CREATE TABLE IF NOT EXISTS search_indexes ( id TEXT PRIMARY KEY, content_id TEXT NOT NULL, content_type TEXT NOT NULL, -- transcript, entity, relation project_id TEXT NOT NULL, tokens TEXT, -- JSON 数组 token_positions TEXT, -- JSON 对象 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(content_id, content_type) ); -- 搜索词频统计表 CREATE TABLE IF NOT EXISTS search_term_freq ( term TEXT NOT NULL, content_id TEXT NOT NULL, content_type TEXT NOT NULL, project_id TEXT NOT NULL, frequency INTEGER DEFAULT 1, positions TEXT, -- JSON 数组 PRIMARY KEY (term, content_id, content_type) ); -- 文本 Embedding 表 CREATE TABLE IF NOT EXISTS embeddings ( id TEXT PRIMARY KEY, content_id TEXT NOT NULL, content_type TEXT NOT NULL, project_id TEXT NOT NULL, embedding TEXT, -- JSON 数组 model_name TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(content_id, content_type) ); -- 搜索相关索引 CREATE INDEX IF NOT EXISTS idx_search_content ON search_indexes(content_id, content_type); CREATE INDEX IF NOT EXISTS idx_search_project ON search_indexes(project_id); CREATE INDEX IF NOT EXISTS idx_term_freq_term ON search_term_freq(term); CREATE INDEX IF NOT EXISTS idx_term_freq_project ON search_term_freq(project_id); CREATE INDEX IF NOT EXISTS idx_embedding_content ON embeddings(content_id, content_type); CREATE INDEX IF NOT EXISTS idx_embedding_project ON embeddings(project_id); -- ============================================ -- Phase 7 Task 8: 性能优化与扩展 -- ============================================ -- 缓存统计表 CREATE TABLE IF NOT EXISTS cache_stats ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, total_requests INTEGER DEFAULT 0, hits INTEGER DEFAULT 0, misses INTEGER DEFAULT 0, hit_rate REAL DEFAULT 0.0, memory_usage INTEGER DEFAULT 0 ); -- 任务队列表 CREATE TABLE IF NOT EXISTS task_queue ( id TEXT PRIMARY KEY, task_type TEXT NOT NULL, status TEXT DEFAULT 'pending', -- pending, running, success, failed, retrying, cancelled payload TEXT, -- JSON result TEXT, -- JSON error_message TEXT, retry_count INTEGER DEFAULT 0, max_retries INTEGER DEFAULT 3, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, started_at TIMESTAMP, completed_at TIMESTAMP ); -- 性能指标表 CREATE TABLE IF NOT EXISTS performance_metrics ( id TEXT PRIMARY KEY, metric_type TEXT NOT NULL, -- api_response, db_query, cache_operation endpoint TEXT, duration_ms REAL, timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, metadata TEXT -- JSON ); -- 性能相关索引 CREATE INDEX IF NOT EXISTS idx_cache_stats_time ON cache_stats(timestamp); CREATE INDEX IF NOT EXISTS idx_task_status ON task_queue(status); CREATE INDEX IF NOT EXISTS idx_task_type ON task_queue(task_type); CREATE INDEX IF NOT EXISTS idx_task_created ON task_queue(created_at); CREATE INDEX IF NOT EXISTS idx_metrics_type ON performance_metrics(metric_type); CREATE INDEX IF NOT EXISTS idx_metrics_endpoint ON performance_metrics(endpoint); CREATE INDEX IF NOT EXISTS idx_metrics_time ON performance_metrics(timestamp); -- ============================================ -- Phase 7: 插件与集成相关表 -- ============================================ -- 插件表 CREATE TABLE IF NOT EXISTS plugins ( id TEXT PRIMARY KEY, name TEXT NOT NULL, plugin_type TEXT NOT NULL, -- chrome_extension, feishu_bot, dingtalk_bot, slack_bot, webhook, webdav, custom project_id TEXT, status TEXT DEFAULT 'active', -- active, inactive, error, pending config TEXT, -- JSON: 插件配置 api_key TEXT UNIQUE, -- 用于认证的 API Key api_secret TEXT, -- 用于签名验证的 Secret webhook_url TEXT, -- 机器人 Webhook URL created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_used_at TIMESTAMP, use_count INTEGER DEFAULT 0, success_count INTEGER DEFAULT 0, fail_count INTEGER DEFAULT 0, FOREIGN KEY (project_id) REFERENCES projects(id) ); -- 机器人会话表 CREATE TABLE IF NOT EXISTS bot_sessions ( id TEXT PRIMARY KEY, plugin_id TEXT NOT NULL, platform TEXT NOT NULL, -- feishu, dingtalk, slack, wechat session_id TEXT NOT NULL, -- 平台特定的会话ID user_id TEXT, user_name TEXT, project_id TEXT, -- 关联的项目ID context TEXT, -- JSON: 会话上下文 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_message_at TIMESTAMP, message_count INTEGER DEFAULT 0, FOREIGN KEY (plugin_id) REFERENCES plugins(id) ON DELETE CASCADE, FOREIGN KEY (project_id) REFERENCES projects(id), UNIQUE(plugin_id, session_id) ); -- Webhook 端点表(用于 Zapier/Make 集成) CREATE TABLE IF NOT EXISTS webhook_endpoints ( id TEXT PRIMARY KEY, plugin_id TEXT NOT NULL, name TEXT NOT NULL, endpoint_path TEXT NOT NULL UNIQUE, -- 如 /webhook/zapier/abc123 endpoint_type TEXT NOT NULL, -- zapier, make, custom secret TEXT, -- 用于签名验证 allowed_events TEXT, -- JSON: 允许的事件列表 target_project_id TEXT, -- 数据导入的目标项目 is_active BOOLEAN DEFAULT 1, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_triggered_at TIMESTAMP, trigger_count INTEGER DEFAULT 0, FOREIGN KEY (plugin_id) REFERENCES plugins(id) ON DELETE CASCADE, FOREIGN KEY (target_project_id) REFERENCES projects(id) ); -- WebDAV 同步配置表 CREATE TABLE IF NOT EXISTS webdav_syncs ( id TEXT PRIMARY KEY, plugin_id TEXT NOT NULL, name TEXT NOT NULL, server_url TEXT NOT NULL, username TEXT NOT NULL, password TEXT NOT NULL, -- 建议加密存储 remote_path TEXT DEFAULT '/', local_path TEXT DEFAULT './sync', sync_direction TEXT DEFAULT 'bidirectional', -- upload, download, bidirectional sync_mode TEXT DEFAULT 'manual', -- manual, realtime, scheduled sync_schedule TEXT, -- cron expression file_patterns TEXT, -- JSON: 文件匹配模式列表 auto_analyze BOOLEAN DEFAULT 1, -- 同步后自动分析 last_sync_at TIMESTAMP, last_sync_status TEXT, is_active BOOLEAN DEFAULT 1, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, sync_count INTEGER DEFAULT 0, FOREIGN KEY (plugin_id) REFERENCES plugins(id) ON DELETE CASCADE ); -- 插件活动日志表 CREATE TABLE IF NOT EXISTS plugin_activity_logs ( id TEXT PRIMARY KEY, plugin_id TEXT NOT NULL, activity_type TEXT NOT NULL, -- message, webhook, sync, error source TEXT NOT NULL, -- 来源标识 details TEXT, -- JSON: 详细信息 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (plugin_id) REFERENCES plugins(id) ON DELETE CASCADE ); -- 插件相关索引 CREATE INDEX IF NOT EXISTS idx_plugins_project ON plugins(project_id); CREATE INDEX IF NOT EXISTS idx_plugins_type ON plugins(plugin_type); CREATE INDEX IF NOT EXISTS idx_plugins_api_key ON plugins(api_key); CREATE INDEX IF NOT EXISTS idx_bot_sessions_plugin ON bot_sessions(plugin_id); CREATE INDEX IF NOT EXISTS idx_bot_sessions_project ON bot_sessions(project_id); CREATE INDEX IF NOT EXISTS idx_webhook_endpoints_plugin ON webhook_endpoints(plugin_id); CREATE INDEX IF NOT EXISTS idx_webdav_syncs_plugin ON webdav_syncs(plugin_id); CREATE INDEX IF NOT EXISTS idx_plugin_logs_plugin ON plugin_activity_logs(plugin_id); CREATE INDEX IF NOT EXISTS idx_plugin_logs_type ON plugin_activity_logs(activity_type); CREATE INDEX IF NOT EXISTS idx_plugin_logs_created ON plugin_activity_logs(created_at); -- ============================================ -- Phase 7 Task 3: 数据安全与合规 -- ============================================ -- 审计日志表 CREATE TABLE IF NOT EXISTS audit_logs ( id TEXT PRIMARY KEY, action_type TEXT NOT NULL, -- create, read, update, delete, login, export, etc. user_id TEXT, user_ip TEXT, user_agent TEXT, resource_type TEXT, -- project, entity, transcript, api_key, etc. resource_id TEXT, action_details TEXT, -- JSON: 详细操作信息 before_value TEXT, -- 变更前的值 after_value TEXT, -- 变更后的值 success INTEGER DEFAULT 1, -- 0 = 失败, 1 = 成功 error_message TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 加密配置表 CREATE TABLE IF NOT EXISTS encryption_configs ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, is_enabled INTEGER DEFAULT 0, encryption_type TEXT DEFAULT 'aes-256-gcm', -- aes-256-gcm, chacha20-poly1305 key_derivation TEXT DEFAULT 'pbkdf2', -- pbkdf2, argon2 master_key_hash TEXT, -- 主密钥哈希(用于验证) salt TEXT, -- 密钥派生盐值 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id) ); -- 脱敏规则表 CREATE TABLE IF NOT EXISTS masking_rules ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, name TEXT NOT NULL, rule_type TEXT NOT NULL, -- phone, email, id_card, bank_card, name, address, custom pattern TEXT NOT NULL, -- 正则表达式 replacement TEXT NOT NULL, -- 替换模板 is_active INTEGER DEFAULT 1, priority INTEGER DEFAULT 0, description TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id) ); -- 数据访问策略表 CREATE TABLE IF NOT EXISTS data_access_policies ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, name TEXT NOT NULL, description TEXT, allowed_users TEXT, -- JSON array: 允许访问的用户ID列表 allowed_roles TEXT, -- JSON array: 允许的角色列表 allowed_ips TEXT, -- JSON array: 允许的IP模式列表 time_restrictions TEXT, -- JSON: {"start_time": "09:00", "end_time": "18:00", "days_of_week": [0,1,2,3,4]} max_access_count INTEGER, -- 最大访问次数限制 require_approval INTEGER DEFAULT 0, -- 是否需要审批 is_active INTEGER DEFAULT 1, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id) ); -- 访问请求表(用于需要审批的访问) CREATE TABLE IF NOT EXISTS access_requests ( id TEXT PRIMARY KEY, policy_id TEXT NOT NULL, user_id TEXT NOT NULL, request_reason TEXT, status TEXT DEFAULT 'pending', -- pending, approved, rejected, expired approved_by TEXT, approved_at TIMESTAMP, expires_at TIMESTAMP, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (policy_id) REFERENCES data_access_policies(id) ); -- 数据安全相关索引 CREATE INDEX IF NOT EXISTS idx_audit_logs_user ON audit_logs(user_id); CREATE INDEX IF NOT EXISTS idx_audit_logs_resource ON audit_logs(resource_type, resource_id); CREATE INDEX IF NOT EXISTS idx_audit_logs_action ON audit_logs(action_type); CREATE INDEX IF NOT EXISTS idx_audit_logs_created ON audit_logs(created_at); CREATE INDEX IF NOT EXISTS idx_encryption_project ON encryption_configs(project_id); CREATE INDEX IF NOT EXISTS idx_masking_project ON masking_rules(project_id); CREATE INDEX IF NOT EXISTS idx_access_policy_project ON data_access_policies(project_id); CREATE INDEX IF NOT EXISTS idx_access_requests_policy ON access_requests(policy_id); CREATE INDEX IF NOT EXISTS idx_access_requests_user ON access_requests(user_id); -- ============================================ -- Phase 7 Task 4: 协作与共享 -- ============================================ -- 项目分享表 CREATE TABLE IF NOT EXISTS project_shares ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, token TEXT NOT NULL UNIQUE, -- 分享令牌 permission TEXT DEFAULT 'read_only', -- 权限级别: read_only, comment, edit, admin created_by TEXT NOT NULL, -- 创建者 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, expires_at TIMESTAMP, -- 过期时间 max_uses INTEGER, -- 最大使用次数 use_count INTEGER DEFAULT 0, -- 已使用次数 password_hash TEXT, -- 密码保护(哈希) is_active BOOLEAN DEFAULT 1, -- 是否激活 allow_download BOOLEAN DEFAULT 0, -- 允许下载 allow_export BOOLEAN DEFAULT 0, -- 允许导出 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE ); -- 评论表 CREATE TABLE IF NOT EXISTS comments ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, target_type TEXT NOT NULL, -- 目标类型: entity, relation, transcript, project target_id TEXT NOT NULL, -- 目标ID parent_id TEXT, -- 父评论ID(支持回复) author TEXT NOT NULL, -- 作者ID author_name TEXT, -- 作者显示名 content TEXT NOT NULL, -- 评论内容 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, resolved BOOLEAN DEFAULT 0, -- 是否已解决 resolved_by TEXT, -- 解决者 resolved_at TIMESTAMP, -- 解决时间 mentions TEXT, -- JSON数组: 提及的用户 attachments TEXT, -- JSON数组: 附件 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE, FOREIGN KEY (parent_id) REFERENCES comments(id) ON DELETE CASCADE ); -- 变更历史表 CREATE TABLE IF NOT EXISTS change_history ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, change_type TEXT NOT NULL, -- 变更类型: create, update, delete, merge, split entity_type TEXT NOT NULL, -- 实体类型: entity, relation, transcript, project entity_id TEXT NOT NULL, -- 实体ID entity_name TEXT, -- 实体名称(用于显示) changed_by TEXT NOT NULL, -- 变更者ID changed_by_name TEXT, -- 变更者显示名 changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, old_value TEXT, -- JSON: 旧值 new_value TEXT, -- JSON: 新值 description TEXT, -- 变更描述 session_id TEXT, -- 会话ID(批量变更关联) reverted BOOLEAN DEFAULT 0, -- 是否已回滚 reverted_at TIMESTAMP, -- 回滚时间 reverted_by TEXT, -- 回滚者 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE ); -- 团队成员表 CREATE TABLE IF NOT EXISTS team_members ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, user_id TEXT NOT NULL, -- 用户ID user_name TEXT, -- 用户名 user_email TEXT, -- 用户邮箱 role TEXT DEFAULT 'viewer', -- 角色: owner, admin, editor, viewer, commenter joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, invited_by TEXT, -- 邀请者 last_active_at TIMESTAMP, -- 最后活跃时间 permissions TEXT, -- JSON数组: 具体权限列表 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE, UNIQUE(project_id, user_id) -- 每个项目每个用户只能有一条记录 ); -- 协作与共享相关索引 CREATE INDEX IF NOT EXISTS idx_shares_project ON project_shares(project_id); CREATE INDEX IF NOT EXISTS idx_shares_token ON project_shares(token); CREATE INDEX IF NOT EXISTS idx_comments_project ON comments(project_id); CREATE INDEX IF NOT EXISTS idx_comments_target ON comments(target_type, target_id); CREATE INDEX IF NOT EXISTS idx_comments_parent ON comments(parent_id); CREATE INDEX IF NOT EXISTS idx_change_history_project ON change_history(project_id); CREATE INDEX IF NOT EXISTS idx_change_history_entity ON change_history(entity_type, entity_id); CREATE INDEX IF NOT EXISTS idx_change_history_session ON change_history(session_id); CREATE INDEX IF NOT EXISTS idx_team_members_project ON team_members(project_id); CREATE INDEX IF NOT EXISTS idx_team_members_user ON team_members(user_id); -- ============================================ -- Phase 7 Task 6: 高级搜索与发现 -- ============================================ -- 搜索索引表 CREATE TABLE IF NOT EXISTS search_indexes ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, content_type TEXT NOT NULL, -- transcript, entity, relation content_id TEXT NOT NULL, content_text TEXT NOT NULL, tokens TEXT, -- JSON array of tokens created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id), UNIQUE(project_id, content_type, content_id) ); -- 文本 Embedding 表 CREATE TABLE IF NOT EXISTS embeddings ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, content_type TEXT NOT NULL, -- transcript, entity content_id TEXT NOT NULL, text TEXT NOT NULL, embedding TEXT NOT NULL, -- JSON array of floats model TEXT NOT NULL, -- 使用的模型名称 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id), UNIQUE(project_id, content_type, content_id) ); -- 全文搜索虚拟表 (FTS5) CREATE VIRTUAL TABLE IF NOT EXISTS fts_transcripts USING fts5( content_text, content_id UNINDEXED, project_id UNINDEXED, content_type UNINDEXED ); -- 搜索相关索引 CREATE INDEX IF NOT EXISTS idx_search_indexes_project ON search_indexes(project_id); CREATE INDEX IF NOT EXISTS idx_search_indexes_type ON search_indexes(content_type); CREATE INDEX IF NOT EXISTS idx_search_indexes_content ON search_indexes(content_id); CREATE INDEX IF NOT EXISTS idx_embeddings_project ON embeddings(project_id); CREATE INDEX IF NOT EXISTS idx_embeddings_type ON embeddings(content_type); CREATE INDEX IF NOT EXISTS idx_embeddings_content ON embeddings(content_id); CREATE INDEX IF NOT EXISTS idx_embeddings_model ON embeddings(model); -- ============================================ -- Phase 7 Task 8: 性能优化与扩展 -- ============================================ -- 缓存统计表 CREATE TABLE IF NOT EXISTS cache_stats ( id TEXT PRIMARY KEY, stat_date DATE NOT NULL, cache_type TEXT NOT NULL, -- redis, memory total_keys INTEGER DEFAULT 0, memory_usage INTEGER DEFAULT 0, -- bytes hit_count INTEGER DEFAULT 0, miss_count INTEGER DEFAULT 0, evicted_count INTEGER DEFAULT 0, expired_count INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(stat_date, cache_type) ); -- 任务队列表 CREATE TABLE IF NOT EXISTS task_queue ( id TEXT PRIMARY KEY, task_type TEXT NOT NULL, -- audio_analysis, report_generation, entity_extraction status TEXT NOT NULL, -- pending, running, success, failure, retry, revoked project_id TEXT NOT NULL, params TEXT NOT NULL, -- JSON result TEXT, -- JSON error TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, started_at TIMESTAMP, completed_at TIMESTAMP, retry_count INTEGER DEFAULT 0, priority INTEGER DEFAULT 5, -- 0=high, 5=normal, 10=low worker_id TEXT, -- 执行任务的 worker FOREIGN KEY (project_id) REFERENCES projects(id) ); -- 性能指标表 CREATE TABLE IF NOT EXISTS performance_metrics ( id TEXT PRIMARY KEY, metric_type TEXT NOT NULL, -- api_response, db_query, cache_operation endpoint TEXT NOT NULL, duration_ms REAL NOT NULL, status_code INTEGER, timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, metadata TEXT -- JSON: 额外信息 ); -- 数据库分片映射表 CREATE TABLE IF NOT EXISTS shard_mappings ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL UNIQUE, shard_id TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, migrated_at TIMESTAMP, FOREIGN KEY (project_id) REFERENCES projects(id) ); -- 性能相关索引 CREATE INDEX IF NOT EXISTS idx_cache_stats_date ON cache_stats(stat_date); CREATE INDEX IF NOT EXISTS idx_task_queue_project ON task_queue(project_id); CREATE INDEX IF NOT EXISTS idx_task_queue_status ON task_queue(status); CREATE INDEX IF NOT EXISTS idx_task_queue_type ON task_queue(task_type); CREATE INDEX IF NOT EXISTS idx_task_queue_created ON task_queue(created_at); CREATE INDEX IF NOT EXISTS idx_metrics_type ON performance_metrics(metric_type); CREATE INDEX IF NOT EXISTS idx_metrics_endpoint ON performance_metrics(endpoint); CREATE INDEX IF NOT EXISTS idx_metrics_timestamp ON performance_metrics(timestamp); CREATE INDEX IF NOT EXISTS idx_shard_mappings_project ON shard_mappings(project_id); CREATE INDEX IF NOT EXISTS idx_shard_mappings_shard ON shard_mappings(shard_id); -- ============================================ -- Phase 8 Task 1: 多租户 SaaS 架构 -- ============================================ -- 租户主表 CREATE TABLE IF NOT EXISTS tenants ( id TEXT PRIMARY KEY, name TEXT NOT NULL, slug TEXT UNIQUE NOT NULL, description TEXT, tier TEXT DEFAULT 'free', status TEXT DEFAULT 'pending', owner_id TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, expires_at TIMESTAMP, settings TEXT DEFAULT '{}', resource_limits TEXT DEFAULT '{}', metadata TEXT DEFAULT '{}' ); -- 租户域名表 CREATE TABLE IF NOT EXISTS tenant_domains ( id TEXT PRIMARY KEY, tenant_id TEXT NOT NULL, domain TEXT UNIQUE NOT NULL, status TEXT DEFAULT 'pending', verification_token TEXT NOT NULL, verification_method TEXT DEFAULT 'dns', verified_at TIMESTAMP, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, is_primary INTEGER DEFAULT 0, ssl_enabled INTEGER DEFAULT 0, ssl_expires_at TIMESTAMP, FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE ); -- 租户品牌配置表 CREATE TABLE IF NOT EXISTS tenant_branding ( id TEXT PRIMARY KEY, tenant_id TEXT UNIQUE NOT NULL, logo_url TEXT, favicon_url TEXT, primary_color TEXT, secondary_color TEXT, custom_css TEXT, custom_js TEXT, login_page_bg TEXT, email_template TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE ); -- 租户成员表 CREATE TABLE IF NOT EXISTS tenant_members ( id TEXT PRIMARY KEY, tenant_id TEXT NOT NULL, user_id TEXT, -- NULL for pending invitations email TEXT NOT NULL, role TEXT DEFAULT 'member', permissions TEXT DEFAULT '[]', invited_by TEXT, invited_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, joined_at TIMESTAMP, last_active_at TIMESTAMP, status TEXT DEFAULT 'pending', updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE ); -- 租户权限定义表 CREATE TABLE IF NOT EXISTS tenant_permissions ( id TEXT PRIMARY KEY, tenant_id TEXT NOT NULL, name TEXT NOT NULL, code TEXT NOT NULL, description TEXT, resource_type TEXT NOT NULL, actions TEXT NOT NULL, conditions TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE, UNIQUE(tenant_id, code) ); -- 租户资源使用统计表 CREATE TABLE IF NOT EXISTS tenant_usage ( id TEXT PRIMARY KEY, tenant_id TEXT NOT NULL, date DATE NOT NULL, storage_bytes INTEGER DEFAULT 0, transcription_seconds INTEGER DEFAULT 0, api_calls INTEGER DEFAULT 0, projects_count INTEGER DEFAULT 0, entities_count INTEGER DEFAULT 0, members_count INTEGER DEFAULT 0, FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE, UNIQUE(tenant_id, date) ); -- 租户相关索引 CREATE INDEX IF NOT EXISTS idx_tenants_slug ON tenants(slug); CREATE INDEX IF NOT EXISTS idx_tenants_owner ON tenants(owner_id); CREATE INDEX IF NOT EXISTS idx_tenants_status ON tenants(status); CREATE INDEX IF NOT EXISTS idx_domains_tenant ON tenant_domains(tenant_id); CREATE INDEX IF NOT EXISTS idx_domains_domain ON tenant_domains(domain); CREATE INDEX IF NOT EXISTS idx_domains_status ON tenant_domains(status); CREATE INDEX IF NOT EXISTS idx_members_tenant ON tenant_members(tenant_id); CREATE INDEX IF NOT EXISTS idx_members_user ON tenant_members(user_id); CREATE INDEX IF NOT EXISTS idx_usage_tenant ON tenant_usage(tenant_id); CREATE INDEX IF NOT EXISTS idx_usage_date ON tenant_usage(date); -- ============================================ -- Phase 8: Multi-Tenant SaaS Architecture -- ============================================ -- 租户主表 CREATE TABLE IF NOT EXISTS tenants ( id TEXT PRIMARY KEY, name TEXT NOT NULL, slug TEXT UNIQUE NOT NULL, -- URL 友好的唯一标识 description TEXT DEFAULT '', status TEXT DEFAULT 'active', -- active, suspended, trial, expired, pending plan TEXT DEFAULT 'free', -- free, starter, professional, enterprise max_projects INTEGER DEFAULT 5, max_members INTEGER DEFAULT 10, max_storage_gb REAL DEFAULT 1.0, max_api_calls_per_day INTEGER DEFAULT 1000, billing_email TEXT DEFAULT '', subscription_start TEXT, subscription_end TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, created_by TEXT DEFAULT '', -- 创建者用户ID db_schema TEXT DEFAULT '', -- 数据库 schema 名称 table_prefix TEXT DEFAULT '' -- 表前缀 ); -- 租户域名绑定表 CREATE TABLE IF NOT EXISTS tenant_domains ( id TEXT PRIMARY KEY, tenant_id TEXT NOT NULL, domain TEXT NOT NULL, -- 自定义域名 status TEXT DEFAULT 'pending', -- pending, verified, active, failed, expired verification_record TEXT DEFAULT '', -- DNS TXT 记录值 verification_expires_at TEXT, ssl_enabled INTEGER DEFAULT 0, ssl_cert_path TEXT, ssl_key_path TEXT, ssl_expires_at TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, verified_at TEXT, UNIQUE(tenant_id, domain), FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE ); -- 租户品牌配置表(白标) CREATE TABLE IF NOT EXISTS tenant_branding ( id TEXT PRIMARY KEY, tenant_id TEXT UNIQUE NOT NULL, logo_url TEXT, logo_dark_url TEXT, -- 深色模式 Logo favicon_url TEXT, primary_color TEXT DEFAULT '#3B82F6', secondary_color TEXT DEFAULT '#10B981', accent_color TEXT DEFAULT '#F59E0B', background_color TEXT DEFAULT '#FFFFFF', text_color TEXT DEFAULT '#1F2937', dark_primary_color TEXT DEFAULT '#60A5FA', dark_background_color TEXT DEFAULT '#111827', dark_text_color TEXT DEFAULT '#F9FAFB', font_family TEXT DEFAULT 'Inter, system-ui, sans-serif', heading_font_family TEXT, custom_css TEXT DEFAULT '', custom_js TEXT DEFAULT '', app_name TEXT DEFAULT 'InsightFlow', login_page_title TEXT DEFAULT '登录到 InsightFlow', login_page_description TEXT DEFAULT '', footer_text TEXT DEFAULT '© 2024 InsightFlow', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE ); -- 租户成员表 CREATE TABLE IF NOT EXISTS tenant_members ( id TEXT PRIMARY KEY, tenant_id TEXT NOT NULL, user_id TEXT NOT NULL, email TEXT NOT NULL, name TEXT DEFAULT '', role TEXT DEFAULT 'viewer', -- owner, admin, editor, viewer, guest status TEXT DEFAULT 'invited', -- active, invited, suspended, removed invited_by TEXT, invited_at TEXT, invitation_token TEXT, invitation_expires_at TEXT, joined_at TEXT, last_active_at TEXT, custom_permissions TEXT DEFAULT '[]', -- JSON 数组 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(tenant_id, user_id), FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE ); -- 租户角色表 CREATE TABLE IF NOT EXISTS tenant_roles ( id TEXT PRIMARY KEY, tenant_id TEXT NOT NULL, name TEXT NOT NULL, description TEXT DEFAULT '', permissions TEXT DEFAULT '[]', -- JSON 数组 is_system INTEGER DEFAULT 0, -- 1=系统预设, 0=自定义 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE ); -- 租户相关索引 CREATE INDEX IF NOT EXISTS idx_tenants_slug ON tenants(slug); CREATE INDEX IF NOT EXISTS idx_tenants_status ON tenants(status); CREATE INDEX IF NOT EXISTS idx_domains_tenant ON tenant_domains(tenant_id); CREATE INDEX IF NOT EXISTS idx_domains_domain ON tenant_domains(domain); CREATE INDEX IF NOT EXISTS idx_domains_status ON tenant_domains(status); CREATE INDEX IF NOT EXISTS idx_members_tenant ON tenant_members(tenant_id); CREATE INDEX IF NOT EXISTS idx_members_user ON tenant_members(user_id); CREATE INDEX IF NOT EXISTS idx_members_role ON tenant_members(role); CREATE INDEX IF NOT EXISTS idx_members_status ON tenant_members(status); CREATE INDEX IF NOT EXISTS idx_members_token ON tenant_members(invitation_token); CREATE INDEX IF NOT EXISTS idx_roles_tenant ON tenant_roles(tenant_id); -- 更新项目表,添加租户关联(可选,支持租户隔离) ALTER TABLE projects ADD COLUMN tenant_id TEXT; CREATE INDEX IF NOT EXISTS idx_projects_tenant ON projects(tenant_id);