# GoChat 技术架构设计文档 > 版本: v2.0 | 日期: 2026-05-25 | 作者: CTO > 项目定位: Go 语言 1:1 重写 Chatwoot(开源多渠道客服平台) > 技术栈: Go 1.24 + Gin + GORM + PostgreSQL + Redis + WebSocket --- ## 1. 项目概况 | 指标 | 数值 | |------|------| | Go 源码文件 | 418 | | 测试文件 | 104 | | 测试代码行 | 33,711 | | 总代码行 | 90,422 | | 数据库表 | 33 | | API 路由 | 106 | | Go 包 | 42 | | 内部模块 | 26 | GoChat 是一个开源企业级多渠道客服平台,以 Go 语言重写 Chatwoot 核心功能。系统采用单体架构 + 模块化设计,按业务域分包(domain-driven),通过接口解耦各模块,渠道通过插件接口注册以保证扩展性。 --- ## 2. 项目目录结构 ``` gochat/ ├── cmd/ # 应用入口 │ ├── gochat/ # 主HTTP服务器入口 │ │ └── main.go # Gin server 启动 │ ├── migrate/ # 数据库迁移独立工具 │ │ └── main.go │ └── test_debug/ # 测试调试辅助工具 │ ├── configs/ # Viper 配置文件 │ ├── default.yaml # 默认配置基线 │ ├── development.yaml # 开发环境覆盖 │ ├── production.yaml # 生产环境覆盖 │ └── test.yaml # 测试环境覆盖 │ ├── internal/ # 核心业务代码(Go不可外部引用) │ ├── app/ # 应用生命周期 │ │ ├── app.go # App 结构体(持有所有依赖) │ │ ├── bootstrap.go # 依赖注入编排(12步启动序列) │ │ ├── database.go # PostgreSQL 连接池管理 │ │ ├── redis.go # Redis 连接 + PubSub │ │ ├── shutdown.go # graceful shutdown 信号处理 │ │ │ ├── config/ # 配置管理 │ │ ├── config.go # Config 结构体(Server/DB/Redis/JWT/Captain/OAuth/SAML/Push/Webhook) │ │ ├── reloader.go # fsnotify 热加载(11字段无需重启) │ │ │ ├── auth/ # 认证授权 │ │ ├── jwt.go # JWT 签发/验证(access + refresh 双令牌) │ │ ├── refresh_store.go # Refresh Token Redis 存储 │ │ ├── oauth.go # OAuth2 (Google/GitHub) 回调处理 │ │ ├── mfa.go # TOTP MFA 启用/验证/禁用 │ │ ├── saml.go # SAML 2.0 SP 发起/IdP 回调 │ │ ├── permission.go # RBAC 权限矩阵(角色→权限映射) │ │ ├── policy.go # Pundit-style 策略引擎 │ │ ├── platform_auth.go # Platform API Key 认证 │ │ ├── webhook_registry.go # Webhook Token 注册表 │ │ │ ├── middleware/ # Gin 中间件链 │ │ ├── auth.go # AuthMiddleware (JWT Bearer) │ │ ├── cors.go # CORS (通配符子域名支持) │ │ ├── ratelimit.go # 速率限制 (Redis滑动窗口) │ │ ├── account_scope.go # AccountScope (账号上下文注入) │ │ ├── super_admin.go # SuperAdmin (超级管理员守卫) │ │ ├── security_headers.go # 安全响应头 │ │ ├── webhook_auth.go # WebhookAuth (渠道回调认证) │ │ ├── recovery.go # panic 恢复 │ │ ├── request_logger.go # 结构化请求日志 │ │ │ ├── model/ # GORM 数据模型层 │ │ ├── base.go # BaseModel (ID/CreatedAt/UpdatedAt/DeletedAt) │ │ ├── account.go # Account 模型 │ │ ├── user.go # User + AccountUser 模型 │ │ ├── contact.go # Contact + ContactInbox 模型 │ │ ├── inbox.go # Inbox + InboxMember 模型 │ │ ├── conversation.go # Conversation 模型 │ │ ├── message.go # Message + Attachment 模型 │ │ ├── notification.go # Notification + NotificationPreference 模型 │ │ ├── platform_app.go # PlatformApp 模型 │ │ ├── captain.go # Captain Assistant/Document/Scenario/CustomTool/Response │ │ ├── copilot.go # Copilot Thread/Message 模型 │ │ ├── team.go # Team + TeamMember 模型 │ │ ├── reporting.go # ReportingEvent/Rollup 模型 │ │ ├── dashboard_app.go # DashboardApp 模型 │ │ ├── portal.go # Portal (Help Center) 模型 │ │ ├── category.go # Category 模型 │ │ ├── article.go # Article 模型 │ │ ├── folder.go # Folder 模型 │ │ ├── channel.go # Channel 配置子类型模型 │ │ │ ├── repository/ # 数据访问层(21+ Repo) │ │ ├── account_repo.go # Account CRUD + 软删除 │ │ ├── user_repo.go # User CRUD + 关联查询 │ │ ├── contact_repo.go # Contact CRUD + 搜索 │ │ ├── contact_inbox_repo.go # ContactInbox 关联 │ │ ├── conversation_repo.go # Conversation CRUD + 状态/标签/优先级 │ │ ├── inbox_repo.go # Inbox CRUD + 成员管理 │ │ ├── inbox_member_repo.go # InboxMember 座席分配 │ │ ├── message_repo.go # Message CRUD + 附件 │ │ ├── notification_repo.go # Notification CRUD + 未读计数 │ │ ├── notification_pref_repo.go # 通知偏好设置 │ │ ├── push_token_repo.go # Push 设备令牌 │ │ ├── webhook_sub_repo.go # Webhook 事件订阅 │ │ ├── team_repo.go # Team CRUD │ │ ├── team_member_repo.go # TeamMember CRUD │ │ ├── captain_*_repo.go # Captain 6 repos │ │ ├── copilot_*_repo.go # Copilot 2 repos │ │ ├── reporting_*_repo.go # Reporting 2 repos │ │ ├── dashboard_app_repo.go # DashboardApp CRUD │ │ ├── platform_app_repo.go # PlatformApp CRUD + API Key │ │ ├── portal_*_repo.go # Help Center 5 repos │ │ │ ├── service/ # 业务逻辑层 │ │ ├── auth_service.go # 登录/注册/刷新/切换账号 │ │ ├── account_service.go # Account 管理 + 成员增删 │ │ ├── contact_service.go # Contact 管理 + 搜索 │ │ ├── conversation_service.go # Conversation CRUD + 状态流转 + Agent分配 │ │ ├── inbox_service.go # Inbox CRUD + 渠道配置 │ │ ├── inbox_member_service.go # 座席分配/移除 │ │ ├── message_service.go # 消息收发 + 附件处理 │ │ ├── notification_service.go # 通知管理 + 未读计数 │ │ ├── notification_delivery_service.go # 通知推送管道(Push/Webhook/Email) │ │ ├── push_subscription_service.go # Push 设令牌管理 │ │ ├── push_delivery_service.go # Web Push 发送 (VAPID) │ │ ├── webhook_subscription_service.go # Webhook 订阅管理 │ │ ├── webhook_delivery_service.go # Webhook 事件投递 + 签名 │ │ ├── profile_service.go # 用户个人信息更新 │ │ ├── team_service.go # Team CRUD + 成员管理 │ │ ├── captain_*_service.go # Captain AI 5 services │ │ ├── copilot_service.go # Copilot Thread + AI建议/摘要/翻译 │ │ ├── analytics_service.go # 报表聚合 + 指标计算 │ │ ├── dashboard_app_service.go # 自定义Dashboard + Widget管理 │ │ ├── platform_app_service.go # Platform App 管理 + API Key │ │ ├── portal_*_service.go # Help Center 5 services │ │ ├── autoassignment/ # 智能分配服务 │ │ │ ├── service.go # RoundRobin + 负载均衡分配 │ │ │ ├── rate_limiter.go # 分配速率限制 │ │ │ ├── listener.go # EventBus 事件监听 │ │ │ ├── automation/ # 自动化引擎 │ │ ├── model.go # AutomationRule + Macro + CsatSurvey 模型 │ │ ├── service.go # AutomationRuleService │ │ ├── action_service.go # 规则动作执行引擎 │ │ ├── condition_filter.go # 条件过滤器 │ │ ├── condition_validator.go # 条件验证器 │ │ ├── macro_service.go # Macro CRUD + 执行 │ │ ├── csat_survey_service.go # CSAT 满意度调查 │ │ ├── *_listener.go # 多个EventBus监听器 │ │ │ ├── channel/ # 渠道抽象层 │ │ ├── provider.go # Provider 接口定义(注册表模式) │ │ ├── dispatcher.go # 事件分发器(注册Listener) │ │ ├── broker.go # 消息中转器(进出分流) │ │ ├── incoming.go # IncomingMessageHandler 接口 │ │ ├── outgoing.go # OutgoingMessageHandler 接口 │ │ ├── lifecycle.go # 渠道生命周期管理 │ │ ├── config.go # 渠道配置结构 │ │ ├── event.go # 渠道事件类型定义 │ │ ├── listener.go # Listener 接口 │ │ ├── facebook/ # Facebook + Instagram 渠道 │ │ │ ├── provider.go # FacebookProvider (Meta API) │ │ │ ├── instagram_provider.go # InstagramProvider │ │ │ ├── listener.go # FacebookEventListener + InstagramEventListener │ │ │ ├── service.go # FacebookService (消息/媒体处理) │ │ │ ├── repository.go # FacebookRepository (DB访问) │ │ │ ├── pipeline.go # 消息处理管道 │ │ │ ├── media.go # 媒体下载/上传 │ │ │ ├── user_mapping.go # FB用户→Contact映射 │ │ │ ├── webhook_handler.go # HTTP webhook 处理 │ │ │ ├── types.go # FB消息/事件类型 │ │ ├── telegram/ # Telegram 渠道 │ │ │ ├── provider.go # TelegramProvider (Bot API) │ │ │ ├── webhook_handler.go # Telegram webhook HTTP处理 │ │ │ ├── service.go # TelegramService │ │ │ ├── repository.go # TelegramRepository │ │ │ ├── pipeline.go # 消息处理管道 │ │ │ ├── types.go # TG消息/事件类型 │ │ ├── whatsapp/ # WhatsApp 渠道 │ │ │ ├── provider.go # WhatsAppProvider (Business API) │ │ │ ├── service.go # WhatsAppService │ │ │ ├── repository.go # WhatsAppRepository │ │ │ ├── pipeline.go # 消息处理管道 │ │ │ ├── types.go # WA消息/事件类型 │ │ ├── email/ # Email 渠道 │ │ │ ├── imap_listener.go # IMAP 收信监听 │ │ │ ├── smtp_sender.go # SMTP 发信 │ │ │ ├── service.go # EmailService │ │ │ ├── repository.go # EmailRepository │ │ │ ├── pipeline.go # 邮件处理管道 │ │ │ ├── webhook_handler.go # Email webhook HTTP处理 │ │ │ ├── types.go # Email消息类型 │ │ │ ├── provider/ # Provider 注册桥接 │ │ │ │ ├── facebook.go # FB Provider → channel.Register │ │ │ │ ├── telegram.go # TG Provider → channel.Register │ │ │ │ ├── whatsapp.go # WA Provider → channel.Register │ │ │ │ ├── email.go # Email Provider → channel.Register │ │ │ │ ├── web_widget.go # WebWidget Provider → channel.Register │ │ │ ├── handler/ # HTTP 处理层 │ │ ├── api/v1/ # API v1 Handlers (49文件) │ │ │ ├── auth_handler.go # Auth: login/register/refresh/logout │ │ │ ├── mfa_handler.go # MFA: enable/verify/disable │ │ │ ├── saml_handler.go # SAML: SP发起/IdP回调/metadata │ │ │ ├── account_handler.go # Account CRUD + 成员 + 设置 │ │ │ ├── contact_handler.go # Contact CRUD + 搜索 │ │ │ ├── conversation_handler.go # Conversation CRUD + 状态/标签/优先级 │ │ │ ├── inbox_handler.go # Inbox CRUD │ │ │ ├── inbox_member_handler.go # 座席分配 │ │ │ ├── message_handler.go # Message CRUD + retry │ │ │ ├── profile_handler.go # Profile GET/PUT/avatar │ │ │ ├── notification_handler.go # 通知管理 │ │ │ ├── platform_app_handler.go # Platform App CRUD + API Key │ │ │ ├── team_handler.go # Team CRUD + 成员 │ │ │ ├── captain_*_handler.go # Captain AI 4 handlers │ │ │ ├── copilot_handler.go # Copilot Thread + AI动作 │ │ │ ├── analytics_handler.go # 报表/指标 │ │ │ ├── live_report_handler.go # 实时报表 │ │ │ ├── dashboard_app_handler.go # Dashboard + Widget │ │ │ ├── portal_handler.go # Help Center Portal │ │ │ ├── category_handler.go # Help Center 分类 │ │ │ ├── article_handler.go # Help Center 文章 │ │ │ ├── folder_handler.go # Help Center 文件夹 │ │ │ ├── portal_member_handler.go # Portal 成员 │ │ │ ├── automation_rule_handler.go # 自动化规则 │ │ │ ├── macro_handler.go # Macro CRUD + execute │ │ │ ├── csat_survey_handler.go # CSAT 满意度调查 │ │ │ ├── push_subscription_handler.go # Push 设备管理 │ │ │ ├── webhook_subscription_handler.go # Webhook 管理 │ │ │ ├── web_widget_handler.go # WebWidget 配置/CRUD │ │ │ ├── *_routes.go # 各模块路由注册函数 │ │ ├── webhook/ # 渠道 Webhook Handler │ │ │ ├── facebook_webhook_handler.go # FB/IG webhook │ │ │ ├── telegram_webhook_handler.go # TG webhook │ │ ├── ws/ # WebSocket Handler │ │ │ ├── handler.go # WS升级 + 消息分发 │ │ │ ├── router/ # 路由注册中心 │ │ ├── router.go # RegisterRoutes(106路由注册) │ │ │ ├── ws/ # WebSocket 核心层 │ │ ├── hub.go # Hub (连接池管理 + 广播) │ │ ├── auth.go # WSAuthenticator (JWT + pubsub_token) │ │ ├── broadcast.go # 事件广播分发 │ │ ├── presence.go # 在线状态追踪 │ │ ├── typing.go # 输入状态推送 │ │ ├── heartbeat.go # 心跳保活 │ │ ├── event_types.go # WS事件类型定义 │ │ │ ├── pubsub/ # 事件总线 │ │ ├── pubsub.go # PubSub 接口定义 │ │ ├── redis_pubsub.go # Redis Pub/Sub (watermill-redisstream) │ │ ├── event_bus.go # EventBus (topic发布/订阅) │ │ │ ├── llm/ # LLM Provider层 │ │ ├── provider.go # LLMProvider 接口 │ │ ├── openai_provider.go # OpenAI/volcengine/Ollama 统一适配 │ │ │ ├── dispatch/ # 事件分发 │ │ ├── dispatcher.go # Dispatcher (事件→Listener路由) │ │ ├── event.go # 事件类型定义 │ │ ├── listener_registry.go # Listener 注册表 │ │ │ ├── worker/ # 后台任务 │ │ ├── worker.go # Worker池 (goroutine并发) │ │ │ ├── security/ # 安全模块 │ │ ├── encryption.go # 加密/解密 │ │ ├── jwt_security.go # JWT 安全检查 │ │ ├── sql_safety.go # SQL 注入防护 │ │ ├── ssrf_protection.go # SSRF 防护 │ │ ├── webhook_signing.go # Webhook HMAC签名 │ │ │ ├── database/ # 数据库管理 │ │ ├── migrate.go # golang-migrate 迁移执行 │ │ │ ├── autoassignment/ # 智能分配 │ ├── campaign/ # 营销活动 │ ├── canned/ # 快捷回复 │ ├── csat/ # CSAT 模型 │ ├── goimap_stub/ # IMAP 客户端桩 │ ├── pgvector_stub/ # pgvector 桩 │ ├── database/ # DB 迁移管理 │ ├── pkg/ # 可外部引用的公共工具包 │ ├── crypto/ # bcrypt Hash/Check │ ├── logger/ # zap 结构化日志封装 │ ├── pagination/ # offset/limit 分页器 │ ├── response/ # {data, meta} 统一响应格式 │ ├── validator/ # go-playground/validator/v10 自定义规则 │ ├── testutil/ # 测试辅助工具 │ ├── migrations/ # SQL 迁移文件(golang-migrate) │ ├── 000001_init_schema.up.sql # 核心表(22表) │ ├── 000002_add_captain_ai_tables.up.sql # Captain AI 表(8表) │ ├── 000003_add_rate_limit_state.up.sql # Rate Limit 表(1表) │ ├── 000004_add_saml_config_tables.up.sql # SAML 表(2表) │ ├── 000005_add_dashboard_apps_table.up.sql # Dashboard App 表(1表) │ + 对应 down.sql 回滚文件 │ ├── deploy/ # 部署配置 │ ├── k8s/ # Kubernetes manifests │ ├── docker/ # Docker 相关 │ ├── tests/ # 测试目录 │ ├── e2e/ # 端到端测试 │ │ ├── auth_e2e_test.go # 认证流程 │ │ ├── account_e2e_test.go # Account CRUD │ │ ├── conversation_e2e_test.go # 会话流程 │ │ ├── crm_e2e_test.go # CRM 流程 │ │ ├── rbac_e2e_test.go # RBAC 流程 │ │ ├── dashboard_app_e2e_test.go # Dashboard 流程 │ │ ├── channel_incoming_e2e_test.go # 渠道流入 │ │ ├── middleware_e2e_test.go # 中间件测试 │ ├── helpers/ # 测试辅助 │ │ ├── pg_helper.go # PostgreSQL 测试连接 │ ├── scripts/ # 脚本 │ ├── coverage/ # 覆盖率报告 │ ├── docker-compose.yml # 主 compose ├── docker-compose.dev.yml # 开发 compose ├── docker-compose.prod.yml # 生产 compose ├── docker-compose.test.yml # 测试 compose ├── Dockerfile # 生产镜像构建 ├── Dockerfile.dev # 开发镜像 ├── .env.example # 环境变量模板 ├── Makefile # 构建/测试/迁移命令 ├── go.mod # Go 模块定义 ├── go.sum # 依赖锁定 ├── .air.toml # Air 热重载配置 ``` --- ## 3. 模块划分 ### 3.1 分层架构总览 GoChat 采用 **四层分层架构**,各层职责明确,通过接口解耦: ``` ┌──────────────────────────────────────────────────────┐ │ Handler (HTTP层) │ │ Gin Handler → 参数校验 → 调用Service → 统一响应格式 │ ├──────────────────────────────────────────────────────┤ │ Service (业务层) │ │ 业务逻辑编排 → 跨Repo事务 → EventBus事件发布 │ ├──────────────────────────────────────────────────────┤ │ Repository (数据层) │ │ GORM查询封装 → 软删除 → 分页 → 条件过滤 │ ├──────────────────────────────────────────────────────┤ │ Model (模型层) │ │ GORM结构体 → 表映射 → 关联定义 → 验证标签 │ ├──────────────────────────────────────────────────────┤ │ Database (基础设施) │ │ PostgreSQL连接池 → Redis PubSub → Migrations │ └──────────────────────────────────────────────────────┘ ``` ### 3.2 模块分组与职责 | 分组 | 模块 | 职责 | 关键文件 | |------|------|------|---------| | **应用生命周期** | app | 启动编排、graceful shutdown | bootstrap.go, app.go, shutdown.go | | **配置管理** | config | Viper多环境叠加、热加载 | config.go, reloader.go | | **认证授权** | auth | JWT、OAuth、MFA、SAML、RBAC | jwt.go, oauth.go, mfa.go, saml.go, permission.go | | **HTTP中间件** | middleware | Auth、CORS、RateLimit、AccountScope、SecurityHeaders | auth.go, cors.go, ratelimit.go | | **数据模型** | model | GORM结构体定义、表映射 | base.go, account.go, user.go, conversation.go | | **数据访问** | repository | CRUD封装、软删除、分页 | 21+ repo文件 | | **业务逻辑** | service | 业务编排、事务、事件发布 | 20+ service文件 | | **HTTP处理** | handler/api/v1 | 参数校验、响应格式化 | 49 handler文件 | | **路由注册** | router | 路由编排、中间件分组 | router.go | | **渠道抽象** | channel | Provider接口、Dispatcher、进/出消息 | provider.go, dispatcher.go | | **渠道实现** | channel/facebook,telegram,whatsapp,email | 各渠道Provider+Service+Repo+Pipeline | 各子包 | | **WebSocket** | ws | Hub、认证、广播、状态、输入 | hub.go, auth.go, broadcast.go | | **事件总线** | pubsub | Redis Pub/Sub + EventBus | pubsub.go, redis_pubsub.go, event_bus.go | | **LLM集成** | llm | OpenAI/Ollama/volcengine统一适配 | provider.go, openai_provider.go | | **自动化引擎** | automation | 规则CRUD+执行、Macro、CSAT | service.go, action_service.go | | **智能分配** | autoassignment | RoundRobin+负载均衡分配 | service.go, round_robin.go | | **报表分析** | reporting | ReportingEvent聚合 | model.go, service.go | | **后台任务** | worker | goroutine并发池 | worker.go | | **安全防护** | security | 加密、SQL注入防护、SSRF防护、Webhook签名 | encryption.go, sql_safety.go | | **数据库管理** | database | golang-migrate迁移执行 | migrate.go | ### 3.3 公共工具包 (pkg/) | 包 | 职责 | |---|------| | crypto | bcrypt Hash/Check 封装 | | logger | zap 结构化日志(级别/格式/输出配置) | | pagination | offset/limit 分页器 + 元数据计算 | | response | `{data, meta}` 统一JSON响应格式 | | validator | go-playground/validator/v10 自定义验证规则 | | testutil | 测试辅助(DB setup/teardown、mock helper) | ### 3.4 模块依赖关系图 ``` cmd/gochat/main.go │ ▼ app.Bootstrap() │ ┌─────────────┼─────────────┐ │ │ │ ▼ ▼ ▼ config database redis │ │ │ └─────────────┼─────────────┘ │ ▼ auth (JWT/OAuth/MFA/SAML) │ ┌─────────────┼─────────────┐ │ │ │ ▼ ▼ ▼ repository service middleware │ │ │ ▼ ▼ │ model handler ────────┤ │ │ ▼ ▼ router ──→ Gin Engine │ ┌─────────────┼─────────────┐ │ │ │ ▼ ▼ ▼ channel ws/Hub pubsub (providers) (WebSocket) (EventBus) │ │ │ ▼ ▼ ▼ FB/TG/WA/Email broadcast Redis stream ``` --- ## 4. 数据库设计 ### 4.1 技术选型 - **主数据库**: PostgreSQL 16 (带 pgvector 扩展,用于 Captain AI 向量搜索) - **缓存层**: Redis 7+ (Pub/Sub + Rate Limit + Refresh Token + Session) - **ORM**: GORM v2 (模型定义 + AutoMigrate + 软删除) - **迁移工具**: golang-migrate (版本化SQL迁移) - **测试模式**: SQLite (单元测试无需PG) / PostgreSQL (e2e测试) ### 4.2 数据库表总览 (33表) #### 核心基础表 (M1 — 初始化) | 表名 | 用途 | 关键字段 | |------|------|---------| | accounts | 多租户账户 | name, locale, timezone, status, feature_flags(JSON) | | users | 用户 | email(唯一), password_hash, role, provider, totp_secret | | account_users | 用户-账号关联 | user_id, account_id, role, custom_role_id | | custom_roles | 自定义角色 | account_id, name, permissions(JSONB) | | contacts | 客户联系人 | account_id, name, email, phone_number, identifier | | inboxes | 收件箱/渠道入口 | account_id, channel_type, channel_id, enable_auto_assignment | | contact_inboxes | 联系人-收件箱关联 | contact_id, inbox_id, source_id, pubsub_token | | inbox_members | 座席分配 | inbox_id, user_id, role, availability_status | | conversations | 会话 | account_id, inbox_id, contact_id, assignee_id, status, priority, uuid | | messages | 消息 | conversation_id(FK), account_id(FK), sender_id, content, message_type | | attachments | 附件 | message_id, file_type, file_url, file_size, metadata(JSONB) | | notifications | 通知 | account_id, user_id, notification_type, primary_actor, read_at | | notification_preferences | 通知偏好 | user_id, channel, event_type, enabled, preferences(JSONB) | #### 渠道配置表 (M1) | 表名 | 用途 | |------|------| | channels | 渠道配置基表 (account_id, inbox_id, type) | | channel_telegrams | Telegram Bot 配置 (bot_token, bot_name) | | channel_web_widgets | Web Widget 配置 (website_url, welcome_title, welcome_text) | | channel_facebook_pages | Facebook Page 配置 (page_id, access_token) | | channel_whatsapps | WhatsApp Business 配置 (phone_number, business_id) | #### 平台管理表 (M2-M4) | 表名 | 用途 | 关键字段 | |------|------|---------| | platform_apps | 平台应用管理 | name, api_key, account_id, type, status | | reporting_events | 事件上报 | account_id, inbox_id, user_id, name, event_start/end_time | | reporting_events_rollups | 报表聚合 | dimension, dimension_value, metric_name, period | | rate_limit_states | 速率限制状态 | Redis-backed, DB持久化 | #### 认证安全表 (M2-M4) | 表名 | 用途 | 关键字段 | |------|------|---------| | saml_configs | SAML 配置 | account_id, idp_url, certificate, sp_entity_id | | saml_sessions | SAML 会话 | session_id, name_id, account_id, expires_at | #### Captain AI 表 (M10) | 表名 | 用途 | 关键字段 | |------|------|---------| | captain_assistants | AI 助手 | account_id, name, config(JSONB), guardrails(JSONB), status | | captain_documents | AI 文档 | assistant_id, external_link, content, content_fingerprint, status | | captain_assistant_responses | AI 响应记录 | assistant_id, conversation_id, response_text, source | | captain_scenarios | AI 场景 | assistant_id, name, trigger_conditions(JSONB), actions(JSONB) | | captain_custom_tools | AI 自定义工具 | account_id, name, tool_config(JSONB) | | captain_inboxes | 助手-收件箱绑定 | assistant_id, inbox_id | #### Copilot 表 (M10) | 表名 | 用途 | 关键字段 | |------|------|---------| | copilot_threads | Copilot 会话线程 | account_id, user_id, status | | copilot_messages | Copilot 消息 | thread_id, role, content, metadata(JSONB) | #### Dashboard 表 (M11) | 表名 | 用途 | 关键字段 | |------|------|---------| | dashboard_apps | 自定义仪表板 | account_id, name, config(JSONB), widgets(JSONB数组) | ### 4.3 关键设计决策 1. **软删除统一**: 所有表支持 `deleted_at` (GORM软删除),所有查询自动过滤已删除记录 2. **JSONB广泛使用**: feature_flags, permissions, config, metadata, guardrails 等灵活字段用 JSONB 3. **外键约束**: messages 引用 conversations/accounts/inboxes (数据一致性保证) 4. **索引策略**: 每张表都有 `deleted_at` 索引 + 业务字段条件索引 (`WHERE deleted_at IS NULL`) 5. **时间戳统一**: 所有表使用 `created_at/updated_at/deleted_at` (TIMESTAMP WITH TIME ZONE) 6. **UUID公开标识**: conversations 有 uuid 字段,用于公开API(避免内部ID泄露) 7. **向量搜索**: captain_documents 未来通过 pgvector 支持语义搜索 (当前用 stub) ### 4.4 ER 关系图(核心实体) ``` Account ──1:N──→ User (via account_users) Account ──1:N──→ Inbox Account ──1:N──→ Contact Account ──1:N──→ Conversation Account ──1:N──→ Notification Account ──1:N──→ CaptainAssistant Account ──1:N──→ DashboardApp Account ──1:N──→ PlatformApp Inbox ──1:N──→ InboxMember (User) Inbox ──1:N──→ Conversation Inbox ──1:1──→ Channel (polymorphic: telegram/web_widget/facebook/whatsapp) Contact ──1:N──→ ContactInbox ──→ Inbox Contact ──1:N──→ Conversation Conversation ──1:N──→ Message Conversation ──1:N──→ Attachment (via Message) Conversation ──1:1──→ Assignee (User) CaptainAssistant ──1:N──→ CaptainDocument CaptainAssistant ──1:N──→ CaptainScenario CaptainAssistant ──1:N──→ CaptainInbox ──→ Inbox CaptainAssistant ──1:N──→ CaptainAssistantResponse CopilotThread ──1:N──→ CopilotMessage ``` --- ## 5. API 路由设计 ### 5.1 路由总体结构 GoChat API 基于 Gin 框架,采用 RESTful 设计,路由分组如下: ``` /health → 健康检查(无认证) /api/v1/auth/* → 认证路由(公开) /api/v1/saml/* → SAML 路由(公开) /api/v1 (AuthRequired) → 主API路由(认证后) /profile → 用户信息 /notifications → 通知管理 /push_subscriptions → Push 设备 /accounts/:id/webhooks → Webhook 管理 /accounts (AccountScope) → 账号级资源 /accounts/:id/inboxes/* → 收件箱 + WebWidget配置 /accounts/:id/conversations/* → 会话 + 消息 /accounts/:id/contacts/* → 联系人 /accounts/:id/teams/* → 团队 /accounts/:id/platform_apps/* → 平台应用 /accounts/:id/captain/* → Captain AI + Copilot /accounts/:id/reports/* → 报表 /accounts/:id/live_reports/* → 实时报表 /accounts/:id/dashboard_apps/* → 自定义仪表板 /accounts/:id/portals/* → Help Center /accounts/:id/automation_rules/* → 自动化规则 /accounts/:id/macros/* → Macro /accounts/:id/csats/* → CSAT 满意度 /platform/api/v1 (SuperAdmin) → 平台管理路由 /widget (CORS, 无认证) → Widget API /public/api/v1 (CORS, 无认证) → 公开 CSAT 调查 /webhooks (WebhookAuth) → 渠道回调 /webhooks/facebook/:inbox_id → FB/IG webhook /webhooks/telegram/:bot_token → TG webhook /ws → WebSocket 主端点 /cable → WebSocket ActionCable兼容端点 ``` ### 5.2 中间件链 ``` 全局中间件(所有路由): Recovery → RequestLogger → RateLimit → CORS → SecurityHeaders 路由组中间件: AuthMiddleware → /api/v1, /platform/api/v1 AccountScope → /accounts 子路由 SuperAdmin → /platform/api/v1 CORS → /widget, /public/api/v1 WebhookAuth → /webhooks ``` ### 5.3 详细路由列表 #### 认证路由 (公开) | 方法 | 路径 | 说明 | |------|------|------| | POST | /api/v1/auth/login | 登录(email+password) | | POST | /api/v1/auth/register | 注册 | | POST | /api/v1/auth/refresh | Token刷新 | | POST | /api/v1/auth/logout | 登出 | | POST | /api/v1/auth/switch_account | 切换账号 | | POST | /api/v1/auth/reset_password | 密码重置请求 | | PATCH | /api/v1/auth/reset_password/confirm | 确认密码重置 | | GET | /api/v1/auth/google/callback | Google OAuth回调 | | GET | /api/v1/auth/github/callback | GitHub OAuth回调 | #### MFA路由 (需认证) | 方法 | 路径 | 说明 | |------|------|------| | POST | /api/v1/auth/mfa/enable | 启用TOTP | | POST | /api/v1/auth/mfa/verify | 验证TOTP | | POST | /api/v1/auth/mfa/disable | 禁用TOTP | #### SAML路由 (公开) | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/auth/saml/:account_id/login | SAML SP发起登录 | | POST | /api/v1/auth/saml/:account_id/callback | SAML IdP回调 | | GET | /api/v1/auth/saml/:account_id/logout | SAML SLO | | GET | /api/v1/auth/saml/:account_id/metadata | SAML SP Metadata | #### Profile路由 (认证, 无账号作用域) | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/profile | 获取用户信息 | | PUT | /api/v1/profile | 更新用户信息 | | PUT | /api/v1/profile/avatar | 更新头像 | #### Notification路由 (认证, 用户级) | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/notifications | 通知列表 | | GET | /api/v1/notifications/unread_count | 未读数 | | POST | /api/v1/notifications/read_all | 全部标读 | | POST | /api/v1/notifications/:id/read | 标读 | | PUT | /api/v1/notifications/:id | 更新 | | DELETE | /api/v1/notifications/:id | 删除 | | GET | /api/v1/accounts/:id/notification_settings | 通知设置 | | PUT | /api/v1/accounts/:id/notification_settings | 更新设置 | #### Push/Webhook Subscription路由 | 方法 | 路径 | 说明 | |------|------|------| | POST | /api/v1/push_subscriptions | 注册Push设备 | | GET | /api/v1/push_subscriptions | 列出Push设备 | | DELETE | /api/v1/push_subscriptions/:id | 删除Push设备 | | GET | /api/v1/accounts/:id/webhooks | Webhook列表 | | POST | /api/v1/accounts/:id/webhooks | 创建Webhook | | GET | /api/v1/accounts/:id/webhooks/:webhook_id | Webhook详情 | | PUT | /api/v1/accounts/:id/webhooks/:webhook_id | 更新Webhook | | DELETE | /api/v1/accounts/:id/webhooks/:webhook_id | 删除Webhook | #### Account路由 (AccountScope) | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/accounts/ | 账号列表 | | POST | /api/v1/accounts/ | 创建账号 | | GET | /api/v1/accounts/:id | 账号详情 | | PUT | /api/v1/accounts/:id | 更新账号 | | DELETE | /api/v1/accounts/:id | 删除账号 | | PUT | /api/v1/accounts/:id/settings | 更新设置 | | GET | /api/v1/accounts/:id/users | 成员列表 | | POST | /api/v1/accounts/:id/users | 添加成员 | | DELETE | /api/v1/accounts/:id/users/:user_id | 移除成员 | #### Inbox路由 (账号级) | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/accounts/:id/inboxes/ | 收件箱列表 | | POST | /api/v1/accounts/:id/inboxes/ | 创建收件箱 | | GET | /api/v1/accounts/:id/inboxes/:inbox_id | 收件箱详情 | | PUT | /api/v1/accounts/:id/inboxes/:inbox_id | 更新 | | DELETE | /api/v1/accounts/:id/inboxes/:inbox_id | 删除 | | POST | /api/v1/accounts/:id/inboxes/web_widget | 创建Widget收件箱 | | GET | /api/v1/accounts/:id/inboxes/:inbox_id/web_widget_config | Widget配置 | | PUT | /api/v1/accounts/:id/inboxes/:inbox_id/web_widget_config | 更新Widget配置 | | DELETE | /api/v1/accounts/:id/inboxes/:inbox_id/web_widget | 删除Widget | #### InboxMember路由 (座席分配) | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/accounts/:id/inboxes/:inbox_id/members | 成员列表 | | POST | /api/v1/accounts/:id/inboxes/:inbox_id/members | 添加成员 | | PATCH | /api/v1/accounts/:id/inboxes/:inbox_id/members/:user_id | 更新成员 | | DELETE | /api/v1/accounts/:id/inboxes/:inbox_id/members/:user_id | 移除成员 | #### Conversation路由 (账号级) | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/accounts/:id/conversations/ | 会话列表 | | POST | /api/v1/accounts/:id/conversations/ | 创建会话 | | GET | /api/v1/accounts/:id/conversations/search | 搜索会话 | | POST | /api/v1/accounts/:id/conversations/filter | 过滤会话 | | GET | /api/v1/accounts/:id/conversations/:id | 会话详情 | | PATCH | /api/v1/accounts/:id/conversations/:id | 更新会话 | | DELETE | /api/v1/accounts/:id/conversations/:id | 删除会话 | | POST | /api/v1/accounts/:id/conversations/:id/assign | 分配Agent | | POST | /api/v1/accounts/:id/conversations/:id/toggle_status | 切换状态 | | PATCH | /api/v1/accounts/:id/conversations/:id/labels | 更新标签 | | POST | /api/v1/accounts/:id/conversations/:id/mute | 静音 | | POST | /api/v1/accounts/:id/conversations/:id/unmute | 取消静音 | | PATCH | /api/v1/accounts/:id/conversations/:id/priority | 更新优先级 | #### Message路由 (嵌套在Conversation下) | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/accounts/:id/conversations/:conv_id/messages/ | 消息列表 | | POST | /api/v1/accounts/:id/conversations/:conv_id/messages/ | 创建消息 | | GET | /api/v1/accounts/:id/conversations/:conv_id/messages/:id | 消息详情 | | PATCH | /api/v1/accounts/:id/conversations/:conv_id/messages/:id | 更新消息 | | DELETE | /api/v1/accounts/:id/conversations/:conv_id/messages/:id | 删除消息 | | POST | /api/v1/accounts/:id/conversations/:conv_id/messages/:id/retry | 重试 | #### Contact路由 (账号级) | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/accounts/:id/contacts/ | 联系人列表 | | POST | /api/v1/accounts/:id/contacts/ | 创建联系人 | | GET | /api/v1/accounts/:id/contacts/search | 搜索联系人 | | GET | /api/v1/accounts/:id/contacts/:contact_id | 联系人详情 | | PUT | /api/v1/accounts/:id/contacts/:contact_id | 更新联系人 | | DELETE | /api/v1/accounts/:id/contacts/:contact_id | 删除联系人 | #### Team路由 (账号级) | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/accounts/:id/teams/ | 团队列表 | | POST | /api/v1/accounts/:id/teams/ | 创建团队 | | GET | /api/v1/accounts/:id/teams/:id | 团队详情 | | PUT | /api/v1/accounts/:id/teams/:id | 更新团队 | | DELETE | /api/v1/accounts/:id/teams/:id | 删除团队 | | POST | /api/v1/accounts/:id/teams/:id/members | 添加成员 | | DELETE | /api/v1/accounts/:id/teams/:id/members/:user_id | 移除成员 | | GET | /api/v1/accounts/:id/teams/:id/members | 成员列表 | #### Captain AI路由 (账号级) | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/accounts/:id/captain/assistants/ | 助手列表 | | POST | /api/v1/accounts/:id/captain/assistants/ | 创建助手 | | GET | /api/v1/accounts/:id/captain/assistants/:id | 助手详情 | | PUT | /api/v1/accounts/:id/captain/assistants/:id | 更新助手 | | DELETE | /api/v1/accounts/:id/captain/assistants/:id | 删除助手 | | POST | /api/v1/accounts/:id/captain/assistants/:id/inboxes | 绑定收件箱 | | DELETE | /api/v1/accounts/:id/captain/assistants/:id/inboxes/:inbox_id | 解绑收件箱 | | GET | /api/v1/accounts/:id/captain/assistants/:asst_id/documents/ | 文档列表 | | POST | /api/v1/accounts/:id/captain/assistants/:asst_id/documents/ | 创建文档 | | GET | /api/v1/accounts/:id/captain/assistants/:asst_id/documents/:id | 文档详情 | | DELETE | /api/v1/accounts/:id/captain/assistants/:asst_id/documents/:id | 删除文档 | | GET | /api/v1/accounts/:id/captain/assistants/:asst_id/scenarios/ | 场景列表 | | POST | /api/v1/accounts/:id/captain/assistants/:asst_id/scenarios/ | 创建场景 | | GET | /api/v1/accounts/:id/captain/assistants/:asst_id/scenarios/:id | 场景详情 | | PUT | /api/v1/accounts/:id/captain/assistants/:asst_id/scenarios/:id | 更新场景 | | DELETE | /api/v1/accounts/:id/captain/assistants/:asst_id/scenarios/:id | 删除场景 | | GET | /api/v1/accounts/:id/captain/custom_tools/ | 自定义工具列表 | | POST | /api/v1/accounts/:id/captain/custom_tools/ | 创建工具 | | GET | /api/v1/accounts/:id/captain/custom_tools/:id | 工具详情 | | PUT | /api/v1/accounts/:id/captain/custom_tools/:id | 更新工具 | | DELETE | /api/v1/accounts/:id/captain/custom_tools/:id | 删除工具 | #### Copilot路由 (账号级) | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/accounts/:id/captain/copilot_threads/ | 线程列表 | | POST | /api/v1/accounts/:id/captain/copilot_threads/ | 创建线程 | | GET | /api/v1/accounts/:id/captain/copilot_threads/:id | 线程详情 | | DELETE | /api/v1/accounts/:id/captain/copilot_threads/:id | 删除线程 | | POST | /api/v1/accounts/:id/captain/copilot_threads/:id/messages | 发送消息 | | POST | /api/v1/accounts/:id/captain/copilot/suggest_replies | AI建议回复 | | POST | /api/v1/accounts/:id/captain/copilot/summarize | AI会话摘要 | | POST | /api/v1/accounts/:id/captain/copilot/translate | AI翻译 | #### Analytics路由 (账号级) | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/accounts/:id/reports/summary | 报表总览 | | GET | /api/v1/accounts/:id/reports/agents | Agent指标 | | GET | /api/v1/accounts/:id/reports/inboxes | Inbox指标 | | GET | /api/v1/accounts/:id/reports/labels | 标签指标 | | GET | /api/v1/accounts/:id/reports/teams | 团队指标 | | GET | /api/v1/accounts/:id/reports/conversations | 会话流量 | | GET | /api/v1/accounts/:id/reports/conversation_traffic | 会话流量 | #### Live Report路由 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/accounts/:id/live_reports/conversation_metrics | 实时会话指标 | #### Dashboard App路由 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/accounts/:id/dashboard_apps/ | Dashboard列表 | | POST | /api/v1/accounts/:id/dashboard_apps/ | 创建Dashboard | | GET | /api/v1/accounts/:id/dashboard_apps/search | 搜索Dashboard | | GET | /api/v1/accounts/:id/dashboard_apps/:id | Dashboard详情 | | PUT | /api/v1/accounts/:id/dashboard_apps/:id | 更新Dashboard | | PATCH | /api/v1/accounts/:id/dashboard_apps/:id | Patch更新 | | DELETE | /api/v1/accounts/:id/dashboard_apps/:id | 删除Dashboard | | GET | /api/v1/accounts/:id/dashboard_apps/:id/widgets | Widget列表 | | POST | /api/v1/accounts/:id/dashboard_apps/:id/widgets | 添加Widget | | PUT | /api/v1/accounts/:id/dashboard_apps/:id/widgets/:idx | 更新Widget | | DELETE | /api/v1/accounts/:id/dashboard_apps/:id/widgets/:idx | 删除Widget | #### Help Center (Portal)路由 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/accounts/:id/portals/ | Portal列表 | | POST | /api/v1/accounts/:id/portals/ | 创建Portal | | GET | /api/v1/accounts/:id/portals/:portal_id | Portal详情 | | PUT | /api/v1/accounts/:id/portals/:portal_id | 更新Portal | | DELETE | /api/v1/accounts/:id/portals/:portal_id | 删除Portal | | POST | /api/v1/accounts/:id/portals/:portal_id/archive | 归档Portal | | DELETE | /api/v1/accounts/:id/portals/:portal_id/logo | 删除Logo | | GET | /api/v1/accounts/:id/portals/:portal_id/categories/ | 分类列表 | | POST | /api/v1/accounts/:id/portals/:portal_id/categories/ | 创建分类 | | GET | /api/v1/accounts/:id/portals/:portal_id/categories/:cat_id | 分类详情 | | PUT | /api/v1/accounts/:id/portals/:portal_id/categories/:cat_id | 更新分类 | | DELETE | /api/v1/accounts/:id/portals/:portal_id/categories/:cat_id | 删除分类 | | POST | /api/v1/accounts/:id/portals/:portal_id/categories/reorder | 分类排序 | | GET | /api/v1/accounts/:id/portals/:portal_id/articles/ | 文章列表 | | POST | /api/v1/accounts/:id/portals/:portal_id/articles/ | 创建文章 | | GET | /api/v1/accounts/:id/portals/:portal_id/articles/search | 搜索文章 | | GET | /api/v1/accounts/:id/portals/:portal_id/articles/status_counts | 状态统计 | | POST | /api/v1/accounts/:id/portals/:portal_id/articles/reorder | 文章排序 | | POST | /api/v1/accounts/:id/portals/:portal_id/articles/bulk_update_status | 批量更新状态 | | POST | /api/v1/accounts/:id/portals/:portal_id/articles/bulk_delete | 批量删除 | | GET | /api/v1/accounts/:id/portals/:portal_id/articles/:art_id | 文章详情 | | GET | /api/v1/accounts/:id/portals/:portal_id/articles/:art_id/edit | 编辑视图 | | PUT | /api/v1/accounts/:id/portals/:portal_id/articles/:art_id | 更新文章 | | DELETE | /api/v1/accounts/:id/portals/:portal_id/articles/:art_id | 删除文章 | | GET | /api/v1/accounts/:id/portals/:portal_id/categories/:cat_id/articles | 分类下文章 | | GET | /api/v1/accounts/:id/portals/:portal_id/folders/ | 文件夹列表 | | POST | /api/v1/accounts/:id/portals/:portal_id/folders/ | 创建文件夹 | | GET | /api/v1/accounts/:id/portals/:portal_id/folders/:folder_id | 文件夹详情 | | PUT | /api/v1/accounts/:id/portals/:portal_id/folders/:folder_id | 更新文件夹 | | DELETE | /api/v1/accounts/:id/portals/:portal_id/folders/:folder_id | 删除文件夹 | | GET | /api/v1/accounts/:id/portals/:portal_id/members/ | 成员列表 | | POST | /api/v1/accounts/:id/portals/:portal_id/members/ | 创建成员 | | GET | /api/v1/accounts/:id/portals/:portal_id/members/:member_id | 成员详情 | | PUT | /api/v1/accounts/:id/portals/:portal_id/members/:member_id | 更新成员 | | DELETE | /api/v1/accounts/:id/portals/:portal_id/members/:member_id | 删除成员 | #### Automation Rule路由 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/accounts/:id/automation_rules/ | 规则列表 | | POST | /api/v1/accounts/:id/automation_rules/ | 创建规则 | | GET | /api/v1/accounts/:id/automation_rules/:id | 规则详情 | | PUT | /api/v1/accounts/:id/automation_rules/:id | 更新规则 | | DELETE | /api/v1/accounts/:id/automation_rules/:id | 删除规则 | | POST | /api/v1/accounts/:id/automation_rules/:id/clone | 克隆规则 | #### Macro路由 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/accounts/:id/macros/ | Macro列表 | | POST | /api/v1/accounts/:id/macros/ | 创建Macro | | GET | /api/v1/accounts/:id/macros/:id | Macro详情 | | PUT | /api/v1/accounts/:id/macros/:id | 更新Macro | | DELETE | /api/v1/accounts/:id/macros/:id | 删除Macro | | POST | /api/v1/accounts/:id/macros/:id/execute | 执行Macro | #### CSAT路由 | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/accounts/:id/csats/ | CSAT列表 | | GET | /api/v1/accounts/:id/csats/metrics | CSAT指标 | | POST | /api/v1/accounts/:id/csats/:id/update_review_notes | 更新审阅笔记 | #### Platform App路由 (账号级) | 方法 | 路径 | 说明 | |------|------|------| | GET | /api/v1/accounts/:id/platform_apps/ | 应用列表 | | POST | /api/v1/accounts/:id/platform_apps/ | 创建应用 | | GET | /api/v1/accounts/:id/platform_apps/search | 搜索应用 | | GET | /api/v1/accounts/:id/platform_apps/:id | 应用详情 | | PUT | /api/v1/accounts/:id/platform_apps/:id | 更新应用 | | DELETE | /api/v1/accounts/:id/platform_apps/:id | 删除应用 | | POST | /api/v1/accounts/:id/platform_apps/:id/regenerate_api_key | 重生API Key | #### Platform API路由 (超级管理员) | 方法 | 路径 | 说明 | |------|------|------| | GET | /platform/api/v1/apps | 应用列表 | | POST | /platform/api/v1/apps | 创建应用 | | GET | /platform/api/v1/apps/search | 搜索应用 | | GET | /platform/api/v1/apps/:id | 应用详情 | | PUT | /platform/api/v1/apps/:id | 更新应用 | | DELETE | /platform/api/v1/apps/:id | 删除应用 | | POST | /platform/api/v1/apps/:id/regenerate_api_key | 重生API Key | #### Widget路由 (公开, CORS) | 方法 | 路径 | 说明 | |------|------|------| | POST | /widget/init | Widget初始化 | | POST | /widget/contact | Widget创建联系人 | | GET | /widget/conversations | Widget会话列表 | | POST | /widget/messages | Widget发送消息 | | GET | /widget/cable_token | 获取Cable令牌 | #### 公开CSAT路由 (无认证, CORS) | 方法 | 路径 | 说明 | |------|------|------| | GET | /public/api/v1/conversations/:uuid/csats | 获取CSAT调查 | | POST | /public/api/v1/conversations/:uuid/csats | 提交CSAT评分 | #### Webhook回调路由 (渠道认证) | 方法 | 路径 | 说明 | |------|------|------| | GET | /webhooks/facebook/:inbox_id | FB webhook验证 | | POST | /webhooks/facebook/:inbox_id | FB webhook回调 | | POST | /webhooks/telegram/:bot_token | TG webhook回调 | | ANY | /webhooks/:channel_type/:identifier | 其他渠道(占位) | #### WebSocket路由 | 方法 | 路径 | 说明 | |------|------|------| | GET | /ws | WebSocket 主端点 (JWT/pubsub_token认证) | | GET | /cable | ActionCable兼容端点 | #### 健康检查 | 方法 | 路径 | 说明 | |------|------|------| | GET | /health | 服务健康检查 (uptime, version, commit) | ### 5.4 统一响应格式 所有API响应遵循 `{data, meta}` envelope 格式: ```json // 成功 - 单条 {"data": { ... }, "meta": {}} // 成功 - 列表 {"data": [ ... ], "meta": {"page": 1, "per_page": 25, "total": 100}} // 错误 {"error": {"code": "UNAUTHORIZED", "message": "Invalid token"}} ``` --- ## 6. 依赖注入与启动序列 ### 6.1 Bootstrap 12步序列 ``` Step 1: LoadWithEnv(env) → 加载配置(Viper多环境叠加) Step 2: Validate(cfg) → 校验配置完整性 Step 3: InitLogger → zap结构化日志初始化 Step 4: NewDatabase → PostgreSQL连接池 Step 4b: RunMigrations → golang-migrate执行(可选) Step 5: NewRedisClient → Redis连接 Step 5b: NewRedisPubSub → Redis Pub/Sub (watermill) Step 6: Wire Auth Infrastructure → JWT + OAuth + MFA + SAML + RefreshStore + WebhookRegistry Step 7: Wire Repositories → 21+ Repo实例化(构造函数注入*gorm.DB) Step 8: Wire Services → 20+ Service实例化(注入Repo+依赖) Step 9: Wire Handlers → 49 Handler实例化(注入Service) Step 10: Setup Gin Router → 中间件链 + 路由注册 Step 11: Create WebSocket Hub → WS Hub + WSAuthenticator Step 12: Setup Config Reloader → fsnotify热加载(11字段) ``` ### 6.2 App 结构体(持有全部依赖) ```go type App struct { config *config.Config reloader *config.ConfigReloader db *gorm.DB pubsub pubsub.PubSub engine *gin.Engine wsHub *ws.Hub } ``` --- ## 7. 技术选型与关键依赖 | 依赖 | 版本 | 用途 | |------|------|------| | Gin | v1.10 | HTTP 框架 | | GORM | v1.30 | ORM (PostgreSQL + SQLite + MySQL驱动) | | golang-migrate | v4.19 | 版本化SQL迁移 | | watermill + redisstream | v1.5/v1.4 | Redis Pub/Sub 事件总线 | | go-redis | v9.12 | Redis客户端 | | gorilla/websocket | v1.5 | WebSocket | | golang-jwt | v5.2 | JWT签发/验证 | | go-playground/validator | v10.20 | 参数校验 | | spf13/viper | v1.19 | 配置管理 | | go-playground/bluemonday | v1.0 | HTML安全过滤 | | go-resty | v2.16 | HTTP客户端(渠道API调用) | | pgvector-go | v0.4 | 向量搜索(Captain AI) | | gorm.io/datatypes | v1.2 | JSONB类型支持 | | emersion/go-imap | v1.2 | IMAP邮件收取 | | fsnotify | v1.7 | 配置文件热加载 | | miniredis | v2.38 | Redis测试mock | | uber/zap | v1.23 | 结构化日志 | | golang.org/x/crypto | v0.45 | bcrypt + argon2 | | golang.org/x/oauth2 | v0.30 | OAuth2客户端 | --- ## 8. 渠道抽象层设计 ### 8.1 Provider 接口 ```go type Provider interface { Name() string // "facebook", "telegram", etc. ProcessIncoming(ctx, event) (Message, error) // 进站消息处理 ProcessOutgoing(ctx, message) error // 出站消息发送 ValidateWebhook(ctx, request) error // Webhook验签 } ``` ### 8.2 渠道注册表模式 - 全局 `channel.Register(provider)` 注册各Provider - `channel.Dispatcher` 分发事件到对应Listener - 每个渠道实现: Provider + Listener + Service + Repository + Pipeline + Types ### 8.3 已实现渠道 | 渠道 | Provider | Listener | Webhook | 状态 | |------|---------|---------|---------|------| | Facebook/Instagram | FacebookProvider + InstagramProvider | FBEventListener + IGEventListener | facebook_webhook_handler | 已实现 | | Telegram | TelegramProvider | (via webhook) | telegram_webhook_handler | 已实现 | | WhatsApp | WhatsAppProvider | (pending) | (pending) | 基础结构 | | Email | EmailProvider (IMAP+SMTP) | IMAPListener | email_webhook_handler | 已实现 | | Web Widget | WebWidgetProvider | (via HTTP) | (内部路由) | 已实现 | --- ## 9. WebSocket 实时通信 ### 9.1 双端点设计 - `/ws` — 主WebSocket端点 - `/cable` — ActionCable兼容端点(Chatwoot迁移兼容) ### 9.2 认证方式 - JWT Bearer Token (query param或首条消息) - pubsub_token (ContactInbox级认证) ### 9.3 功能模块 | 模块 | 职责 | |------|------| | Hub | 连接池管理 + 消息广播 | | WSAuthenticator | JWT + pubsub_token 双认证 | | Broadcast | EventBus → WS事件分发 | | Presence | 在线/离线状态追踪 | | Typing | 输入状态实时推送 | | Heartbeat | 心跳保活 (ping/pong) | --- ## 10. 安全架构 | 安全措施 | 实现 | |---------|------| | JWT认证 | Access Token (短期) + Refresh Token (Redis存储, 长期) | | MFA (TOTP) | 启用/验证/禁用三步流程 | | SAML 2.0 | SP发起 + IdP回调 + SLO | | RBAC | 角色→权限矩阵 (agent/admin/super_admin + custom_roles) | | Rate Limiting | Redis滑动窗口 (per-IP + per-user) | | SQL注入防护 | GORM参数化查询 + sql_safety检查 | | SSRF防护 | URL白名单 + 内网IP过滤 | | Webhook签名 | HMAC-SHA256 签名验证 | | HTML安全 | bluemonday HTML过滤 | | 安全响应头 | X-Frame-Options, CSP, HSTS, X-Content-Type-Options | | 密码存储 | bcrypt + argon2id | --- ## 11. 测试架构 | 测试层级 | 工具 | 覆盖范围 | |---------|------|---------| | 单元测试 | Go testing + testify | Service/Repository/Auth/Middleware/Model (83文件, 141+用例) | | E2E测试 | Go testing + PG helper | Auth/Account/Conversation/CRM/RBAC/Dashboard/Channel/Middleware | | 测试DB | SQLite (单元) + PostgreSQL (e2e) | 独立DB, 无副作用 | | Redis Mock | miniredis | Auth/RateLimit/PubSub测试 | | Benchmark | Go benchmark | JWT签发/验证性能 | --- ## 12. 部署架构 ### 12.1 Docker Compose 模式 ``` docker-compose.yml → 主compose (app + postgres + redis) docker-compose.dev.yml → 开发 (热重载 + debug端口) docker-compose.prod.yml → 生产 (健康检查 + 资源限制) docker-compose.test.yml → 测试 (独立PG + 覆盖率) ``` ### 12.2 Kubernetes 部署 ``` deploy/k8s/ → Deployment + Service + ConfigMap + Secret manifests ``` ### 12.3 环境配置优先级 ``` .env (最高) → configs/production.yaml → configs/default.yaml → 程序默认值 ``` ### 12.4 热加载字段(11个,无需重启) - Log Level, CORS origins, Rate Limit thresholds, JWT expiry, Worker concurrency 等 --- ## 13. 与 Chatwoot 的架构差异总结 | 维度 | Chatwoot (Ruby/Rails) | GoChat (Go/Gin) | |------|---------------------|-----------------| | 代码组织 | MVC按技术层分层 | 按业务域分包 (domain-driven) | | 依赖注入 | Rails自动加载 | 手动DI + 构造函数注入 | | 实时推送 | ActionCable | Redis Pub/Sub + WebSocket Hub | | 异步任务 | Sidekiq (Ruby进程) | Goroutine + Worker池 | | DB迁移 | ActiveRecord Migration | golang-migrate (SQL文件) | | 配置管理 | InstallationConfig表 + ENV | Viper配置层 + fsnotify热加载 | | 中间件 | Rails before_action | Gin显式中间件链 | | 权限校验 | Pundit Policy类 | 中间件 + 内联权限函数 | | 多态关联 | polymorphic (owner_type+owner_id) | 独立关联表 + JSON字段 | | 事件分发 | Dispatcher + Listener | EventBus接口 + Redis Pub/Sub | | 路由数量 | 327 | ~106 (精简合并) | | 表数量 | 87 | 33 (精简+合并) |