R78 A3-A5:跑通本地支付尾链回归并回填报告
这个提交包含在:
@@ -6,6 +6,30 @@ const { createPrismaClient } = require("../prismaClient");
|
||||
const { hashPassword } = require("../utils/crypto");
|
||||
const { validatePassword } = require("../utils/passwordPolicy");
|
||||
|
||||
const DEFAULT_FORCE_ON_FLAGS = Object.freeze([
|
||||
"portal_home_v1",
|
||||
"announcements_v1",
|
||||
"global_search_v1",
|
||||
"presence_board_v1",
|
||||
"attendance_v1",
|
||||
"weekly_report_v1",
|
||||
"employee_lifecycle_v1",
|
||||
"todo_board_v1",
|
||||
"project_domain_v1",
|
||||
"project_linking_v1",
|
||||
"project_communication_log_v1",
|
||||
"project_closure_checklist_v1",
|
||||
"confidential_doc_refs_v1",
|
||||
]);
|
||||
|
||||
const OPTIONAL_FORCE_ON_FLAGS = new Set([
|
||||
"erp_sync",
|
||||
"budget_precheck_v1",
|
||||
"payment_batch_v1",
|
||||
"workflow_definition_admin_v1",
|
||||
"cutover_console_v1",
|
||||
]);
|
||||
|
||||
function requiredEnv(name) {
|
||||
const value = process.env[name];
|
||||
if (typeof value !== "string" || !value.trim()) {
|
||||
@@ -14,6 +38,29 @@ function requiredEnv(name) {
|
||||
return value.trim();
|
||||
}
|
||||
|
||||
function parseExtraForceOnFlags() {
|
||||
const raw = String(process.env.TRIALRUN_EXTRA_FORCE_ON_FLAGS ?? "").trim();
|
||||
if (!raw) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const parts = raw
|
||||
.split(/[\s,]+/)
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean);
|
||||
const unique = Array.from(new Set(parts));
|
||||
const invalid = unique.filter((flagKey) => !OPTIONAL_FORCE_ON_FLAGS.has(flagKey));
|
||||
if (invalid.length > 0) {
|
||||
throw new Error(
|
||||
`Unsupported TRIALRUN_EXTRA_FORCE_ON_FLAGS: ${invalid.join(", ")}. Allowed: ${Array.from(
|
||||
OPTIONAL_FORCE_ON_FLAGS,
|
||||
).join(", ")}`,
|
||||
);
|
||||
}
|
||||
|
||||
return unique;
|
||||
}
|
||||
|
||||
async function ensureDepartment(prisma, payload) {
|
||||
const now = new Date();
|
||||
const existing = await prisma.department.findFirst({
|
||||
@@ -255,21 +302,10 @@ async function main() {
|
||||
|
||||
await ensureWorkspaceSetting(prisma);
|
||||
|
||||
for (const flagKey of [
|
||||
"portal_home_v1",
|
||||
"announcements_v1",
|
||||
"global_search_v1",
|
||||
"presence_board_v1",
|
||||
"attendance_v1",
|
||||
"weekly_report_v1",
|
||||
"employee_lifecycle_v1",
|
||||
"todo_board_v1",
|
||||
"project_domain_v1",
|
||||
"project_linking_v1",
|
||||
"project_communication_log_v1",
|
||||
"project_closure_checklist_v1",
|
||||
"confidential_doc_refs_v1",
|
||||
]) {
|
||||
const extraForceOnFlags = parseExtraForceOnFlags();
|
||||
const forceOnFlags = [...DEFAULT_FORCE_ON_FLAGS, ...extraForceOnFlags];
|
||||
|
||||
for (const flagKey of forceOnFlags) {
|
||||
await ensureFeatureFlag(prisma, {
|
||||
flag_key: flagKey,
|
||||
override_mode: "force_on",
|
||||
@@ -287,6 +323,8 @@ async function main() {
|
||||
console.log(`- phone: ${adminPhone}`);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`- created: ${result.created}`);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`- force_on flags: ${forceOnFlags.join(", ")}`);
|
||||
if (result.password) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`- one-time password: ${result.password}`);
|
||||
|
||||
在新工单中引用
屏蔽一个用户