From 594b950f9552e2635d4ac51189e3d3e3a7ac21a4 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 21 Jul 2026 17:14:24 +0000 Subject: [PATCH 1/6] =?UTF-8?q?fix(tools):=20check-catalog.js=20=E6=94=B9?= =?UTF-8?q?=E7=94=A8=20CommonJS=20require,=E4=BF=AE=E5=A4=8D=20CI=20?= =?UTF-8?q?=E5=B4=A9=E6=BA=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根目录 package.json 未声明 "type": "module",check-catalog.js 却用 ESM import 语法,导致 node 直接执行时抛出 "SyntaxError: Cannot use import statement outside a module"。 tools/ 下其余脚本均为 CommonJS,统一风格并修复 check-ootb CI 检查项。 Co-authored-by: Shiroha --- tools/check-catalog.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tools/check-catalog.js b/tools/check-catalog.js index 26a3f4a..c40ef52 100644 --- a/tools/check-catalog.js +++ b/tools/check-catalog.js @@ -11,12 +11,10 @@ * - entry.init 仅在 sapi 类型可选 * - 不允许循环依赖(拓扑排序检测) */ -import { accessSync, constants, readFileSync } from "node:fs"; -import { resolve, join, dirname } from "node:path"; -import { fileURLToPath } from 'node:url'; -import path from "node:path"; +const { accessSync, constants, readFileSync } = require("node:fs"); +const { resolve, join } = require("node:path"); -const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), ".."); +const ROOT = resolve(__dirname, ".."); const CATALOG = join(ROOT, "modules", "catalog.json"); const SERVICES_CATALOG = join(ROOT, "services", "catalog.json"); /* SAPI modules no longer register through a single static entry.ts — From 9057b7f2620a828acce7eabe907e56349b067a71 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 21 Jul 2026 17:14:30 +0000 Subject: [PATCH 2/6] =?UTF-8?q?fix(tools):=20=E4=BF=AE=E6=AD=A3=20db-serve?= =?UTF-8?q?r=20=E5=85=A5=E5=8F=A3=E8=B7=AF=E5=BE=84=E4=B8=BA=20dist/index.?= =?UTF-8?q?js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit check-ootb.js 与 sim-new-user.js 均直接 spawn db-server/index.js, 但该文件不存在 —— db-server 编译后的真实入口是 dist/index.js (package.json#main / sfmc/src/runtime.ts / dispatcher.ts 均已如此引用)。 之前一直因路径错误导致 db-server 无法启动、sim-new-user 超时。 Co-authored-by: Shiroha --- tools/check-ootb.js | 2 +- tools/sim-new-user.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/check-ootb.js b/tools/check-ootb.js index 970b038..240bb13 100644 --- a/tools/check-ootb.js +++ b/tools/check-ootb.js @@ -106,7 +106,7 @@ function fileContains(p, needle) { { let dbProc = null; try { - dbProc = spawn(process.execPath, [path.join(ROOT, "db-server", "index.js")], { + dbProc = spawn(process.execPath, [path.join(ROOT, "db-server", "dist", "index.js")], { cwd: ROOT, env: { ...process.env }, stdio: ["ignore", "pipe", "pipe"], diff --git a/tools/sim-new-user.js b/tools/sim-new-user.js index 18990b9..8206073 100644 --- a/tools/sim-new-user.js +++ b/tools/sim-new-user.js @@ -30,7 +30,7 @@ let dbProc = null; function startDb(simDir) { const env = { ...process.env, SFMC_ROOT: simDir, DB_PORT: String(DB_PORT) }; - dbProc = spawn(process.execPath, [path.join(ROOT, "db-server", "index.js")], { + dbProc = spawn(process.execPath, [path.join(ROOT, "db-server", "dist", "index.js")], { cwd: ROOT, env, stdio: ["ignore", "pipe", "pipe"], From ec3332939d5c016224cd04230304d299c86189d4 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 21 Jul 2026 17:14:36 +0000 Subject: [PATCH 3/6] =?UTF-8?q?fix(configs):=20modulesDir=20=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC=E6=94=B9=E4=B8=BA=E7=9B=B8=E5=AF=B9=E4=BB=93?= =?UTF-8?q?=E5=BA=93=E6=A0=B9=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit configs-default/db_config.json 的 modulesDir 原为 "../modules", 会相对 PROJECT_ROOT(仓库根)再向上一级解析,指向仓库外不存在的目录, 导致模块 API 返回空 catalog。改为 "modules" 以正确指向 /modules (与省略该字段时的默认回退行为一致)。 Co-authored-by: Shiroha --- configs-default/db_config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs-default/db_config.json b/configs-default/db_config.json index 0dff98e..c1380db 100644 --- a/configs-default/db_config.json +++ b/configs-default/db_config.json @@ -3,5 +3,5 @@ "db_port": 3001, "http_auth": "", "dbDir": "./data/sfmc_data.db", - "modulesDir": "../modules" + "modulesDir": "modules" } From 97f6cf9c295cbcca360cba595aab3071db107d5d Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 21 Jul 2026 17:14:44 +0000 Subject: [PATCH 4/6] =?UTF-8?q?fix(db-server):=20=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=90=AF=E5=81=9C=E6=8E=A5=E5=8F=A3=E5=86=99=E5=85=A5=E5=90=8E?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E5=86=85=E5=AD=98=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit setModuleEnabled() 每次都从磁盘重新读取 lock 文件、更新并写回, 但内存中长期持有的 lockFile 变量从未被刷新 —— buildModuleList()/current() 读取的一直是旧引用,导致 POST /api/sfmc/modules/:id/{enable|disable} 接口返回的 module.enabled 字段仍是切换前的状态(尽管磁盘已写入正确值)。 写盘后同步刷新 lockFile,使接口的读己之写立即可见。 Co-authored-by: Shiroha --- db-server/src/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/db-server/src/index.ts b/db-server/src/index.ts index b4a149f..746455c 100644 --- a/db-server/src/index.ts +++ b/db-server/src/index.ts @@ -78,7 +78,7 @@ log.success( ); // ── enabled 集合(从 lock file)───────────────────────────── -const lockFile = loadModuleLock(env.MODULE_LOCK_PATH); +let lockFile = loadModuleLock(env.MODULE_LOCK_PATH); const moduleCatalog = readJsonFile<{ modules?: unknown[] }>(env.MODULE_CATALOG_PATH, { modules: [], }); @@ -194,6 +194,8 @@ function setModuleEnabled(mod: { id: string; canDisable: boolean }, enabled: boo const lock = loadModuleLock(env.MODULE_LOCK_PATH); updateModuleState(lock, mod.id, { enabled: !!enabled }); writeJsonFile(env.MODULE_LOCK_PATH, lock); + // 同步内存缓存,避免写入后立即读取(如 enable/disable 接口的返回值)仍是旧状态 + lockFile = lock; } // ── 路由工厂实例 (旧业务路径 — 保留直到各模块迁 v2) ──────────────── From 6317d81349c2ef7599976157db354ad978d53deb Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 21 Jul 2026 17:14:51 +0000 Subject: [PATCH 5/6] =?UTF-8?q?ci(ootb):=20=E8=BF=90=E8=A1=8C=20check-ootb?= =?UTF-8?q?=20=E5=89=8D=E4=BB=8E=20configs-default/=20=E8=A1=A5=E5=85=A8?= =?UTF-8?q?=20configs/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit configs/ 已被 .gitignore 忽略,CI checkout 后该目录始终不存在, 导致 check-ootb.js 的"必备仓库文件齐全"检查(要求 configs/db_config.json 等三个文件存在)每次都失败。 新增一步在构建之后、检查之前把 configs-default/*.json 复制到 configs/(仅当目标文件不存在时),与本地开发环境的标准初始化步骤一致。 Co-authored-by: Shiroha --- .github/workflows/ootb.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/ootb.yml b/.github/workflows/ootb.yml index c6ac97d..2b0b99b 100644 --- a/.github/workflows/ootb.yml +++ b/.github/workflows/ootb.yml @@ -27,6 +27,15 @@ jobs: shell: pwsh run: npm run build --workspaces --if-present + - name: Populate configs/ from configs-default/ + shell: pwsh + run: | + New-Item -ItemType Directory -Force -Path configs | Out-Null + Get-ChildItem configs-default/*.json | ForEach-Object { + $dest = Join-Path configs $_.Name + if (-not (Test-Path $dest)) { Copy-Item $_.FullName $dest } + } + - name: Run check-ootb shell: pwsh run: node tools/check-ootb.js From e562ade550f64ccebd6953a45584f6a2e0da3fc8 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 21 Jul 2026 17:14:57 +0000 Subject: [PATCH 6/6] =?UTF-8?q?chore(.gitignore):=20=E8=A1=A5=E5=85=85=20q?= =?UTF-8?q?q-bridge/sfmc/remote-controller=20=E7=9A=84=20dist/=20=E5=BF=BD?= =?UTF-8?q?=E7=95=A5=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 这三个 workspace 都会通过 tsc 产出 dist/,但 .gitignore 里只有 bds-tools、db-server、panel(已不存在)三项,遗漏了它们, 本地构建后会被 git 当作未跟踪文件提示。 Co-authored-by: Shiroha --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 8337848..08108d4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ bds-tools/dist/ db-server/dist/ panel/dist/ +qq-bridge/dist/ +sfmc/dist/ +remote-controller/dist/ modules/sdk/@sfmc-sdk/dist/ modules/sdk/@sfmc-sdk/node_modules/ shared/**/dist/