人员名单归一 · 方案

SalesRoomRe · 2026-08-03 · 病因=用名字当外键;prod 20 个成员收不到消息

病因就一句话:这套系统用「名字」当外键

Prod 实锤 —— 同一个人,因为一个空格,在系统里是两个人:

在收消息的名单里在组织成员名单里
Alex (彦序) ← 有空格Alex(彦序) ← 没空格
傅丰凯付丰恺

所以才需要 recipient-aliases.json 人肉打补丁 —— 而补丁永远追不上

和 7 月客户那边是同一个病。アトレ / アトレ_GBaseSupport 名字漂移 → pipeline fail-close → 最后靠 migration 0039 改成用 customers.id
客户那边已经付过代价改成 id 了,人这边还在用名字。

Prod 现在正在发生的事

DB 组织成员
28
config.yaml 名单
47
在组织里 · 收不到消息
20
不在组织里 · 在收消息
4

20 个正式成员收不到任何消息(你自己也在这份名单里)。 同时 傅丰凯(MiniBee 的开发)在收销售消息。

47 不是销售人数,是历史堆积 —— 里面有 Admin、开发、测试号。28 才是真的。

目标:一份名单,用 id 连

属于哪个组织

members_sync 镜像

sales_owner_id

发给谁

CONTROL_USERS

string

id

PK

UUID · 跨组织唯一

string

email

身份

string

name

展示用 · 不当外键

MEMBERSHIPS

RUNS_USERS

string

id

PK

= control UUID

string

display_names

别名 · 盒子画像

int

cp_user

1=成员 0=历史画像

int

notify

新增 · 收不收消息

string

lark_open_id

新增 · 渠道绑定

string

lark_bound_at

新增 · 确认送达才算绑定

CUSTOMERS

string

id

PK

string

sales_owner_id

FK

新增 · 现在存的是名字

DELIVERIES

string

id

PK

string

user_id

FK

发给谁

string

channel

lark 或 teams

string

status

sent 或 failed

string

error

失败原因

决定
不建 user_channels渠道绑定就是 runs_users 上的两列。多一张表 = 多一处会漂移的地方
notify 放 runs.db盒子级偏好 —— 同一个人在 A 组织要收、B 组织不要收,是合理的
sales_owner_id 是 FK现在 profile.md 里存的是名字。这就是 #201 那个病

四步(原方案的「补 membership」整个删掉)

做什么效果
1 notify 挪进 DB,只给那 28 人
按 name + display_names 匹配一次,匹配不上的**列出来人工过**,不静默跳过
立刻修好「20 人收不到」
顺带把 4 个非成员摘掉
2 收件人解析改用 user_id
纯函数层 worker/lib/org_members.py,和 mail_query.py 同形
根治。名字只用来显示,不再当外键
3 废弃 config.yaml team.members + org-members.json
先停止读,观察两周再删
四份 → 一份
4 Mio 的花名册改走 MCP list_org_members JSON 退役后 Mio 不会拿着死指针

⚠️ prod 新盒子(spt-fde)根本没有 config.yaml / org-members.json —— 新架构其实已经不生成它们了,只是老盒子还留着。这佐证了「废弃」而不是「合并」。

之后才轮到消息推送那条线

第 0 步 · 名单归一

身份绑定
销售 ↔ Lark

路由三档
owner / 组织者 / 待认领

送达落库 + 统计 tab

投递层抽象
Lark + Teams 骨架

通知粒度 + 管理 UI

绕开第 0 步先做后面任何一条,产出的都是建在名字匹配上的第五份名单。

一个要现在决定的 prod 正在漏

20 个人收不到消息,是此刻正在发生的事,不是设计问题。

选项
先单独修这一条
手工把 28 人补进 config.yaml 的 notify
半小时,立刻止血。但那是往要废弃的文件里加东西 —— 做完还得再迁一次
直接做第 1 步一两天,做完就是终局。但这一两天里那 20 人继续收不到

我倾向直接做第 1 步 —— 这个状态已经存在了一段时间(config.yaml 是 5 月的), 再多一两天不改变性质;而往废弃文件里加东西,是在给自己造第二次迁移。
但如果你觉得这两天有要紧的通知会漏,那就先止血。你拍。

Generated as a visual answer · open in browser