达人是唯一主档(Engagement),一次合作是达人 × 活动方向(Collaboration), 交付物逐条追踪(泳道)。功能分两半:CRM 聊天(零 LLM 依赖的地板)与 Studio 制片(L0→L3 渐进自动)。 本文是唯一权威设计;迁移见姊妹篇《迁移计划》。
| 词 | 定义 | 关键规则 |
|---|---|---|
| Engagement 达人主档 | 一个达人在系统里的唯一记录 | 议价成功、运营 pick 后建档;也可手动建/存量迁入。名下挂社媒组、联系方式组、Collaboration 组 |
| 社媒组 social profiles | 该达人的全部社媒账号 | 支持采集(tt/yt/ig/x)带指标(粉丝、近 12 条中位播放),可出建议报价;不支持的(snapchat 等)只记 handle+平台,供分发 |
| 联系方式组 contact methods | 达人本人 + 所属经纪的手机/邮箱 | 每条标 personal / agency;经纪方式可同时指派给旗下多个达人,不作身份合并键 |
| Collaboration 一次合作 | 达人 × Campaign 的一轮合作 | 复购(同 Campaign)、复用(跨 Campaign)都开新条,可并行;建档即快照(权益/整价/要求/限制),支持达人级字段 override |
| Deliverable 泳道 | 一条交付物,Studio 追踪的最小单位 | 阶段 = 全局超集 × Campaign 模板;挂具体社媒账号;全程消息引用可跳原文;创建 Collaboration 时至少播种一条 |
| Campaign 活动方向 | 合作的稳定归属容器 | 边界 = 提报总表/进度总表(8、9 月同表即同一个);有起止但时间不是边界;变更走「发布 → 订阅方更新」 |
| Scouting 招募批次 | Java 侧 campaign 的新名分 | 只读镜像,允许继续随意开;只用于溯源「这个人是哪一批找来的」,不参与业务判断 |
| CRM | 运营与达人的聊天工具 | threads 按 Campaign 分组;完全不依赖 LLM 也可用(翻译/润色类轻功能允许) |
| Studio 制片 | 智能与做片推进管理 | 泳道组界面 + 快捷操作;自动化 L0→L3 全局爬梯;高危/高难度由 LLM 判定转人工 |
库表命名:界面词 Engagement,数据库表暂名 coordinator_creator_relationships (旧 coordinator_engagements 迁移期仍存活,同库同词双义是事故源;旧表退役后再改名)。
Engagement(达人主档) │ ├─ 社媒组 ────────── 复用平台已有 creator_profiles(445 万行,含粉丝/中位播放,勿新建第三套) ├─ 联系方式组 ────── 新建 contact_methods + 指派表(personal / agency) └─ Collaboration[](并行) ├─ 快照 + override(权益 · 整价 · 要求 · 限制) ├─ Deliverable[](泳道,挂具体社媒账号) │ └─ 阶段事件(带消息引用)· artifacts · 分发 · 付款 └─ 对价与实付(账本) Campaign ←(发布变更)── 订阅 ──→ 各 Collaboration Scouting(旧 campaigns 表,只读)──→ collaboration.scouting_batch_id 溯源
平台已有 contacts(247 万,含 kind = person | agency 与合并机制)、 creator_profiles(445 万,指标齐全)、contact_relationships (15 万条经纪↔达人)。vNext 不再新建身份体系,只做接线 —— 这是全部工程量估算「20% 新模型、80% 接线」的来源。
-- 达人主档(界面词 Engagement) create table coordinator_creator_relationships ( id uuid primary key default gen_random_uuid(), creator_contact_id uuid not null references contacts(id), status text not null default 'active' check (status in ('active','paused','blocked','closed')), env text not null default 'live' check (env in ('live','sim')), created_at timestamptz not null default now(), unique (creator_contact_id, env), unique (id, creator_contact_id) ); -- 联系方式:方式归其真正主人(经纪邮箱归经纪 contact) create table contact_methods ( id uuid primary key default gen_random_uuid(), contact_id uuid not null references contacts(id), method_type text not null check (method_type in ('email','phone','whatsapp','wechat','telegram','other')), raw_value text not null, normalized_value text not null, label text, verification_status text not null default 'unverified', mergeable boolean not null default true, -- agency/共享信箱 false:不作身份合并键 valid_during tstzrange not null default tstzrange(now(),null,'[)'), unique (contact_id, method_type, normalized_value), unique (id, contact_id) ); -- 指派:这个方式「用于」哪个达人;personal / agency 标在这里 create table contact_method_assignments ( id uuid primary key default gen_random_uuid(), creator_contact_id uuid not null references contacts(id), contact_method_id uuid not null, method_owner_contact_id uuid not null, assignment_type text not null check (assignment_type in ('personal','agency')), source_relationship_id uuid references contact_relationships(id), valid_during tstzrange not null default tstzrange(now(),null,'[)'), is_primary boolean not null default false, foreign key (contact_method_id, method_owner_contact_id) references contact_methods(id, contact_id), check ((assignment_type='personal' and method_owner_contact_id = creator_contact_id and source_relationship_id is null) or (assignment_type='agency' and method_owner_contact_id <> creator_contact_id and source_relationship_id is not null)) );
-- Campaign:提报总表边界;运营本地建,不碰 Java create table coordinator_campaigns ( id uuid primary key default gen_random_uuid(), label text not null, client_name text not null, product_line text not null, starts_at date, ends_at date, -- 生命周期存在,但不定义边界 stage_template jsonb not null, -- 从全局阶段超集中启用哪些(§04) pricing_rules jsonb, -- 指标 → 建议起价(决定 11) benefits jsonb, requirements jsonb, restrictions jsonb, -- 统一管理的三类内容 created_by text not null, created_at timestamptz not null default now(), unique (client_name, product_line, label) ); -- Campaign 变更:保存 ≠ 生效,必须「发布」;订阅方逐条收敛 create table coordinator_campaign_releases ( id uuid primary key default gen_random_uuid(), campaign_id uuid not null references coordinator_campaigns(id), note text not null, diff jsonb not null, published_by text not null, published_at timestamptz not null default now() ); create table coordinator_collaboration_release_states ( collaboration_id uuid not null, release_id uuid not null references coordinator_campaign_releases(id), status text not null check (status in ('applied','pending_review','rejected')), resolved_by text, resolved_at timestamptz, primary key (collaboration_id, release_id) ); -- 一次合作:达人 × Campaign(无多达人打包 — 决定 1) create table coordinator_collaborations ( id uuid primary key default gen_random_uuid(), engagement_id uuid not null, -- → coordinator_creator_relationships creator_contact_id uuid not null, campaign_id uuid references coordinator_campaigns(id), -- 可空:临时合作/待归类 scouting_batch_id int references campaigns(id), -- 溯源,只读 lifecycle_status text not null check (lifecycle_status in ('draft','delivering','closed','dropped')), env text not null default 'live' check (env in ('live','sim')), snapshot jsonb not null, -- 建档快照:权益/整价/要求/限制 overrides jsonb not null default '{}', -- 达人级字段覆盖(如特殊发布要求) renewal_of_collaboration_id uuid references coordinator_collaborations(id), agreed_at timestamptz, closed_at timestamptz, legacy_engagement_id uuid unique, -- 存量迁入回指(NOT VALID FK) created_at timestamptz not null default now(), foreign key (engagement_id, creator_contact_id) references coordinator_creator_relationships(id, creator_contact_id), unique (id, engagement_id) );
-- 泳道:挂具体社媒账号;创建 Collaboration 时至少播种一条(provisional) create table coordinator_deliverables_v2 ( id uuid primary key default gen_random_uuid(), collaboration_id uuid not null, engagement_id uuid not null, creator_contact_id uuid not null, creator_profile_id uuid, -- 发布账号;签约后再定允许 null sequence int not null check (sequence > 0), deliverable_type text not null, -- 含 'provisional' 占位型 current_stage text not null, -- §04 超集之一 needs_script boolean not null default true, due_at timestamptz, foreign key (collaboration_id, engagement_id) references coordinator_collaborations(id, engagement_id), foreign key (creator_profile_id, creator_contact_id) references creator_profiles(id, creator_id), -- 前置:unique(id, creator_id) unique (collaboration_id, sequence), unique (id, collaboration_id) ); -- 阶段事件:每次推进一条,消息引用在此(hover/点击跳原文) create table coordinator_stage_events ( id uuid primary key default gen_random_uuid(), deliverable_id uuid not null references coordinator_deliverables_v2(id), stage text not null, action text not null, -- entered | revised | approved | blocked … waiting_on text check (waiting_on in ('us','kol','brand')), -- 等我们/等达人/等品牌 note text, source_message_ids uuid[] not null default '{}', -- 引用的聊天消息 actor text not null, -- operator:| studio:L1 … created_at timestamptz not null default now() ); -- artifacts:版本化,只存引用(脚本 v1/v2、样片、发布链接、物流单号) create table coordinator_deliverable_artifacts ( id uuid primary key default gen_random_uuid(), deliverable_id uuid not null references coordinator_deliverables_v2(id), kind text not null check (kind in ('product_pick','tracking_no','script','cut','publish_url','distribute_url','other')), version int not null default 1, uri text, content text, review_state text, source_message_id uuid, created_at timestamptz not null default now(), unique (deliverable_id, kind, version) ); -- 对价(含谈判中报价)与实付(append-only,幂等) create table coordinator_collaboration_considerations ( id uuid primary key default gen_random_uuid(), collaboration_id uuid not null references coordinator_collaborations(id), consideration_type text not null check (consideration_type in ('cash_package','cash_fee','barter','gift','commission','other')), side text not null default 'agreed' check (side in ('asked','offered','agreed')), amount numeric(19,4), currency char(3), description text, observed_at timestamptz not null default now(), source_message_id uuid, unique (id, collaboration_id), check ((amount is null) = (currency is null) and (amount is null or (amount >= 0 and currency::text ~ '^[A-Z]{3}$'))) ); create unique index one_agreed_package on coordinator_collaboration_considerations(collaboration_id) where consideration_type='cash_package' and side='agreed'; create table coordinator_collaboration_payments ( id uuid primary key default gen_random_uuid(), collaboration_id uuid not null references coordinator_collaborations(id), deliverable_id uuid, consideration_id uuid, payee_contact_id uuid not null references contacts(id), -- 可为经纪 amount numeric(19,4) not null check (amount >= 0), currency char(3) not null check (currency::text ~ '^[A-Z]{3}$'), direction text not null default 'outbound' check (direction in ('outbound','refund','chargeback')), source_kind text not null, -- chat_capture_confirmed | operator | payment_system(决定 9) source_ref text not null, -- 消息 id / 回执号 paid_at timestamptz not null, unique (source_kind, source_ref, direction), -- 幂等,回调重试不重复入账 foreign key (deliverable_id, collaboration_id) references coordinator_deliverables_v2(id, collaboration_id), foreign key (consideration_id, collaboration_id) references coordinator_collaboration_considerations(id, collaboration_id) );
-- thread 归属 = 可见性授予;可多条并存(决定 4/5) create table coordinator_thread_bindings ( id uuid primary key default gen_random_uuid(), thread_key text not null, -- channel:identity:conversation collaboration_id uuid not null references coordinator_collaborations(id), granted_from timestamptz not null default now(), -- 自绑定时刻起可见,不回溯 bound_by text not null, -- auto:new_email_thread | operator:released_at timestamptz, unique (thread_key, collaboration_id) );
| 渠道 | 归组方式 | 多活动同人 |
|---|---|---|
| 邮件 | 新活动开新 thread,建 thread 即绑定,零人工 | 天然分开(两个 thread) |
| WhatsApp / XDM | 未归属会话进「待绑定」,运营一键绑定到 Collaboration,自绑定时刻起生效 | 一个会话可绑多条,两边都显示 |
| 经纪信箱 | 邮件:请其按活动开多 thread;WA:同上绑定 | 同上;经纪方式 mergeable=false,永不触发身份合并 |
product_pick 选品 → sampling 寄样 → logistics 物流签收 → script 脚本* → script_rev 脚本修改*(多轮,每轮一条 stage_event) → cut 样片 → cut_rev 样片修改(多轮) → publish 发布 → distribute 分发(不支持采集的平台在此登记) → payment 付款 * needs_script=false 的泳道自动跳过;纯 gifting 模板可停用 payment; 软件类模板可停用 sampling/logistics。模板配置在 Campaign 上,泳道不允许自定义。
Campaign 上配 pricing_rules(平台 × 粉丝/中位播放区间 → 金额)。 泳道挂哪个社媒账号,就按那个账号的指标算 —— 同一个人 YT 与 IG 各算各的。 结果只作为建议起价展示;是否直接采用由运营(或 L2+ 的自动化)决定。
谈判上游(现系统,暂不动)──议价成功──▶ 运营 pick │ 也可:手动建档 / 存量 delivery 迁入 ▼ 若首次合作:建 Engagement(接线 contacts + creator_profiles + 联系方式组) 建 Collaboration:campaign_id + 快照(整价来自谈判结果,权益/要求/限制来自 Campaign) 按 Campaign 模板播种泳道(至少一条;数量按谈定的交付物拆) ▼ Studio 制片开始
编辑 Campaign(如:产品发货延误两周)→ 保存 ≠ 生效 ▼ 发布 release(note + diff) ▼ 订阅的每条 Collaboration 生成 release_state: ├─ 与达人 override 无冲突 → applied:快照更新、泳道排期顺延、时间线留痕 └─ 有冲突 → pending_review:待运营逐条确认
邮件:开新 thread ─▶ 生来绑定(零人工)
WhatsApp:未归属会话 ─▶ 运营绑定 ─▶ granted_from 起对该合作可见
同一会话双活动 ─▶ 两条 binding,两边都显示
L1+ 从聊天里采集付款信号(金额/币种/凭证)─▶ 生成待确认付款记录(带消息引用) 运营确认 ─▶ 落 payments(source_kind='chat_capture_confirmed') 将来接支付系统 ─▶ source_kind='payment_system',按实付自动对账「谈成 vs 实付」
定稿依据:12 项决定(2026-07-27 逐条拍板)。词表见 §01,冲突处以本文为准。
迁移路径:《迁移计划》 · 周会版:presentation