- 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
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
- 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
- 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.
- 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.
- 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
- Strengthen WeComSyncTest personType assertion by seeding a value (3)
that differs from what resolvePersonType(user001/INTERNAL) would assign (1),
so the test actually detects an overwrite.
- Remove redundant personMapper/conversationMapper selectById calls in
upsertContact and upsertConversation; preserve original business fields
by reading them from the already-loaded entity before mutation.
- Delete the manual regression shell script; the unit tests are the primary
verification and the script required manual DB edits and only covered
conversation fields.
- New module: mci-channel-wechat-personal
- Implements ChannelAdapter SPI for personal WeChat
- Calls Python channel-service pywechat HTTP APIs:
- /v1/wechat-personal/login/start for initAccount QR code
- /v1/wechat-personal/send/text and /send/image for sendMessage
- Configurable base URL via sino.channel.wechat-personal.base-url
- Added MockWebServer unit tests
- Wired module into backend parent and mci-server
- Merge infrastructure/docker-compose.yml + docker-compose.app.yml into root docker-compose.yml with profiles (infra/app).
- Add healthchecks for mysql/redis/rabbitmq/mci-server/channel-service and depends_on conditions.
- Rewrite scripts/local-up.sh to use profiles and wait for healthy states.
- Add curl to mci-server and channel-service Docker images for healthchecks.
- Add npm test script to admin-web (type-check + build smoke test).
- Add scripts/test-external-api.sh covering 11 API endpoints.
- Verify Java (7/7), Python (6/6), npm build, external API (11/11), and UI flows.
- Add admin-web/ with Vite + Vue 3 + Element Plus + Vue Router
- Add 8 management pages: dashboard, channel subject/account, conversation,
person, tag, send record (with test send), inbound flow
- Add API client modules for account/channel/crm/send/flow
- Add Dockerfile and nginx config for admin-web
- Add Dockerfile for mci-server
- Add docker-compose.app.yml for one-command app deployment
- Add K8s deployment manifests for backend/admin-web/channel-service
- Update scripts/local-up.sh with shared network and --with-apps option