// Copyright 2025 Kuban Technologies // // 自定义字段验证框架 - 基于 buf/validate 优化设计 // 提供简化的 API、中文支持和业务规则集成 syntax = "proto3"; package kuban.api.validate; import "google/protobuf/descriptor.proto"; // import "google/protobuf/duration.proto"; // 未使用 // import "google/protobuf/timestamp.proto"; // 未使用 option go_package = "git.ikuban.com/server/kubanapis/kuban/api/validate;validate"; // ============================================================================ // 扩展定义 - 为 Protobuf 描述符添加验证能力 // ============================================================================ // MessageOptions 扩展 - 消息级别验证 extend google.protobuf.MessageOptions { // 消息级别的验证规则 MessageRules message = 10100; } // FieldOptions 扩展 - 字段级别验证 extend google.protobuf.FieldOptions { // 字段级别的验证规则 FieldRules field = 10100; // 预定义规则引用(用于扩展) PredefinedRules predefined = 10101; } // OneofOptions 扩展 - oneof 级别验证 extend google.protobuf.OneofOptions { // oneof 级别的验证规则 OneofRules oneof = 10100; } // ============================================================================ // 核心规则定义 // ============================================================================ // CEL 验证规则 // 使用 Common Expression Language 编写自定义验证逻辑 message Rule { // 规则唯一标识符 string id = 1; // 错误消息(中文) string message = 2; // 错误消息(英文) - 可选,用于国际化 string message_en = 3; // CEL 表达式 - 返回 true 表示验证通过 string expression = 4; } // 消息级别验证规则 message MessageRules { // CEL 自定义规则列表 repeated Rule cel = 1; // 是否禁用所有字段验证 bool disabled = 2; // 验证组 - 用于分组验证 repeated string groups = 3; } // Oneof 验证规则 message OneofRules { // 是否必须选择一个字段 bool required = 1; } // 字段级别验证规则 message FieldRules { // CEL 自定义规则列表 repeated Rule cel = 1; // 字段是否必填 (Proto3 不需要 optional 关键字) bool required = 2; // 忽略策略 IgnoreRule ignore = 3; // 验证组 - 只在指定组中验证 repeated string groups = 4; // ========== 自定义错误消息 ========== // 使用场景: // 1. error_message: 覆盖所有类型验证规则的默认错误消息 // 2. required_message: 专门为 required 验证自定义错误消息 // // 优先级: required_message > error_message > 默认消息 // // 示例: // string password = 1 [(kuban.api.validate.field) = { // required: true, // required_message: "密码不能为空", // required 验证失败时使用 // error_message: "密码格式不符合要求", // 其他验证失败时使用 // string: { min_len: 8, max_len: 32 } // }]; // 通用错误消息(中文) - 覆盖所有验证规则的默认消息 string error_message = 5; // 通用错误消息(英文) string error_message_en = 6; // required 验证专用错误消息(中文) string required_message = 7; // required 验证专用错误消息(英文) string required_message_en = 8; // 类型特定的验证规则 oneof type { // 数值类型 FloatRules float = 10; DoubleRules double = 11; Int32Rules int32 = 12; Int64Rules int64 = 13; UInt32Rules uint32 = 14; UInt64Rules uint64 = 15; SInt32Rules sint32 = 16; SInt64Rules sint64 = 17; Fixed32Rules fixed32 = 18; Fixed64Rules fixed64 = 19; SFixed32Rules sfixed32 = 20; SFixed64Rules sfixed64 = 21; // 布尔和字符串 BoolRules bool = 30; StringRules string = 31; BytesRules bytes = 32; // 复杂类型 EnumRules enum = 40; RepeatedRules repeated = 41; MapRules map = 42; // Well-Known Types DurationRules duration = 50; TimestampRules timestamp = 51; } } // 预定义规则(用于规则扩展) message PredefinedRules { repeated Rule cel = 1; } // 忽略策略 enum IgnoreRule { // 未指定 - 默认行为(字段未设置时不验证) IGNORE_UNSPECIFIED = 0; // 字段为零值时忽略验证 IGNORE_IF_ZERO = 1; // 始终忽略验证 IGNORE_ALWAYS = 2; // 从不忽略验证(即使未设置也验证) IGNORE_NEVER = 3; } // ============================================================================ // 数值类型验证规则 // ============================================================================ // 浮点数验证规则 message FloatRules { // 常量值 - 字段必须等于此值 optional float const = 1; // 小于 optional float lt = 2; // 小于等于 optional float lte = 3; // 大于 optional float gt = 4; // 大于等于 optional float gte = 5; // 在值列表中 repeated float in = 6; // 不在值列表中 repeated float not_in = 7; // 是否为有限数(非 NaN/Inf) optional bool finite = 8; } // 双精度浮点数验证规则 message DoubleRules { optional double const = 1; optional double lt = 2; optional double lte = 3; optional double gt = 4; optional double gte = 5; repeated double in = 6; repeated double not_in = 7; optional bool finite = 8; } // Int32 验证规则 message Int32Rules { optional int32 const = 1; optional int32 lt = 2; optional int32 lte = 3; optional int32 gt = 4; optional int32 gte = 5; repeated int32 in = 6; repeated int32 not_in = 7; } // Int64 验证规则 message Int64Rules { optional int64 const = 1; optional int64 lt = 2; optional int64 lte = 3; optional int64 gt = 4; optional int64 gte = 5; repeated int64 in = 6; repeated int64 not_in = 7; } // UInt32 验证规则 message UInt32Rules { optional uint32 const = 1; optional uint32 lt = 2; optional uint32 lte = 3; optional uint32 gt = 4; optional uint32 gte = 5; repeated uint32 in = 6; repeated uint32 not_in = 7; } // UInt64 验证规则 message UInt64Rules { optional uint64 const = 1; optional uint64 lt = 2; optional uint64 lte = 3; optional uint64 gt = 4; optional uint64 gte = 5; repeated uint64 in = 6; repeated uint64 not_in = 7; } // SInt32 验证规则 message SInt32Rules { optional sint32 const = 1; optional sint32 lt = 2; optional sint32 lte = 3; optional sint32 gt = 4; optional sint32 gte = 5; repeated sint32 in = 6; repeated sint32 not_in = 7; } // SInt64 验证规则 message SInt64Rules { optional sint64 const = 1; optional sint64 lt = 2; optional sint64 lte = 3; optional sint64 gt = 4; optional sint64 gte = 5; repeated sint64 in = 6; repeated sint64 not_in = 7; } // Fixed32 验证规则 message Fixed32Rules { optional fixed32 const = 1; optional fixed32 lt = 2; optional fixed32 lte = 3; optional fixed32 gt = 4; optional fixed32 gte = 5; repeated fixed32 in = 6; repeated fixed32 not_in = 7; } // Fixed64 验证规则 message Fixed64Rules { optional fixed64 const = 1; optional fixed64 lt = 2; optional fixed64 lte = 3; optional fixed64 gt = 4; optional fixed64 gte = 5; repeated fixed64 in = 6; repeated fixed64 not_in = 7; } // SFixed32 验证规则 message SFixed32Rules { optional sfixed32 const = 1; optional sfixed32 lt = 2; optional sfixed32 lte = 3; optional sfixed32 gt = 4; optional sfixed32 gte = 5; repeated sfixed32 in = 6; repeated sfixed32 not_in = 7; } // SFixed64 验证规则 message SFixed64Rules { optional sfixed64 const = 1; optional sfixed64 lt = 2; optional sfixed64 lte = 3; optional sfixed64 gt = 4; optional sfixed64 gte = 5; repeated sfixed64 in = 6; repeated sfixed64 not_in = 7; } // ============================================================================ // 字符串验证规则 // ============================================================================ // 布尔值验证规则 message BoolRules { optional bool const = 1; } // 字符串验证规则 - 增强的中文支持 message StringRules { // 常量值 optional string const = 1; // 长度限制(字符数,非字节数) optional uint64 len = 2; optional uint64 min_len = 3; optional uint64 max_len = 4; // 字节长度限制 optional uint64 len_bytes = 5; optional uint64 min_bytes = 6; optional uint64 max_bytes = 7; // 模式匹配 optional string pattern = 8; // 正则表达式 // 前缀/后缀 optional string prefix = 9; optional string suffix = 10; // 包含/不包含 optional string contains = 11; optional string not_contains = 12; // 在值列表中 repeated string in = 13; repeated string not_in = 14; // 预定义格式(优化设计 - 更简洁) oneof well_known { bool email = 20; // 邮箱格式 bool hostname = 21; // 主机名 bool ip = 22; // IP 地址(v4/v6) bool ipv4 = 23; // IPv4 bool ipv6 = 24; // IPv6 bool uri = 25; // URI bool uri_ref = 26; // URI 引用 bool uuid = 27; // UUID // 中文业务格式 - 这是优化点! bool chinese_mobile = 30; // 中国手机号 bool chinese_id_card = 31; // 中国身份证号 bool chinese_name = 32; // 中文姓名 bool chinese_postcode = 33; // 中国邮政编码 } // 字符类型限制 optional bool ascii = 40; // 仅 ASCII 字符 optional bool printable = 41; // 可打印字符 optional bool alpha = 42; // 仅字母 optional bool alphanumeric = 43; // 字母和数字 optional bool numeric = 44; // 仅数字 // 大小写要求 optional bool lowercase = 50; // 仅小写 optional bool uppercase = 51; // 仅大写 } // 字节数组验证规则 message BytesRules { optional bytes const = 1; optional uint64 len = 2; optional uint64 min_len = 3; optional uint64 max_len = 4; optional bytes pattern = 5; optional bytes prefix = 6; optional bytes suffix = 7; optional bytes contains = 8; repeated bytes in = 9; repeated bytes not_in = 10; // Well-known 格式 oneof well_known { bool ip = 20; bool ipv4 = 21; bool ipv6 = 22; } } // ============================================================================ // 复杂类型验证规则 // ============================================================================ // 枚举验证规则 message EnumRules { optional int32 const = 1; optional bool defined_only = 2; // 仅允许已定义的枚举值 repeated int32 in = 3; repeated int32 not_in = 4; } // 重复字段验证规则 message RepeatedRules { optional uint64 min_items = 1; // 最小元素数 optional uint64 max_items = 2; // 最大元素数 optional bool unique = 3; // 元素必须唯一 FieldRules items = 4; // 元素验证规则 } // Map 验证规则 message MapRules { optional uint64 min_pairs = 1; // 最小键值对数 optional uint64 max_pairs = 2; // 最大键值对数 FieldRules keys = 3; // 键验证规则 FieldRules values = 4; // 值验证规则 } // ============================================================================ // Well-Known Types 验证规则 // ============================================================================ // Duration 验证规则 message DurationRules { optional bool required = 1; // Duration 常量 optional int64 const_seconds = 2; optional int32 const_nanos = 3; // 范围限制 optional int64 lt_seconds = 4; optional int64 lte_seconds = 5; optional int64 gt_seconds = 6; optional int64 gte_seconds = 7; // 在值列表中 repeated int64 in_seconds = 8; repeated int64 not_in_seconds = 9; } // Timestamp 验证规则 message TimestampRules { optional bool required = 1; // Timestamp 常量(Unix 秒) optional int64 const = 2; // 范围限制 optional int64 lt = 3; optional int64 lte = 4; optional int64 gt = 5; optional int64 gte = 6; // 相对时间限制 optional bool lt_now = 7; // 必须在当前时间之前 optional bool gt_now = 8; // 必须在当前时间之后 // 时间范围(从现在开始的偏移量,秒) optional int64 within_seconds = 9; // 必须在现在的 N 秒内 }