fix(n8n): AList user/update requires username; hooks -> container-local; deploy script

- w1/w3-body: disable calls now send username + assert code===200
  (v3.63 validator rejects {id,disabled} with 400 -> silent no-disable)
- regenerated W1/W3 json, deployed live via REST API, activeVersionId re-aligned
- NocoDB hooks repointed to http://n8n:5678 (old auto.hoelee.com chain loses
  events on VPS stalls; W2 hook path was also 404 since creation)
- deploy_w1_w3.mjs: reusable PUT deploy via n8n API key from SECRETS.md
- PROJECT_STATE: e2e verification results + updated next steps
This commit is contained in:
2026-08-25 05:17:46 +08:00
parent fd62775fcd
commit 773fd3f2d5
7 changed files with 71 additions and 19 deletions
+31 -13
View File
@@ -1,4 +1,4 @@
# Project State (Handoff) — 2026-08-24
# Project State (Handoff) — 2026-08-25
> 交接文档:压缩/新会话后按此续做。**入口顺序:AGENTS.md → 本文件 → SECRETS.md(凭据)。**
> 本文件只记「状态与下一步」;API 怪癖/坑的唯一权威 = Hermes skill `alist-serve-resource` + `docs/API_INTEGRATION.md`。
@@ -7,15 +7,24 @@
全部集中在根目录 **`SECRETS.md`**(唯一凭据文件;把项目给别人 = 删它即可)。
表 ID / workflow ID 不是机密,见 `docs/DATABASE_SCHEMA.md` 与下文。
## 系统现状(2026-08-24 实测)
- 容器全绿:`alist-serve-resource`(healthy) · `nocodb` · `n8n`
- W1–W4 四个 workflow 激活正常(postgres 复核 `activeVersionId` 全对齐)
## 系统现状(2026-08-25 实测)
- 容器全绿:`alist-serve-resource`(healthy) · `nocodb` · `n8n` · `nginx-limit-alist` · `traefik-update-alist`(08-25 全部 redeploy)
- **公网上线 ✅**:`https://drive.digikedai.com` 经 CF Tunnel 全链路实测通
(/ping pong、/ 与 /login 均 200 AList SPA、/@manage 403 防护有效)
- W1–W4 四个 workflow 激活正常(postgres 复核 `activeVersionId` 全对齐;08-25 PUT 更新后仍对齐)
- **端到端实测通过 ✅(08-25)**:真实业务事件全链路——建 Customer→W1 自动开通+写回;
建 CP→W2 自动算 scopes(`/Class/Forex`);AList 真实登录/范围内 200/范围外 403;
CP 到期→W3 sweep 收权;Customer suspended→W1 禁用(客户 token 全 API 401);
active 恢复→重启用重算;人为漂移→W4 dryRun 只报告不写入 / 正式跑修复且幂等。
- **08-25 三处基础设施修复**:① AList `/user/update` 必须带 `username`(否则 400 静默不禁用)
→ w1/w3-body.js 已修并部署;② NocoDB 两 hook 改指 `http://n8n:5678`(原 auto.hoelee.com
走旧公网链路,VPS 卡顿时事件静默丢失),W2 hook 路径 `alist-cp-sync`→`alist-customerproduct-sync`
(原来一直 404);③ n8n API key 已入档 SECRETS.md。
- **n8n「执行消失」已结案**:容器 env `EXECUTIONS_DATA_SAVE_ON_SUCCESS=none`,成功执行不落库是配置使然,管道健康(详见下方结案记录)
- NocoDB 数据:Products 176 / Resources 171(商品目录健在);Customers / CustomerProducts / AccessGrants / ReconcileLogs = **0**(旧测试数据已被清空)
- AList 已清理至干净态:仅 guest/hoelee 用户 + guest/admin 角色
- NocoDB 数据:Products 176 / Resources 171(商品目录健在);Customers/CustomerProducts 测试数据已清空(残留 1 行上个会话的 `e2e_test_01` 待用户处置);AList 仅 guest/hoelee(+e2e_test_01 残留)
## 已完成 ✅(细节见各 DESIGN 文档与 git log)
1. **Phase 1** AList stock v3.63.0 :5244(bridge_hoelee,4 只读挂载;旧 alist :5243 未处理)
1. **Phase 1** AList stock v3.63.0 :5244(bridge_hoelee,4 只读挂载;旧 alist 已下线,compose 内注释保留)
2. **Phase 2** NocoDB base `AlistAccess`(`p3lzkresswyowqg`) 8 表(7 业务 + ReconcileLogs);脚本 `scripts/create_nocodb_schema.py` / `add_reconcilelogs_table.py`
3. **W1** 客户开通 + 5 状态 lifecycle(pending/active/suspended/expired/deleted)— 实测跑通;old/new 字段比对 loop guard + `sync_required` 强制重算 + writeBack 值比对守卫(`test_w1_lifecycle.js` 10 场景全过)
4. **W2** CustomerProduct 权限同步(调共享算法)— 实测跑通
@@ -23,15 +32,24 @@
6. **共享库** `n8n/shared/effective-grants.js` 单一事实源,构建期内联(`gen_w*.js`),三 workflow 零复制算法;union 语义:CP 派生 ∪ AccessGrants,同 path 取 MAX(expires_at),expiry 边界 `<= today`
7. **W4** 每日 03:00 全量对账 + ReconcileLogs 审计 — 本地 + 直连生产实测通过(dry-run→repair→复跑幂等;34 项 mock 测试过);单向同步 NocoDB=SOT,密码不随 repair 推送(方案 C)
8. 文档体系:ARCHITECTURE / PERMISSIONS / ADMIN_GUIDE / DATABASE_SCHEMA / N8N_WORKFLOWS 等;git 已推 Gitea
9. **公网链路切换(08-25)**:DSM 文件统一收进 `/volume1/docker/alist-digikedai/`(容器名全部未动——n8n `ALIST_URL` 硬依赖);CF Tunnel `drive.digikedai.com` 回源 `http://172.16.0.1:5246`;traefik 删除 `/login`→n8n 劫持路由(曾致登录页挂起);nginx 移除 drive 域不限速白名单(现吃默认 1.5MB/s + limit_conn 10/IP)。完整记录 = DSM `/volume1/docker/alist-digikedai/alist-serve-resource/NETWORK_ARCHITECTURE.md`
## 🔴 下一步(按序)
1. **端到端实测(最优先)**:建测试客户走完 W1(provision)→W2(sync)→W3(sweep)。验证看 AList/NocoDB 的实际状态变化,别数 executions 表
2. **补 n8n env 并 rebuild(Portainer stack 144)**:`NOCODB_TABLE_RECONCILELOGS=mktsb7le6fqr2u1` + `NOCODB_FK_RECONCILELOG_CUSTOMER=nc_jitu___Customers_id`(改 env 必须 rebuild,restart 无效)
3. AccessGrants 不物化(保持手工人为授权入口,n8n 永不写)— 已定案
4. 密码保持方案 C(客户可自改 AList 密码 → NocoDB plaintext 失真;不强制回写)
5. 公网域名 `nocodb.hoelee.com` 连通未恢复(DSM 内网端口全正常)— 待查 DNS / 隧道
1. **补 n8n env 并 rebuild(Portainer stack 144,改 env 必须 rebuild)**:`NOCODB_TABLE_RECONCILELOGS=mktsb7le6fqr2u1` + `NOCODB_FK_RECONCILELOG_CUSTOMER=nc_jitu___Customers_id`(W4 审计落库当前被跳过);顺手加 `TZ=Asia/Kuala_Lumpur` 修 UTC 时区
2. **决策:auto.hoelee.com 是否退役/迁移**——n8n 公网访问现在只剩 UI 用途;hook 已容器化。若保留,建议迁到 CF Tunnel 新链路;若退役,同步删 VPS DNS + DSM 反代条目
3. **清理上个会话残留**:NocoDB Customer Id=8 `e2e_test_01` + AList user 17 / role `customer-e2e_test_01`
4. 公网限速实测:经 CF 后确认 nginx 限速按访客真实 IP 计(若 key 变 docker 内网 IP 全员共享一桶 → 调 traefik ipStrategy depth / nginx XFF)
5. 旧链路退役清理:旧 alist 数据目录、DSM 反代 access.hoelee.com 条目、VPS DNS、compose 注释块择机删
6. AList site_url 设为 `https://drive.digikedai.com`(分享链接需要)
7. 密码保持方案 C(客户可自改 AList 密码 → NocoDB plaintext 失真;不强制回写)
8. W2 不写 CP bookkeeping(sync_status/last_sync 永不更新)——现状可用;若未来有逻辑依赖这些字段再补写回节点
## 结案记录
- **CF Tunnel drive.digikedai.com 打不通(08-25 发现 → 当日结案)**
- 现象:公网 TCP/TLS 能建立但 HTTP 层零响应超时;DSM 内部链路对任意 Host 头都正常 → 不是 hostname 检查
- 根因:cloudflared 在 bridge_hoelee 网络,**容器→宿主机自身 LAN IP (192.168.1.1:5246) 被 DSM 防火墙 hairpin 丢弃**(日志 `dial tcp ... i/o timeout`);同隧道其他站点源是别的机器所以没事
- 修复:CF Dashboard 回源改 `http://172.16.0.1:5246`(docker0 网关=宿主机),实测公网 pong。备选:容器 DNS 名 `nginx-limit-alist:5246`
- 同场加映:traefik `rtr-alist-login` 把 GET /login 劫持到 n8n(:5678),n8n 无此路由 → 登录页挂起 499。已删路由 + 孤儿 middleware `mw-webhook-user-rewrite`(备份 dynamic.yml.bak-20260825)
- **n8n 执行管道停摆(08-23 报告 → 08-24 结案,误报)**
- 现象:webhook 全 200 但 executions 表零记录、schedule 无痕迹
- 根因:`EXECUTIONS_DATA_SAVE_ON_SUCCESS=none` → 成功执行从不落库,只有 error 会记(期间唯一入库记录恰是一条无关备份 workflow 的 error,完全吻合)
@@ -43,7 +61,7 @@
- AList:空 role 建用户必 400(先建 role)|base_path 必须 `/` 否则双重前缀全 403|delete 用 `?id=`|裸 token 无 Bearer
- NocoDB:link 查询必须 `(link.Id,eq,N)`|写 bt 链接要写 FK 列 `nc_jitu___*_id`|删行 DELETE+body|v1 列端点已废|SingleSelect 先建空列再 PATCH
- n8n:Code 节点 `$env` 可用、HTTP 表达式不行(Load Env 模式)|API 导入节点 id 必须 UUID 且顶层无 pinData|webhook 节点缺 webhookId 则生产 URL 不注册|激活真标志=DB 的 activeVersionId|执行消失假象=SAVE_ON_SUCCESS
- 环境:DSM IP 会漂移(连不上先探测)|DSM sshd 无 SFTP(POST body 用 stdin pipe 传)
- 环境:DSM IP 会漂移(连不上先探测,08-25 起在 192.168.137.2)|DSM sshd 无 SFTP(POST body 用 stdin pipe 传)|**容器→宿主 LAN IP 被 hairpin 丢包,回宿主机服务用 172.16.0.1 或容器 DNS 名**
> **Status 语义已定稿**:`pending/active/suspended/expired/deleted`,account-level 整户开关,
> **不进** permission calc。详见 `docs/ARCHITECTURE.md`、`docs/PERMISSIONS.md`、`docs/DATABASE_SCHEMA.md`。