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:
@@ -0,0 +1,35 @@
|
||||
"""voice_clip matched_friend_id
|
||||
|
||||
Revision ID: b3c4d5e6f7a8
|
||||
Revises: a1b2c3d4e5f6
|
||||
Create Date: 2026-08-10 00:00:00.000000
|
||||
|
||||
"""
|
||||
from collections.abc import Sequence
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = 'b3c4d5e6f7a8'
|
||||
down_revision: str | Sequence[str] | None = 'a1b2c3d4e5f6'
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
"""Upgrade schema."""
|
||||
# LOCAL-only 手动匹配 column: references customer.friend_id. NULL = unmatched.
|
||||
# batch_alter_table keeps this portable across SQLite (dev/test, table-recreate)
|
||||
# and MySQL (prod, direct ALTER). See env.py render_as_batch wiring.
|
||||
with op.batch_alter_table('voice_clip', schema=None) as batch_op:
|
||||
batch_op.add_column(
|
||||
sa.Column('matched_friend_id', sa.String(length=128), nullable=True)
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
"""Downgrade schema."""
|
||||
with op.batch_alter_table('voice_clip', schema=None) as batch_op:
|
||||
batch_op.drop_column('matched_friend_id')
|
||||
Reference in New Issue
Block a user