fix: 补齐候选诊断环境与证据保护(09-06-release-gate-integrity)

这个提交包含在:
2026-09-08 07:21:19 +08:00
父节点 66f25b1fa8
当前提交 99167127b5
共修改 33 个文件,包含 2915 行新增和 67 行删除
+56 -10
查看文件
@@ -263,6 +263,47 @@ create_and_bind_invoice() {
echo "$invoice_id"
}
set_non_positive_item_fixture() {
DATABASE_URL="$DATABASE_URL" node - "$1" <<'NODE'
const reimbursementId = process.argv[2];
const { createPrismaClient } = require('./src/prismaClient');
(async () => {
const { prisma, pool } = createPrismaClient();
await prisma.$connect();
try {
const itemId = await prisma.$transaction(async (tx) => {
const items = await tx.reimbursementItem.findMany({
where: { reimbursement_id: reimbursementId },
select: { id: true },
});
if (items.length !== 1) throw new Error('non_positive_item_fixture_requires_one_item');
const item = await tx.reimbursementItem.update({
where: { id: items[0].id },
data: { amount: '-1.00' },
select: { id: true, amount: true },
});
const aggregate = await tx.reimbursementItem.aggregate({
where: { reimbursement_id: reimbursementId },
_sum: { amount: true },
});
if (item.amount.toFixed(2) !== '-1.00' || aggregate._sum.amount?.toFixed(2) !== '-1.00') {
throw new Error('non_positive_item_fixture_not_persisted');
}
return item.id;
});
process.stdout.write(itemId);
} finally {
await prisma.$disconnect();
await pool.end();
}
})().catch((error) => {
console.error(error);
process.exit(1);
});
NODE
}
set_reimbursement_total_amount() {
local reimbursement_id="$1"
local total_amount="$2"
@@ -988,16 +1029,21 @@ withdraw_reimbursement "$EMPLOYEE_TOKEN" "$RID_PERM" "cleanup after PERM_002" "$
assert_instance_status "$INSTANCE_PERM" "cancelled" "PERM_002 cleanup"
assert_reimbursement_status_db "$RID_PERM" "draft" "PERM_002 cleanup"
echo "[6/23] negative_not_allowed: submit blocked when total_amount < 0"
RID_NEGATIVE="$(create_reimbursement "$EMPLOYEE_TOKEN" "$TMP_DIR/negative-create.json")"
create_and_bind_invoice "$EMPLOYEE_TOKEN" "$RID_NEGATIVE" "negative" >/dev/null
set_reimbursement_total_amount "$RID_NEGATIVE" "-1.00"
echo "[6/23] items_positive_amount_required: submit blocked for a negative item"
RID_NON_POSITIVE_ITEM="$(create_reimbursement "$EMPLOYEE_TOKEN" "$TMP_DIR/non-positive-item-create.json")"
create_and_bind_invoice "$EMPLOYEE_TOKEN" "$RID_NON_POSITIVE_ITEM" "non-positive-item" >/dev/null
NON_POSITIVE_ITEM_ID="$(set_non_positive_item_fixture "$RID_NON_POSITIVE_ITEM")"
negative_submit_status="$(api_json_auth POST "$BASE_URL/api/reimbursements/$RID_NEGATIVE/submit" "$EMPLOYEE_TOKEN" "$TMP_DIR/negative-submit.json" '{}')"
assert_status "$negative_submit_status" "400" "negative_not_allowed submit" "$TMP_DIR/negative-submit.json"
assert_error_code "$TMP_DIR/negative-submit.json" "VALID_001" "negative_not_allowed submit"
assert_error_detail "$TMP_DIR/negative-submit.json" '.error.details.total_amount' "negative_not_allowed" "negative_not_allowed submit"
assert_no_workflow_instance "$RID_NEGATIVE" "negative_not_allowed"
non_positive_submit_status="$(api_json_auth POST "$BASE_URL/api/reimbursements/$RID_NON_POSITIVE_ITEM/submit" "$EMPLOYEE_TOKEN" "$TMP_DIR/non-positive-item-submit.json" '{}')"
assert_status "$non_positive_submit_status" "400" "items_positive_amount_required submit" "$TMP_DIR/non-positive-item-submit.json"
assert_error_code "$TMP_DIR/non-positive-item-submit.json" "VALID_001" "items_positive_amount_required submit"
assert_error_detail "$TMP_DIR/non-positive-item-submit.json" '.error.details.items' "positive_amount_required" "items_positive_amount_required submit"
assert_error_detail "$TMP_DIR/non-positive-item-submit.json" '.error.details.reasonCode' "reimbursement.items_positive_amount_required" "items_positive_amount_required submit"
if ! jq -e --arg item_id "$NON_POSITIVE_ITEM_ID" '.error.details.itemIds == [$item_id]' "$TMP_DIR/non-positive-item-submit.json" >/dev/null; then
echo "[ERROR] items_positive_amount_required must identify exactly the injected item" >&2
exit 1
fi
assert_no_workflow_instance "$RID_NON_POSITIVE_ITEM" "items_positive_amount_required"
echo "[7/23] Prepare manager-missing context"
set_employee_direct_manager "$EMPLOYEE_ID" "__NULL__"
@@ -1338,7 +1384,7 @@ echo "- reject reimbursementId: $RID_REJECT"
echo "- return reimbursementId: $RID_RETURN"
echo "- withdraw reimbursementId: $RID_WITHDRAW"
echo "- perm reimbursementId: $RID_PERM"
echo "- negative reimbursementId: $RID_NEGATIVE"
echo "- non-positive item reimbursementId: $RID_NON_POSITIVE_ITEM"
echo "- manager-skip reimbursementId: $RID_SKIP"
echo "- no-actionable reimbursementId: $RID_NO_ACTIONABLE"
echo "- transfer-ok reimbursementId: $RID_TRANSFER_OK"