feat(P11-P12): 落地治理开关与移动端MVP(G0-G6/H1/M1-M4)
- 新增 Feature Flag 模型、评估服务与管理 API(erp_sync/invoice_verification)\n- 完成 ERP 与验真灰度收口(路由/服务/作业统一判定)\n- 补齐 pay 与手动 sync 的 department_id 灰度上下文\n- 增加管理后台开关页、PWA 基础设施与移动拍照/审批页面\n- 增加回归脚本、安全基线与压测脚本,更新文档与执行合同\n\nIssue: G0,G1,G2,G3,G4,G5,G6,H1,M1,M2,M3,M4
这个提交包含在:
@@ -292,6 +292,50 @@ run_outbox_once() {
|
||||
npm run --silent job:integration-outbox-once >"$TMP_DIR/outbox-once.log"
|
||||
}
|
||||
|
||||
set_erp_flag() {
|
||||
local mode="$1"
|
||||
DATABASE_URL="$DATABASE_URL" MODE="$mode" node <<'NODE'
|
||||
require("dotenv/config");
|
||||
|
||||
const { createPrismaClient } = require("./src/prismaClient");
|
||||
|
||||
(async () => {
|
||||
const mode = process.env.MODE;
|
||||
const { prisma, pool } = createPrismaClient();
|
||||
await prisma.$connect();
|
||||
|
||||
try {
|
||||
await prisma.featureFlag.upsert({
|
||||
where: { flag_key: "erp_sync" },
|
||||
create: {
|
||||
flag_key: "erp_sync",
|
||||
override_mode: mode,
|
||||
rollout_type: "global",
|
||||
department_ids: [],
|
||||
note: "regression-integrations",
|
||||
},
|
||||
update: {
|
||||
override_mode: mode,
|
||||
rollout_type: "global",
|
||||
department_ids: [],
|
||||
note: "regression-integrations",
|
||||
version: { increment: 1 },
|
||||
},
|
||||
});
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
await pool.end();
|
||||
}
|
||||
})().catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
NODE
|
||||
}
|
||||
|
||||
echo "[0/6] Ensure ERP feature flag force_on"
|
||||
set_erp_flag "force_on"
|
||||
|
||||
assert_mode_semantics() {
|
||||
local mode="$1"
|
||||
local state_json="$2"
|
||||
@@ -373,3 +417,6 @@ run_mode_case "timeout"
|
||||
|
||||
echo "[6/6] Done"
|
||||
echo "[OK] Integrations regression passed"
|
||||
|
||||
echo "[post] Reset ERP feature flag force_off"
|
||||
set_erp_flag "force_off"
|
||||
|
||||
在新工单中引用
屏蔽一个用户