Commit Graph

109 Commits

Author SHA1 Message Date
f108465d4f fix(plan/ui): correct screenshot extension and align bot ext_info guard with backend 2026-07-15 14:06:39 +08:00
1378649fc7 docs(plan): correct admin-web routes and reduce webhook URL parse noise 2026-07-15 14:02:21 +08:00
d4b48fb611 docs(testing): e2e verification report for send routing with WECOM_BOT 2026-07-15 13:55:26 +08:00
0ad12c6df6 fix(send): extract webhook_url from JSON ext_info for WECOM_BOT 2026-07-15 13:35:44 +08:00
168cd2de11 fix(send-routing): address re-review issues
- Set conversationScene=EXTERNAL in SendEndToEndTest and align account to WECHAT_PERSONAL
- Replace literal account type code with AccountType.WECHAT_PERSONAL.getCode()
- Use replaceFirst for webhook URL placeholder in WeComBotSender
- Remove unused selectDefaultAccount overload
- Hide scene selector for single-chat conversations in admin-web
2026-07-15 12:08:56 +08:00
0a326e7ff9 fix(send-routing): address final code review findings
- WeComBotSender.resolveWebhookUrl: use custom URL as-is when no %s placeholder
- WeComBotSender: treat unparseable/blank response body as failure
- ConversationService.isAccountCompatibleWithConversation: ignore scene for single chats
- SendService.selectSendAccountCandidates: apply accountTypes filter for non-conversation records
- SendService: replace account type magic numbers with AccountType constants
- WeComChannelAdapter: use AccountType.WECOM_BOT.getCode() instead of literal 6
- admin-web Conversation.vue: fallback to channelType filter when scene is unset
- add tests for single-chat null scene, webhook_url propagation, and custom URL without %s
2026-07-15 11:53:51 +08:00
c24891a82e fix(send): use stored WECOM_BOT webhook URL and preserve single-chat routing without scene
- Copy account.ext_info into extra.webhook_url for WECOM_BOT sends.
- Allow null conversation_scene for single chats; only enforce scene-based routing for group chats.
- Harden WeComBotSender custom URL handling when placeholder is missing.
2026-07-14 18:45:48 +08:00
11ee7384b3 fix(send-routing): address final review findings
- Persist conversationScene in create/update conversation
- Make bindAccount validate by conversation scene (1=WECOM_BOT, 2=WECHAT_PERSONAL)
- Re-derive channelType from conversation_scene in dispatchRecord
- Check WeCom response errcode and HTTP status in WeComBotSender
- Support custom webhook_url from ext_info in WeComBotSender
- Configure RestTemplate with 5s connect / 10s read timeouts
- Expand WeComBotSenderTest with MockRestServiceServer coverage
2026-07-14 18:35:50 +08:00
e1c7c582ee test(send): integration tests for scene-based routing 2026-07-14 18:08:05 +08:00
128df39113 feat(admin): conversation scene and account binding by scene 2026-07-14 18:00:45 +08:00
687269cce6 feat(admin): support WECOM_BOT account creation 2026-07-14 17:56:11 +08:00
c4caf48bad feat(sync): default WeCom-synced groups to external scene 2026-07-14 17:50:51 +08:00
3a8d51b0df fix(send): remove out-of-scope tag/combined-target logic and revert conversationId handling
Task 5 (aeb14cf) correctly added scene/person-based automatic routing,
but also introduced tag/combined-target features and changed doSendAttempt
conversationId handling that were not in the task brief.

This commit reverts those out-of-scope changes while keeping the
scene/person routing and account-type selection that belong to Task 5:
- Revert tag target resolution to single-tag logic (no tag_ids/inner_logic)
- Remove combined target type and all helper methods
- Revert doSendAttempt conversationId to use record.conversationId directly
- Keep conversation_scene routing, person_type routing, and account-type helpers
2026-07-14 17:44:48 +08:00
aeb14cfa30 feat(send): route by conversation_scene and person_type 2026-07-14 17:33:09 +08:00
ed76915f56 feat(selector): filter send accounts by account type 2026-07-14 17:21:55 +08:00
0bef33bbb8 feat(wecom): add group bot webhook sender and dispatch by account type 2026-07-14 17:15:32 +08:00
4bc643024d feat(conversation): add conversation_scene field 2026-07-14 17:08:35 +08:00
895c78d60e feat(channel): add WECOM_BOT account type 2026-07-14 17:05:27 +08:00
93df416954 docs(agents): 补充 IDE 本地调试说明 2026-07-13 14:34:49 +08:00
0e8d3f61d4 docs(agents): 补充 .env 环境切换与本地启动使用说明 2026-07-13 14:26:39 +08:00
0bf48fd449 chore: 统一环境配置,支持 .env 快速切换本地/远程基础设施 2026-07-13 14:17:49 +08:00
8c4deb5be4 chore: 集成初始化 SQL 导入到 local-up.sh,导出默认及全量初始化数据 2026-07-13 10:29:44 +08:00
31d4a34ebb feat: 新增渠道身份菜单、会话成员/标签展示、修复群聊成员 person_type 及重复同步问题 2026-07-13 09:38:03 +08:00
749856c455 fix(test): 为 ChannelAccountEventControllerTest 添加 @Transactional,防止测试 SQL 清空开发库渠道账号数据 2026-07-10 16:29:23 +08:00
758ed73f9d fix: 渠道账号群聊同步缓存 key 及成员名称兜底;统一 Docker/Maven 项目约定 2026-07-10 15:55:30 +08:00
560bd4599b fix(channel): accept snake_case event request fields from channel-service 2026-07-10 12:33:24 +08:00
3b8cde2995 chore(docker): add channel-service event store config and volume 2026-07-10 12:26:31 +08:00
82d1450182 feat(send): pass record_id and tenant_code, accept async response 2026-07-10 12:26:05 +08:00
302e0ab442 feat(channel): add channel account event receiver endpoint 2026-07-10 12:24:00 +08:00
1fabc04d70 feat(channel): add event handling service 2026-07-10 12:21:33 +08:00
e3bae8aa1f feat(db): add channel event record idempotency table 2026-07-10 12:20:35 +08:00
4b0780c181 feat(event): add daily cleanup for delivered/dead-letter events 2026-07-10 12:19:43 +08:00
c3aefc97de feat(main): start and stop event publisher worker 2026-07-10 12:19:14 +08:00
1641553d31 feat(send): async acceptance and send_result event 2026-07-10 12:18:54 +08:00
1d2948677e feat(login): emit login and online status events 2026-07-10 12:16:27 +08:00
2f4783f1f9 feat(heartbeat): emit heartbeat event to SQLite 2026-07-10 12:11:18 +08:00
0cf57bfaca feat(config): add event publisher settings 2026-07-10 12:09:27 +08:00
0e6f7a3072 feat(event): add single-thread event publisher with retry and cleanup 2026-07-10 12:08:24 +08:00
96ec929378 feat(client): add mci-server event poster 2026-07-10 12:06:21 +08:00
41cb52daa1 feat(event): add SQLite outbound event store 2026-07-10 12:06:19 +08:00
b2e5cc187c feat(event): add outbound event models 2026-07-10 12:00:08 +08:00
b0624126ad docs: add system menu redesign spec 2026-07-09 10:53:08 +08:00
78a46977ba fix(channel-conversation): address code review issues for Task 5
- Make frontend account filter case-insensitive in Conversation.vue
- Warn when bind dialog is submitted without selecting an account
- Reuse AccountSelector.isHealthy in resolvePersonTarget
- Expand ConversationService.bindAccount unit tests
- Update channel mismatch assertion in SendServiceResolveTargetTest
- Move currentConversationId declaration near tag binding state
2026-07-08 17:58:35 +08:00
2cdbc662f3 feat(send-record): support tag and rule targets in test send
- Add tag/rule options to the target type selector.
- Show tag selector + scope selector (all/conversation/person) for tag targets.
- Show rule JSON textarea for rule targets.
- Load tag list on mount.
- Update buildTargetValue to build tag_id/scope and parsed rule payloads.
2026-07-08 17:48:53 +08:00
ec0733cb28 feat(ui): conversation account binding for send/receive primary/backup
- Filter account selector by conversation channelType
- Add sortOrder priority input
- Use currentBindConversation ref for binding context
2026-07-08 17:48:31 +08:00
fc6dbb2ca3 fix(send): apply AccountSelector health checks to fallback owner account and add person-target validation tests
- Make AccountSelector.isHealthy public static so SendService can reuse it.
- Use isHealthy for the resolved/fallback conversation account instead of
  a weaker existence/status/channel check, covering risk level and PYWECHAT
  heartbeat/online status.
- Add null-safe channel-type comparison in resolvePersonTarget.
- Add @Min(0) to BindConversationAccountRequest.sortOrder.
- Rename misleading conversation fallback test and add tests for
  resolvePersonTarget disabled/cross-tenant/channel-mismatch cases.
- Remove unused java.util.Arrays import from test file.
2026-07-08 17:42:51 +08:00
ed7c64de7c fix(channel/send): restore AccountSelector delegation and validate conversation account binding
- SendService.selectSendAccount now delegates to AccountSelector with
  extractStrategy(channelStrategy) instead of an inline filter that only
  checked tenant/status, restoring risk/online/heartbeat checks.
- ConversationService.bindAccount validates the account exists, belongs
  to the same tenant, and matches the conversation channel type before
  creating the binding.
- Add unit tests for ConversationService.bindAccount validation and
  SendService.resolveConversationTarget strategy/health behaviors.
2026-07-08 17:31:18 +08:00
6288f0a305 feat(channel/send): support all 4 binding types and validate send targets
- BindConversationAccountRequest: restrict bindingType to 1-4
- ConversationService.bindAccount: upsert binding by account+conversation+type with sortOrder and status=1
- SendService.selectSendAccount: prefer send-primary(1), fallback send-backup(2), status=1, tenant/channel match, sortOrder asc
- SendService.resolveConversationTarget/resolvePersonTarget: verify account tenant, channel type and status; ensure person identity channel type matches for single chat
2026-07-08 17:08:38 +08:00
1298a558e8 wip: baseline changes before channel-conversation-task boundary implementation 2026-07-08 16:23:09 +08:00
89c9e6a066 fix(channel): add null guard when loading person during sync 2026-07-08 16:07:26 +08:00