Files
alist-serve-resource/docs/ARCHITECTURE.md
T
hoelee 80eb2b71be docs: architecture, permissions, admin guide + refresh schema/workflows
- New ARCHITECTURE.md (3-layer model + data flow + lifecycle matrix)
- New PERMISSIONS.md (grant calculation rules + enforcement)
- New ADMIN_GUIDE.md (華文极简:Customer/CustomerProduct 授权 + Product/Resource 管理)
- Rewrite N8N_WORKFLOWS.md from WF1-6 (obsolete) to actual W1/W2/W3
- Update DATABASE_SCHEMA.md: fix status enum (drop 'disabled'), add 5-status semantics
- Update README.md doc index
2026-08-23 07:30:41 +08:00

3.7 KiB
Raw Blame History

架构说明(Architecture)

本文解释系统的分层职责与数据流。更新日期 2026-08-23。

三层职责(核心心智模型)

层 载体 职责 谁改它
Account lifecycle Customers.status 账户整体状态开关(active / pending / suspended / expired / deleted) 管理员手工
Product entitlement CustomerProducts + Products + Resources 「这个客户买了哪些产品 → 能访问哪些路径」+ 每个产品的到期时间 管理员手工
Effective permission AList Role permission_scopes 最终生效的路径授权(由 n8n 从上面两层计算出来,写到 AList) 仅 n8n,管理员不直接碰
Customers.status          (account-level:整户开关)
      +
CustomerProducts          (product entitlement:买了什么、何时到期)
      +
Product → Resources       (产品包含哪些路径)
      +
CustomerProduct.expires_at
      ↓
calculateEffectiveGrants   (n8n 共享算法,单一事实源)
      ↓
AList Role.permission_scopes  (effective/materialized permission)

关键原则

  1. Customers.status 不进入权限计算。它只决定「整户开关」:

    • active → 允许计算并应用 grants
    • pending / suspended / expired / deleted → AList user disabled + scopes 清空(账户级封禁)
    • 权限的「细粒度」永远来自 CustomerProducts 的到期时间,不由 status 替代。
  2. AccessGrants 是预留的物化表,当前不经 n8n 写入。将来(W4)可用于 reconciliation 日志/物化审计,但现在不作为 source-of-truth,也不参与计算。

  3. n8n 是同步器,不是 SOT。Source of Truth = NocoDB;AList 只做 enforcement。

数据流

管理员在 NocoDB 改 Customers.status 或 CustomerProducts
        │  (NocoDB webhook:after insert / after update)
        ▼
n8n W1 (Customer webhook)       ── 处理整户 status lifecycle
n8n W2 (CustomerProduct webhook) ── 重算该客有效 grants 并应用
n8n W3 (每 5 分钟 schedule)      ── 全量对账:重算所有客户,修 drift
        │
        ▼
AList Admin API(role/update 写 permission_scopes;user/update 写 disabled)
  • W1 单一 Code 节点:provision + status lifecycle(5 状态)+ 幂等 write-back。
  • W2 单一 Code 节点:CustomerProduct 变更 → 重算该客 grants → diff → 应用。
  • W3 单一 Code 节点:全量 sweep,逐客调共享算法,diff 后应用;支持 dry-run / auto-disable 开关。

三个 workflow 共用同一个 calculateEffectiveGrants(n8n/shared/effective-grants.js,构建时内联),保证三处算法零复制、零漂移。

Status lifecycle(W1)

status AList user scopes 说明
pending(无 user) —(不建) — 纯标签,customer 未正式开通
pending/suspended/expired/deleted(有 user) disabled 清空 账户级封禁,soft,保留历史
active(无 user) 新建 + enabled 计算应用 首次开通
active(有 user) re-enable 重算 + 应用 恢复/续期,永不恢复旧值
任意 X → active enable 重算(仅当前有效) resume,忽略已过期产品

Loop 防护

  • n8n 只写回 bookkeeping 字段(alist_user_id/alist_role_id/sync_status/sync_required/last_sync/last_sync_error)。
  • W1 用 old/new field comparison(NocoDB webhook 的 previous_rows vs rows)区分「管理员业务变更」vs「自己的 write-back echo」:echo 直接短路,零 PATCH。
  • writeBack() 有值比对守卫:字段值没变就不发 PATCH,从物理上掐断 echo loop。