feat(calls): voice_clip 手动匹配(voice_clip↔customer 本地关联写操作)
- VoiceClip: 新增 matched_friend_id 列 (String(128), nullable) + alembic 迁移 b3c4d5e6f7a8
- PATCH /api/voice-clips/{id}/match: friend_id 关联 / null 取消 (本地写, 不回写云客)
- GET /api/voice-clips: 批量解析 matched_friend_name (remark>nickname>real>id)
- VoiceClipModal: 已匹配客户列 + 匹配/取消匹配按钮 + 嵌套客户选择 picker (默认按员工列客户, 名搜索走 /search)
- 测试: 17 passed (新增 7 个 match 用例覆盖 set/clear/name 解析/404)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -516,6 +516,12 @@ class VoiceClip(Base):
|
||||
duration_format: Mapped[str | None] = mapped_column(String(32), nullable=True)
|
||||
channel: Mapped[str] = mapped_column(String(16), nullable=False)
|
||||
|
||||
# LOCAL-only manual match: references customer.friend_id when an operator
|
||||
# has associated this clip with a specific customer (好友). NULL = unmatched.
|
||||
# The mirror never pushes this back to 云客 — it's our own bookkeeping for
|
||||
# the 手动匹配 UI (spec §7). Read paths resolve the customer name via join.
|
||||
matched_friend_id: Mapped[str | None] = mapped_column(String(128), nullable=True)
|
||||
|
||||
raw_json: Mapped[dict[str, Any] | None] = mapped_column(JSON, nullable=True)
|
||||
fetched_at: Mapped[dt.datetime] = _fetched_at()
|
||||
updated_at: Mapped[dt.datetime] = _updated_at()
|
||||
|
||||
Reference in New Issue
Block a user