feat: 完成P13治理收尾并创建P14执行合同(Issue: P13-1,P13-2,P13-3,P13-4,P13-5,P13-6,P13-7,P13-8,P14-0)

这个提交包含在:
2026-02-13 00:25:04 +08:00
父节点 3b221a2202
当前提交 1412fead5d
共修改 30 个文件,包含 3988 行新增和 105 行删除
+130
查看文件
@@ -3,6 +3,10 @@ const { z } = require("zod");
const { AppError } = require("../utils/AppError");
const { buildAuditLogData } = require("../utils/audit");
const { sendData } = require("../utils/reply");
const {
buildDataEnvelopeSchema,
buildErrorEnvelopeSchema,
} = require("../utils/openapi");
const {
FEATURE_FLAG_KEY_LIST,
OVERRIDE_MODE_LIST,
@@ -24,6 +28,49 @@ const UPDATE_BODY_SCHEMA = z.object({
expectedVersion: z.coerce.number().int().min(1),
});
const FEATURE_FLAG_ITEM_SCHEMA = {
type: "object",
required: [
"id",
"flagKey",
"overrideMode",
"rolloutType",
"departmentIds",
"note",
"version",
"createdAt",
"createdBy",
"updatedAt",
"updatedBy",
"envEnabled",
"effectiveEnabled",
"effectiveReason",
"matchedDepartmentId",
"requiresDepartment",
],
properties: {
id: { anyOf: [{ type: "string", format: "uuid" }, { type: "null" }] },
flagKey: { type: "string", enum: FEATURE_FLAG_KEY_LIST },
overrideMode: { type: "string", enum: OVERRIDE_MODE_LIST },
rolloutType: { type: "string", enum: ROLLOUT_TYPE_LIST },
departmentIds: {
type: "array",
items: { type: "string", format: "uuid" },
},
note: { type: "string" },
version: { type: "integer" },
createdAt: { anyOf: [{ type: "string", format: "date-time" }, { type: "null" }] },
createdBy: { anyOf: [{ type: "string", format: "uuid" }, { type: "null" }] },
updatedAt: { anyOf: [{ type: "string", format: "date-time" }, { type: "null" }] },
updatedBy: { anyOf: [{ type: "string", format: "uuid" }, { type: "null" }] },
envEnabled: { type: "boolean" },
effectiveEnabled: { type: "boolean" },
effectiveReason: { type: "string" },
matchedDepartmentId: { anyOf: [{ type: "string", format: "uuid" }, { type: "null" }] },
requiresDepartment: { type: "boolean" },
},
};
function parseKey(params) {
const parsed = KEY_PARAM_SCHEMA.safeParse(params ?? {});
if (!parsed.success) {
@@ -66,6 +113,31 @@ async function featureFlagsRoutes(fastify) {
"/system/feature-flags",
{
preHandler: fastify.requirePermission("system.settings"),
schema: {
tags: ["system", "feature-flags"],
summary: "获取功能开关列表",
security: [{ bearerAuth: [] }],
response: {
200: buildDataEnvelopeSchema(
{
type: "object",
required: ["items"],
properties: {
items: {
type: "array",
items: FEATURE_FLAG_ITEM_SCHEMA,
},
},
},
"功能开关列表",
),
403: buildErrorEnvelopeSchema({
description: "无权限",
codeExample: "PERM_001",
messageExample: "无权限",
}),
},
},
},
async (request, reply) => {
const items = await listFeatureFlags(fastify.prisma, fastify.config);
@@ -77,6 +149,64 @@ async function featureFlagsRoutes(fastify) {
"/system/feature-flags/:key",
{
preHandler: fastify.requirePermission("system.settings"),
schema: {
tags: ["system", "feature-flags"],
summary: "更新功能开关",
security: [{ bearerAuth: [] }],
params: {
type: "object",
required: ["key"],
properties: {
key: { type: "string", enum: FEATURE_FLAG_KEY_LIST },
},
},
body: {
type: "object",
required: ["overrideMode", "rolloutType", "departmentIds", "expectedVersion"],
properties: {
overrideMode: { type: "string", enum: OVERRIDE_MODE_LIST },
rolloutType: { type: "string", enum: ROLLOUT_TYPE_LIST },
departmentIds: {
type: "array",
items: { type: "string", format: "uuid" },
},
note: { type: "string", maxLength: 500 },
expectedVersion: { type: "integer", minimum: 1 },
},
},
response: {
200: buildDataEnvelopeSchema(
{
type: "object",
required: ["item"],
properties: {
item: FEATURE_FLAG_ITEM_SCHEMA,
},
},
"更新后的功能开关",
),
400: buildErrorEnvelopeSchema({
description: "参数校验失败",
codeExample: "VALID_001",
messageExample: "参数校验失败",
}),
404: buildErrorEnvelopeSchema({
description: "开关不存在",
codeExample: "SYS_404",
messageExample: "Not Found",
}),
409: buildErrorEnvelopeSchema({
description: "版本冲突",
codeExample: "VALID_001",
messageExample: "参数校验失败",
detailsExample: {
featureFlag: "version_conflict",
expectedVersion: 2,
currentVersion: 3,
},
}),
},
},
},
async (request, reply) => {
const key = parseKey(request.params);