fix: 加固日历日期与动态错误合同(09-05-error-explainability-payment-readiness,09-08-reimbursement-payment-closeout)
这个提交包含在:
@@ -2,7 +2,7 @@ const { z } = require("zod");
|
||||
|
||||
const { AppError } = require("../utils/AppError");
|
||||
const { buildAuditLogData } = require("../utils/audit");
|
||||
const { parseDateOnlyString } = require("../utils/date");
|
||||
const { parseDateOnlyString, isValidDateOnlyString } = require("../utils/date");
|
||||
const { issueDocumentNumber } = require("../services/documentSequence");
|
||||
const { FEATURE_FLAG_KEYS, evaluateFeatureFlag } = require('../services/featureFlags');
|
||||
const {
|
||||
@@ -14,7 +14,7 @@ const { sendData } = require("../utils/reply");
|
||||
|
||||
const UUID_SCHEMA = z.string().uuid();
|
||||
const BOOLEAN_QUERY_SCHEMA = z.enum(["0", "1", "true", "false"]).optional();
|
||||
const DATE_ONLY_SCHEMA = z.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
||||
const DATE_ONLY_SCHEMA = z.string().regex(/^\d{4}-\d{2}-\d{2}$/).refine(isValidDateOnlyString, { message: "invalid_calendar_date" });
|
||||
const ASSET_STATUS_VALUES = ["in_stock", "in_use", "under_repair", "retired", "archived"];
|
||||
const ASSET_TYPE_VALUES = ["fixed_asset", "electronic_document", "electronic_system", "code_repository", "backup_media"];
|
||||
const ASSET_SENSITIVITY_VALUES = ["public_candidate", "internal", "confidential", "strictly_confidential"];
|
||||
|
||||
@@ -12,7 +12,7 @@ const { z } = require("zod");
|
||||
const { AppError } = require("../utils/AppError");
|
||||
const { sendData } = require("../utils/reply");
|
||||
const { buildAuditLogData } = require("../utils/audit");
|
||||
const { currentDateString, parseDateOnlyString } = require("../utils/date");
|
||||
const { currentDateString, parseDateOnlyString, isValidDateOnlyString } = require("../utils/date");
|
||||
const { FEATURE_FLAG_KEYS, evaluateFeatureFlag } = require("../services/featureFlags");
|
||||
const { createNotificationsWithRecords } = require("../services/notifications");
|
||||
const { NOTIFICATION_TYPES } = require("../constants/notificationTypes");
|
||||
@@ -70,14 +70,14 @@ const CREATE_SCHEMA = z.object({
|
||||
entityType: ENTITY_TYPE_SCHEMA,
|
||||
name: z.string().trim().min(1).max(120).optional(),
|
||||
entityIds: z.array(UUID_SCHEMA).min(1).max(200),
|
||||
defaultPaymentDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),
|
||||
defaultPaymentDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).refine(isValidDateOnlyString, { message: "invalid_calendar_date" }).optional(),
|
||||
defaultPaymentChannel: PAYMENT_CHANNEL_SCHEMA.optional(),
|
||||
voucherPrefix: z.string().trim().min(1).max(32).optional(),
|
||||
}).strict();
|
||||
|
||||
const PATCH_ITEM_SCHEMA = z.object({
|
||||
paymentVoucherNoOverride: z.string().trim().max(50).nullable().optional(),
|
||||
paymentDateOverride: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).nullable().optional(),
|
||||
paymentDateOverride: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).refine(isValidDateOnlyString, { message: "invalid_calendar_date" }).nullable().optional(),
|
||||
}).strict().refine((value) => Object.keys(value).length > 0, { message: "empty_patch" });
|
||||
|
||||
const REVIEW_SCHEMA = z.object({
|
||||
|
||||
@@ -10,7 +10,7 @@ const { buildAuditLogData } = require("../utils/audit");
|
||||
const { sha256Hex } = require("../utils/crypto");
|
||||
const { buildAttachmentContentDisposition } = require("../utils/contentDisposition");
|
||||
const { signPayload, verifyToken } = require("../utils/signedUrl");
|
||||
const { compactDateString, currentDateString, parseDateOnlyString } = require("../utils/date");
|
||||
const { compactDateString, currentDateString, parseDateOnlyString, isValidDateOnlyString } = require("../utils/date");
|
||||
const { findActiveDelegationForDelegate, listActiveDelegationPrincipals } = require("../utils/delegation");
|
||||
const { hasPermission, resolveEntityPermission } = require("../constants/permissions");
|
||||
const {
|
||||
@@ -76,7 +76,7 @@ const {
|
||||
const UUID_SCHEMA = z.string().uuid();
|
||||
const PAY_BODY_SCHEMA = z.object({
|
||||
paymentVoucherNo: z.string().trim().min(1).max(50).optional(),
|
||||
paymentDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),
|
||||
paymentDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).refine(isValidDateOnlyString, { message: "invalid_calendar_date" }).optional(),
|
||||
paymentChannel: z.enum(["bank", "alipay", "wechat", "cash", "other"]).optional(),
|
||||
paymentNote: z.string().trim().max(200).optional(),
|
||||
});
|
||||
@@ -91,12 +91,12 @@ const REIMBURSEMENT_LIST_QUERY_SCHEMA = z.object({
|
||||
});
|
||||
|
||||
const REIMBURSEMENT_UPDATE_BODY_SCHEMA = z.object({
|
||||
reimbursementDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),
|
||||
reimbursementDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).refine(isValidDateOnlyString, { message: "invalid_calendar_date" }).optional(),
|
||||
description: z.string().trim().max(500).nullable().optional(),
|
||||
travelPurpose: z.string().trim().max(200).nullable().optional(),
|
||||
travelLocation: z.string().trim().max(200).nullable().optional(),
|
||||
travelStartDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).nullable().optional(),
|
||||
travelEndDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).nullable().optional(),
|
||||
travelStartDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).refine(isValidDateOnlyString, { message: "invalid_calendar_date" }).nullable().optional(),
|
||||
travelEndDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).refine(isValidDateOnlyString, { message: "invalid_calendar_date" }).nullable().optional(),
|
||||
}).superRefine((value, ctx) => {
|
||||
if (value.travelStartDate && value.travelEndDate && value.travelStartDate > value.travelEndDate) {
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "invalid_date_range", path: ["travelEndDate"] });
|
||||
@@ -151,14 +151,14 @@ function throwMaterialPreviewAppError(error) {
|
||||
const REIMBURSEMENT_CREATE_BODY_SCHEMA = z
|
||||
.object({
|
||||
ownerEmployeeId: z.string().uuid().optional(),
|
||||
reimbursementDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),
|
||||
reimbursementDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).refine(isValidDateOnlyString, { message: "invalid_calendar_date" }).optional(),
|
||||
description: z.string().max(500).optional(),
|
||||
templateId: z.string().uuid().optional(),
|
||||
linkedTravelRequestId: z.string().uuid().optional(),
|
||||
travelPurpose: z.string().trim().max(200).optional(),
|
||||
travelLocation: z.string().trim().max(200).optional(),
|
||||
travelStartDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),
|
||||
travelEndDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),
|
||||
travelStartDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).refine(isValidDateOnlyString, { message: "invalid_calendar_date" }).optional(),
|
||||
travelEndDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).refine(isValidDateOnlyString, { message: "invalid_calendar_date" }).optional(),
|
||||
})
|
||||
.strict()
|
||||
.superRefine((value, ctx) => {
|
||||
@@ -181,13 +181,13 @@ const REIMBURSEMENT_CREATE_BODY_SCHEMA = z
|
||||
|
||||
const REIMBURSEMENT_ITEM_BODY_SCHEMA = z.object({
|
||||
expenseTypeId: z.string().uuid().nullable(),
|
||||
expenseDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
|
||||
expenseDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).refine(isValidDateOnlyString, { message: "invalid_calendar_date" }),
|
||||
amount: z.string().regex(/^\d+(\.\d{1,2})?$/),
|
||||
description: z.string().trim().max(500),
|
||||
assetPriorApprovalBasis: z.string().trim().max(500).nullable().optional(),
|
||||
});
|
||||
|
||||
const DATE_ONLY_QUERY_SCHEMA = z.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
||||
const DATE_ONLY_QUERY_SCHEMA = z.string().regex(/^\d{4}-\d{2}-\d{2}$/).refine(isValidDateOnlyString, { message: "invalid_calendar_date" });
|
||||
const REIMBURSEMENT_STATS_QUERY_SCHEMA = z.object({
|
||||
dateFrom: DATE_ONLY_QUERY_SCHEMA.optional(),
|
||||
dateTo: DATE_ONLY_QUERY_SCHEMA.optional(),
|
||||
|
||||
@@ -2,7 +2,7 @@ const { z } = require("zod");
|
||||
|
||||
const { AppError } = require("../utils/AppError");
|
||||
const { buildAuditLogData } = require("../utils/audit");
|
||||
const { parseDateOnlyString } = require("../utils/date");
|
||||
const { parseDateOnlyString, isValidDateOnlyString } = require("../utils/date");
|
||||
const { sendData } = require("../utils/reply");
|
||||
const { issueDocumentNumber } = require("../services/documentSequence");
|
||||
const { resolveApplicableBudgetPoolByContext } = require("../services/budgetPool");
|
||||
@@ -28,7 +28,7 @@ const { flushNotificationDispatchTasks } = require("../services/notificationDisp
|
||||
const UUID_SCHEMA = z.string().uuid();
|
||||
const BOOLEAN_QUERY_SCHEMA = z.enum(["0", "1", "true", "false"]).optional();
|
||||
const MONEY_STRING_SCHEMA = z.string().regex(/^\d+(?:\.\d{1,2})?$/);
|
||||
const DATE_ONLY_SCHEMA = z.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
||||
const DATE_ONLY_SCHEMA = z.string().regex(/^\d{4}-\d{2}-\d{2}$/).refine(isValidDateOnlyString, { message: "invalid_calendar_date" });
|
||||
const DATE_TIME_SCHEMA = z.string().min(1).max(64);
|
||||
const TRAVEL_STATUS_SCHEMA = z.enum(["draft", "reviewing", "approved", "rejected"]);
|
||||
const TRIP_TYPE_SCHEMA = z.enum(["domestic", "international"]);
|
||||
|
||||
@@ -17,8 +17,15 @@ function parseDateOnlyString(value) {
|
||||
return new Date(`${value}T00:00:00.000Z`);
|
||||
}
|
||||
|
||||
function isValidDateOnlyString(value) {
|
||||
if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}$/.test(value)) return false;
|
||||
const date = parseDateOnlyString(value);
|
||||
return Number.isFinite(date.getTime()) && date.toISOString().slice(0, 10) === value;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
compactDateString,
|
||||
currentDateString,
|
||||
parseDateOnlyString,
|
||||
isValidDateOnlyString,
|
||||
};
|
||||
|
||||
在新工单中引用
屏蔽一个用户