Files

2.0 KiB
Raw Permalink Blame History

W2 — CustomerProduct 变更 → 同步 AList Role Scopes

事件驱动:NocoDB CustomerProducts 表 webhook → n8n webhook → 重取记录 → 全量重算该 customer 的 effective grants → diff AList role scopes → apply → 物化 AccessGrants + 回写 sync_status。

核心逻辑(desired-state,规格 §19/§37)

  1. webhook 只带 record Id,n8n GET /api/v2/tables/{CustomerProducts}/records/{Id} 重取完整记录。
  2. 从记录解析 customer link(NocoDB link 字段返回关联行 Id + display value); 若返回对象数组,取第一个的 Id。
  3. 拉取该 customer 所有 status=active 且未过期 的 CustomerProducts。
  4. 每个 CP → product link → Product;再走 Products 的 M2M link 列 c4ko4x8kwi16swg(GET /api/v2/tables/{Products}/links/c4ko4x8kwi16swg/records/{pid}) 取该 Product 的全部 Resources(含 alist_path)。
  5. 汇总:alist_path -> MAX(expires_at)(多 Product 重叠取最晚;规格 §18「取最大值」)。
  6. 取 customer 的 alist_role_id → GET /api/admin/role/get?id= 读当前 scopes。
  7. diff:desired paths vs 当前 scopes → 要加 / 要删。
  8. POST /api/admin/role/update 整体重写 permission_scopes(幂等)。
  9. 物化 AccessGrants:删掉该 customer 的 product 源 grants,重插 desired(manual 源保留不动)。
  10. 回写 CustomerProducts 各记录 sync_status=synced + last_sync。

关键 fact(已验证)

  • NocoDB link 字段在 v2 records GET 返回形如 {"customer": {"Id": 5, "username": "..."}} 或 [{"Id":5}]; Code 节点需兼容两种。
  • AList role create/update 返回 data:null;role/get 可回读 scopes。
  • permission=0(read-only bitmask);role scope 用 {path, permission:0}。
  • M2M link col id: Products.Resources = c4ko4x8kwi16swg。

首期不做

  • expiry 定时扫描/移除(W1/W2 验证后再加)
  • 密码 change-detection 的 password_updated_at 触发逻辑(W1 已留字段)