feat(server): 完成 P0+P1 后端能力(工作流、RBAC、付款归档)
P0 MVP: - 认证:login/refresh/logout/forgot/reset + tokenVersion - RBAC:角色到权限映射 + requirePermission - 发票池:upload/bind/signed-url + 判重(VALID_003/VALID_005) - 报销:create/view/submit + 单号生成 - 工作流:approve + department_manager 解析 P1 扩展: - 动作:reject/return/withdraw(含 comment) - transfer:任务转审 + 链路上限 3 - pay:approved -> paid + 发票归档 used_complete - 动态审批链:approval_rules 驱动 回归脚本: - smoke-test.sh / regression-dedup.sh / regression-workflow-actions.sh
这个提交包含在:
@@ -0,0 +1,48 @@
|
||||
const path = require("node:path");
|
||||
|
||||
const ONE_DAY_SECONDS = 24 * 60 * 60;
|
||||
|
||||
function requiredEnv(name) {
|
||||
const value = process.env[name];
|
||||
if (!value) {
|
||||
throw new Error(`Missing required env: ${name}`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function getConfig() {
|
||||
const nodeEnv = process.env.NODE_ENV ?? "development";
|
||||
const serverRoot = path.resolve(__dirname, "..");
|
||||
const storageDir = process.env.STORAGE_DIR ?? "generated/storage";
|
||||
|
||||
return {
|
||||
nodeEnv,
|
||||
port: Number(process.env.PORT ?? 3000),
|
||||
host: process.env.HOST ?? "0.0.0.0",
|
||||
|
||||
appOrigin: process.env.APP_ORIGIN ?? "",
|
||||
jwtSecret: requiredEnv("JWT_SECRET"),
|
||||
|
||||
accessTokenTtl: "15m",
|
||||
refreshTtlSeconds: 7 * ONE_DAY_SECONDS,
|
||||
|
||||
refreshCookieName: "refresh_token",
|
||||
cookieSecure:
|
||||
process.env.COOKIE_SECURE != null
|
||||
? process.env.COOKIE_SECURE === "true"
|
||||
: nodeEnv === "production",
|
||||
|
||||
passwordResetCodeTtlSeconds: Number(
|
||||
process.env.PASSWORD_RESET_CODE_TTL_SECONDS ?? 10 * 60,
|
||||
),
|
||||
|
||||
devShowPasswordResetCode: process.env.DEV_SHOW_PASSWORD_RESET_CODE === "true",
|
||||
|
||||
appTimezone: process.env.APP_TIMEZONE ?? "Asia/Shanghai",
|
||||
storageDir: path.resolve(serverRoot, storageDir),
|
||||
signedUrlTtlSeconds: Number(process.env.SIGNED_URL_TTL_SECONDS ?? 600),
|
||||
maxUploadSizeBytes: Number(process.env.MAX_UPLOAD_SIZE_BYTES ?? 10 * 1024 * 1024),
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = { getConfig };
|
||||
在新工单中引用
屏蔽一个用户