Commit Graph
36 Commits
Author SHA1 Message Date
Rogee 63df5b8b91 fix(captain): 试验场不查 FAQ 知识库 + 添加常见问题报 400
三个问题修复:

1. 添加常见问题报 400 (assistant_id 类型不匹配)
   - CreateResponseDialog.vue: route.params.assistantId 是字符串,
     传给后端 uint 字段导致 JSON 反序列化失败
   - 修复: Number(route.params.assistantId) 转为数字
   - 同时修复 POST /assistant_responses 无尾部斜杠 307 重定向问题

2. 试验场 playground 不做 RAG 检索
   - generatePlaygroundLLMResponse 只构建 system prompt + 对话历史,
     从不查 FAQ 知识库
   - 新增 retrieveFAQContext(): embed 用户问题 → pgvector 搜索 approved
     FAQ → 注入 system prompt
   - 受 feature_faq 配置开关控制

3. FAQ embedding 无法写入 (pgvector 序列化 + 维度问题)
   - pgvector stub 无 driver.Valuer, GORM Save() 报 SQLSTATE 42804
   - 新增 UpdateEmbedding() 用 ?::vector 原始 SQL 绕过
   - SimilaritySearch 排除 embedding 列 + 手动格式化向量字面量
   - embedding 列从 vector(1536) 改为 vector (跟随模型维度)
   - FAQ 创建/更新时自动索引 embedding (SetRAGService 注入)
2026-08-01 19:37:19 +08:00
Rogee bb4c4bb807 fix(captain): 护栏/回复指南编辑按钮不生效
根因:
1. guardrails/guidelines 页面直接导航时 store 无助手记录,getRecord
   返回空对象导致列表为空、编辑无数据
2. storeFactoryHelper updateRecord 用 EDIT mutation(仅更新已有记录),
   store 为空时 API 返回数据被丢弃

修复:
- storeFactoryHelper: updateRecord 改用 UPSERT,确保 API 返回记录始终写入 store
- guardrails/Index.vue & guidelines/Index.vue: onMounted 时若 store 无记录
  则 dispatch captainAssistants/show 拉取单条助手数据
2026-08-01 16:24:09 +08:00
Rogee cd82d079e3 fix(ws): 发送 WebSocket 协议级 Ping 控制帧防止 60s 后连接断开
writePump 只发 ActionCable 文本 JSON ping,从不发 websocket.PingMessage,
导致 readPump 的 PongHandler 永远不触发,ReadDeadline(60s) 到期后连接
被强制关闭。前端每 60 秒弹出"离线""重连"通知。

修复:在 ticker 中先发 PingMessage 控制帧(浏览器自动回 Pong 重置
ReadDeadline),再发 ActionCable 文本 ping(保活 ConnectionMonitor)。

同时包含此前会话中的其他变更:
- 移除安全设置(SAML)页面及路由
- 新增超级管理员控制台前端页面
- platform agent_bots 路由使用 Platform* handler
- 超级管理员入口改为 SPA 内路由跳转
2026-07-30 16:55:44 +08:00
Rogee 57c56c849d fix: 帮助中心设置页报 No valid base URL found in configuration
根因:portalHelper.js getDefaultBaseURL() 在 hostURL 和 helpCenterURL
均为空时直接抛错,但 index.html 中两者默认都是空字符串(表示同源)。
当配置为空时应 fallback 到 window.location.origin 而非抛错。

修复:将空字符串 fallback 改为 window.location.origin,移除 throw。
2026-07-30 11:29:43 +08:00
Rogee 73065d6888 i18n: 翻译会话/帮助中心/集成模块剩余英文文案
- conversation.json: 会话标签计数、语音通话、引用回复、文件类型、
  原生应用提示、邮件转录、Shopify 订单/支付/履行状态等 35 条
- helpCenter.json: 批量翻译/操作、草稿/发布语言、分类排序、
  门户设置(自定义域名/DNS/CNAME)、PDF 上传、内容生成等 46 条
- integrations.json (INTEGRATION_SETTINGS): Shopify 连接/删除、
  Webhook 密钥/搜索、OpenAI 语气/回复选项、Linear/Notion 集成等 40 条
2026-07-30 11:26:06 +08:00
Rogee 6001231cac i18n: 批量翻译公司菜单及全局未翻译英文文案
覆盖 37 个 zh_CN locale JSON 文件,主要模块:
- companies: 公司 CRUD、详情页、联系人关联、属性、头像、删除等 50+ 条
- settings: 个人设置(消息签名/安全/MFA/SLA通知)、账单积分购买、
  APP_GLOBAL/CREATE_ACCOUNT/SIDEBAR 等全局文案
- agentBots/agentMgmt/attributesMgmt: 搜索、机器人配置、属性类型
- automation: 创建/搜索/事件/动作/消息类型
- bulkActions: 批量分配/解决确认文案
- campaign: WhatsApp 营销活动全流程
- contact: 联系人批量操作、备注、新建会话搜索
- report: CSAT/团队/收件箱报告描述、审核备注、评分分布
- signup/resetPassword/login: 注册流程、密码重置、邮箱验证
- snooze: 自然语言时间解析器(分钟/小时/天/月/序数等)
- whatsappTemplates: 模板选择器、参数解析、OTP/优惠券
- yearInReview: 年度回顾全部文案
- onboarding/macros/labelsMgmt/cannedMgmt/teamsSettings 等

保留未翻译:品牌名(Captain/Copilot/WhatsApp 等)、
技术术语(API/URL/SLA/CSAT/SDK 等)、SAML SSO(已移除方向)
2026-07-30 11:23:08 +08:00
Rogee 6e4d6bc137 i18n: 翻译 Captain 文档/工具/助手护栏/回复指南模块中文文案
- zh_CN/integrations.json DOCUMENTS: 批量删除/同步、筛选器、同步状态、
  同步错误、表单类型、操作选项、空状态等 30+ 条翻译
- zh_CN/integrations.json CUSTOM_TOOLS: 创建/编辑/删除、表单字段、认证配置、
  参数、测试、空状态等 40+ 条翻译
- zh_CN/integrations.json ASSISTANTS.GUARDRAILS: 标题、描述、批量操作、
  示例/新增/空状态/API 消息等 20+ 条翻译
- zh_CN/integrations.json ASSISTANTS.RESPONSE_GUIDELINES: 同上 20+ 条翻译
- zh_CN/integrations.json ASSISTANTS.SETTINGS: 基础/系统设置描述、
  控制项标题/描述/护栏/回复指南翻译
- zh_CN/integrations.json RESPONSES: 待审核标题、横幅、空状态翻译
- guardrails/Index.vue: 硬编码示例护栏数据翻译
- guidelines/Index.vue: 硬编码示例回复指南数据翻译
2026-07-30 10:57:57 +08:00
Rogee 95b85b6da9 i18n: 翻译 Captain > Scenarios 模块中文文案
- zh_CN/integrations.json: SCENARIOS 块全部 30+ 条 i18n key 翻译为中文
  (标题、描述、批量操作、表单标签/占位符/校验、空状态、API 消息等)
- zh_CN/settings.json: 侧边栏 CAPTAIN_SCENARIOS 标签 Scenarios → 场景
- scenarios/Index.vue: 硬编码示例场景数据(标题/描述/指令)翻译为中文
2026-07-30 10:50:04 +08:00
Rogee 92c625ea4a fix: 修复登录后白屏 + label标签闪屏
白屏: security.routes.js 缺少 security_settings_index 命名路由,
SidebarGroup 的 router.resolve 抛错导致所有 sidebar 组件渲染失败.
修复: 添加命名子路由指向空占位组件.

闪屏: 后端 FilterParams.Labels 用 form:"labels" 绑定,
无法解析 Chatwoot 前端的 labels[] 数组参数, label 过滤从未生效.
IntersectionObserver 检测到"还有更多数据"不断触发 loadMore,
8秒内发出 1000+ 次重复请求形成无限循环.
修复: 新增 LabelsArr []string 字段绑定 form:"labels[]",
在 handler 中合并到 Labels 字段.
2026-07-30 10:37:38 +08:00
Rogee 04b999e377 refactor: 移除 FakeMessagePlatform channel 全部逻辑、展示、配置
- 删除 channels/fake/ 整个 Node.js FakeMessagePlatform (8文件)
- 删除后端 FakeProvider (fake.go + fake_test.go) + FakeWebhookHandler (fake_webhook.go)
- bootstrap.go: 移除 FakeProvider 接线 + isFakeChannelEnabled()
- router.go: 移除 FakeWebhook 字段 + /webhooks/fake/:identifier 路由
- provider.go: 移除 ChannelFake 常量
- inbox_service.go: 移除 fake channel 类型验证 + isFakeChannelAllowed()
- 前端: 移除 Fake.vue + ChannelFactory/ChannelList/ChannelItem 引用 + i18n (en/zh_CN)
- package.json: 移除 fake:start/dev/test/dev:all 脚本
- pnpm-workspace.yaml: 移除 channels/fake
- .env/.env.example/quickstart: 移除 GOCHAT_ALLOW_FAKE_CHANNEL
- 测试: bridge_listener_test 改用 web_widget, router_test 移除 fake 路由断言
- 保留 fake:ai LLM Provider (backend/internal/llm/fake_provider.go) — 与 channel 无关
2026-07-30 09:09:17 +08:00
Rogee 851ca7e372 refactor: 移除 SAML/LDAP/MFA 登录方式,仅保留本地账号密码和 OIDC
后端移除:
- SAML: auth/saml.go, handler/saml_handler.go, account_saml_settings_handler.go,
  model/account_saml_settings.go, model/saml_idp_config.go, repo/*.go
- LDAP: auth/ldap.go, handler/ldap_handler.go, model/account_ldap_settings.go,
  repo/account_ldap_settings_repo.go
- MFA: auth/mfa.go, handler/mfa_handler.go
- auth_service: 移除 mfaService 依赖、MFARequired 字段、LoginWithMFA 方法
- auth_handler: 移除 LoginMFA handler、MFA 分支逻辑
- bootstrap: 移除 SAML/LDAP/MFA service 初始化和 handler 注册
- sso_middleware: 精简为仅支持 OIDC provider
- router: 移除 SAML/LDAP/MFA 路由注册
- config: 移除 SAMLConfig/LDAPConfig struct 和 defaults

前端移除:
- v3/login: 移除 MFA 验证流程和 SAML 登录入口
- v3/api/auth: 移除 MFA 响应处理
- v3/routes: 移除 SSO login 路由
- dashboard: 移除 MFA 设置页面、SAML 安全设置页面
- i18n: 移除 mfa.json
- featureFlags: 移除 SAML feature flag

.env.example / .env: 移除 SAML/LDAP 配置段
2026-07-29 19:03:04 +08:00
Rogee 7ed53bec47 chore: 修复登录页与前端开发服务器配置
- vite dev server 端口改为 5000 并启用 strictPort,端口冲突时拒绝启动
- AGENTS.md 更新前端目录结构说明(移除已删除的 ERB/enterprise 目录)及端口文档
- v3 登录页精简:移除 useBranding/globalConfig 依赖,去掉忘记密码链接
- 中文登录表单翻译优化(Email → 电子邮件)
2026-07-29 14:49:20 +08:00
Rogee 83386dff75 fix: 修复4个已知BUG — P1 ChatList/P2 错误密码/P3 Copilot崩溃/P3超管entrypoint
P1: ChatList.vue — 添加 conversationStats watch fallback,检测 stats>0
   但 chatList 为空时自动触发 fetchConversations
P2: api.js parseAPIErrorResponse — 处理 error 字段为对象时提取 .message
P3: CopilotContainer.vue — activeAssistant 判空保护
P3: 新建 super_admin.html + vite.config.ts rewrite 规则
    (注:entrypoint 仅含样式,Vue应用代码待补)
防御: NotificationTable.vue — 可选链保护 primary_actor.meta 路径
2026-07-29 09:55:24 +08:00
rogee d16bb55d91 feat(realtime): complete fake channel reply flow 2026-07-13 14:57:28 +08:00
rogee a712b91982 fix(copilot): harden provider configuration flow 2026-07-13 14:57:28 +08:00
rogee 19cee9af11 fix(copilot): align runtime configuration contracts 2026-07-13 14:57:28 +08:00
rogee 8b9eedc0e2 feat(copilot): finish configuration center 2026-07-13 14:57:28 +08:00
rogee df23caf7d9 feat(copilot): move provider configuration to settings 2026-07-12 22:27:29 +08:00
rogee f39943629f fix: remove enterprise mode gating 2026-07-12 22:19:51 +08:00
rogee 813faa4cd7 fix(messages): normalize webhook reply references 2026-07-12 22:17:04 +08:00
rogee b0bb7f0702 fix(frontend): stop offline conversation request loop 2026-07-12 22:16:16 +08:00
rogee f923791d39 update 2026-07-12 12:20:23 +08:00
rogee 7f2d5579ff fix: stabilize development config and account settings 2026-07-11 17:15:38 +08:00
rogee 690796a7de fix: resolve 4 bugs from QA round 6 (BUG-F/G/H/I)
BUG-F (P1): Fake webhook lookupInbox used JSONB @> operator on a TEXT
column, causing all fake webhooks to return "ignored". Cast
channel_config::jsonb before the @> operator.

BUG-G (P3): Vue Router history.state warning on Activity page. Four
call sites replaced history.state with null/{}, destroying Vue Router's
internal navigation state. Now all replaceState calls preserve
window.history.state.

BUG-H (P3): Inbox list showed stale data because cache_keys endpoint
returned hardcoded "0000000000" for inbox/label/team, so the frontend
IndexedDB cache never invalidated. Cache keys are now derived from
actual DB state (row count + MAX(updated_at)), with defensive fallback
for missing tables.

BUG-I (P3): All worker goroutines shared the same Redis consumer name,
so XINFO CONSUMERS showed 1 consumer instead of N. Each goroutine now
generates a unique consumer ID (workerID-index).
2026-07-10 16:59:26 +08:00
rogee 05af5ebcbc fix: harden fake channel — production guard, token validation, typing events, URL validation, capability narrowing
- Guard fake channel with GOCHAT_ENV check: skip init() registration,
  bootstrap wiring, and inbox creation in production
- Reject empty-token webhooks in production (was silently skipped)
- Use PostgreSQL jsonb @> query for inbox lookup, keep SQLite fallback
- Replace isValidURL string-prefix hack with net/url.Parse
- Handle typing.start/typing.stop by returning nil (no garbage messages)
- Narrow Capabilities to only implemented features (Attachments, Replies)
- Hide fake channel from frontend channel list in production builds
2026-07-10 10:55:54 +08:00
rogee 9c852cd99b add fake channel 2026-07-09 18:14:45 +08:00
rogee 0dabb8cfa5 docs: 整理文档目录结构 — 清理过时文档、归集功能子目录、统一命名规范
清理:
- 删除 34 份过时文档(gap reports/QA临时报告/验收报告/阶段性文档)
- 删除 docs/.hermes/skills 第三方 skills 副本(16 文件)
- 删除 skills-lock.json

目录归集:
- 根目录仅保留 README.md 索引
- product/ — 产品与架构设计(PRD + ARCHITECTURE + P2设计文档 + AI/企业路线图)
- tracking/ — Chatwoot parity 开发跟踪
- requirements/ — M01-M12 模块需求
- plans/ — 历史实现计划
- parity/ — 路由 parity 与前端契约
- qa/ — QA 报告与测试计划
- ops/ — 运维部署

命名规范:
- 全小写 kebab-case,禁止全大写文件名
- product/tracking/ops 用 NN- 序号前缀
- requirements 用 MNN- 两位零填充模块号
- plans/qa 用 YYYY-MM-DD- 日期前缀
- requirements M1-M9 零填充为 M01-M09(修复字典序)

同步更新:
- backend/cmd/route_parity/main.go 路径默认值
- backend/scripts/parity_frontend_smoke.sh 报告路径
- 所有 docs 内部交叉引用
- .gitignore 排除编译产物 (backend/gochat, backend/route_parity)
- 新增迁移 000052/000053
- 前端 WS 相关修改
2026-07-09 14:53:27 +08:00
rogee 3fb3126b4c fix(frontend): translate AssignmentPolicy/ConversationWorkflow to zh_CN + fix Agent Assignment crash
- Add Chinese translations for ASSIGNMENT_POLICY, CONVERSATION_WORKFLOW
  sections and SIDEBAR labels in zh_CN settings.json
- Fix AssignmentCard.vue: v-for :key used feature.id which was always
  undefined (feature objects have no id field), causing duplicate keys
  and Vue reconciliation crash (Cannot read properties of null reading
  parentNode) when navigating to the Agent Assignment settings page
2026-07-08 17:18:33 +08:00
rogee 10cc300f31 Fix canned_responses 500: add missing SQL migration
The canned_responses table was registered in autoMigrate() (app.go) but
autoMigrate() is never called on the serve path (Bootstrap -> NewDatabase
-> RunMigrations only). With no SQL migration file, the table never
existed, so POST /api/v1/accounts/:id/canned_responses failed with
'relation does not exist' -> 500.

Add migration 000049 to create the table matching the GORM model
(id, account_id, content, short_code, timestamps) with the account+
short_code partial unique index and deleted_at index.

Also include two related fixes staged in the working tree:
- router.go: register notifications.GET("") alongside GET("/") to avoid
  Gin 301 trailing-slash redirect that the Vite proxy doesn't follow
- notifications/actions.js: stop the infinite loader on fetch error to
  prevent IntersectionObserver re-fire loop
2026-07-08 11:43:34 +08:00
rogee be38051ac5 Fix Reports 500, Settings white screen, SidebarGroup exceptions
ISS-01: Fix reporting_events_rollups table schema mismatch
- The init migration (000001) created columns (dimension, dimension_value,
  metric_name, value, value_in_business_hours, period) that do not match
  the GORM model which expects (date, dimension_type, dimension_id, metric,
  count, sum_value, sum_value_business_hours)
- Add migration 000048 to drop and recreate the table with correct schema
  matching the GORM model and all Go code that references it
- Fixes: GET /api/v2/accounts/:id/reports returning HTTP 500 with
  'column date does not exist (SQLSTATE 42703)'

ISS-02: Fix Settings > General page white screen
- AccountId.vue: add null-safe access for currentAccount.value.id before
  calling toString() — currentAccount can be {} when account data not yet
  loaded in store
- BuildInfo.vue: add null-safe access for globalConfig.value.gitSha and
  globalConfig.value.appVersion; guard copyGitSha with existence check;
  add v-if guard on gitSha span in template

ISS-04: Fix SidebarGroup mounted hook exceptions
- SidebarGroup.vue: Object.keys(child.to.params) throws TypeError when
  child.to.params is undefined; add null-safe fallback Object.keys(child.to?.params ?? {})
- This was the source of the 29 recurring JS exceptions on every Settings
  page navigation

ISS-05: Fix Vue Router root path warning
- Add root route { path: '/', redirect: '/app/login' } to silence
  'No match found for location with path /' warning
2026-07-08 10:02:29 +08:00
rogee a1ae852eb2 Fix widget i18n missing locale files and clean up unused locales
- widget/i18n/index.js: only import en.json and zh_CN.json (the only
  locale files present); remove 40+ imports for missing locale JSONs
  that caused Vite compile failure and global white screen
- dashboard/i18n/index.js: remove unused locale imports for consistency
- Remove 62 unused locale JSON files from widget/i18n/locale/
- Minor: update index.html, test helpers, e2e test, languages spec
2026-07-08 09:57:00 +08:00
rogee 9c74b83560 modify 2026-07-08 09:52:19 +08:00
rogee 8aeee9ebc7 Fix frontend login flow: merge v3 auth routes, fix vite proxy, SPA redirect 2026-07-07 18:57:11 +08:00
rogee 4d167c3331 Fix hardcoded Rails direct_upload URLs in Vue upload components
Replace '/rails/active_storage/direct_uploads' with GoChat endpoint
'/api/v1/widget/direct_uploads' in two dashboard upload components:
- ActionButtons.vue (new conversation attachment upload)
- ReplyBottomPanel.vue (conversation reply attachment upload)

These data attributes are consumed by vue-upload-component; the actual
upload logic in useFileUpload/fileUploadMixin already used the correct
GoChat endpoints. Spotted by decoupling audit report.
2026-07-07 15:41:25 +08:00
rogee 1535e6cd55 Decouple frontend from Rails, establish pnpm workspace dev workflow
Strip the Chatwoot frontend down to a standalone Vite + Vue 3 SPA that talks
directly to the GoChat Go backend — no Ruby/Rails required.

Deleted from frontend/ (all Rails-only):
- Ruby: Gemfile, Gemfile.lock, config.ru, Capfile, Rakefile, bin/ (binstubs),
  config/ (application/boot/environment/routes/initializers/environments/locales),
  app/helpers/ (*.rb), app/views/ (ERB/jbuilder), app/assets/ (administrate scss)
- Enterprise overlay (enterprise/ — pure Ruby/jbuilder, zero JS)
- Infra: Procfile*, docker-compose*, docker/, deployment/, swagger/, .circleci/,
  .devcontainer/, .qlty/, .codegraph/, .windsurf/, .github/, .vscode/, .husky/
- Lint/config: .rubocop.yml, .scss-lint.yml, .rspec, rubocop/, .bundler-audit.yml,
  .annotaterb.yml, .all-contributorsrc, crowdin.yml, histoire.config.ts, etc.
- Stale frontend/pnpm-lock.yaml (replaced by root workspace lockfile)

Kept (frontend build essentials):
- app/javascript/ (all Vue SPA source — dashboard/widget/sdk/portal/superadmin/survey/v3)
- package.json, vite.config.ts, tailwind.config.js, postcss.config.js
- theme/, vitest.setup.js, .prettierrc

Key decoupling changes:
- vite.config.ts: removed vite-plugin-ruby, added explicit rollupOptions.input
  for all 7 entrypoints + dev-server proxy (/api,/platform,/cable,/health → GoChat)
- index.html: created static SPA entry that injects window.chatwootConfig /
  window.globalConfig (previously done by Rails ERB vueapp.html.erb)
- package.json: renamed @gochat/frontend, removed vite-plugin-ruby/histoire/husky,
  scripts now use plain vite dev/build
- tailwind.config.js: removed enterprise ERB content paths
- markdownEmbeds.js: relocated markdown_embeds.yml into app/javascript/dashboard/config/

Root pnpm workspace:
- package.json: dev:backend (air), dev:frontend (vite), dev (concurrently)
- pnpm-workspace.yaml: frontend as workspace package
- .gitignore: node_modules/, frontend/dist/, frontend build artifacts

Verified: pnpm install + vite build succeeds (4446 modules, all 7 entrypoints
produce JS+CSS chunks in dist/).
2026-07-07 15:37:24 +08:00
rogee 321c61aaae Vendor Chatwoot Vue 3 frontend into frontend/
Copy the Chatwoot (v4.14.0) frontend runnable subset into frontend/ for
customization:
- app/javascript/ (Vue SPA: dashboard, widget, sdk, portal, superadmin)
- app/views/ (ERB templates for vite-plugin-ruby entrypoint resolution)
- app/helpers/, app/assets/ (Rails view helpers, static assets)
- enterprise/ (Enterprise edition frontend overlay)
- config/vite.json, vite.config.ts, bin/vite (Vite-Rails toolchain)
- package.json, pnpm-lock.yaml, tailwind/postcss/eslint configs
- Gemfile, Gemfile.lock (vite_rails gem for bin/vite binstub)

Excluded Rails backend: controllers, models, services, jobs, mailers,
policies, db, lib, spec, public, node_modules.

Update references to the new frontend location:
- .gitignore: exclude frontend build artifacts (node_modules, tmp, packs),
  keep frontend/bin/ and frontend/vendor/ via negation
- backend/scripts/parity_frontend_smoke.sh: CHATWOOT_DIR default
  reference/chatwoot -> ../frontend
- backend/scripts/parity_frontend_browser_smoke.mjs: same default update
- AGENTS.md: add frontend section with Rails/Vite coupling notes
- README: architecture tree includes frontend/
2026-07-07 14:56:01 +08:00