306 lines
8.7 KiB
Protocol Buffer
306 lines
8.7 KiB
Protocol Buffer
// common/proto/table_validation.proto
|
||
syntax = "proto3";
|
||
package komp_ac.table_validation;
|
||
|
||
// This proto is the canonical server-side storage and distribution contract for
|
||
// client validation configuration.
|
||
//
|
||
// Design goals:
|
||
// - The server stores the entire field validation definition in one structured payload.
|
||
// - Clients fetch the validation rules for a table in one batch and map them to
|
||
// their local validation/runtime system (for example canvas).
|
||
// - Common validation must be represented as typed data, not as string mini-languages.
|
||
//
|
||
// Important split:
|
||
// - limits / pattern / allowed_values / required are validation rules.
|
||
// - mask / formatter are presentation and input-shaping metadata for clients.
|
||
|
||
// Request validation rules for a table
|
||
message GetTableValidationRequest {
|
||
string profileName = 1;
|
||
string tableName = 2;
|
||
}
|
||
|
||
// Response with field-level validations for the whole table.
|
||
// If a field is omitted, no validation configuration exists for that field.
|
||
message TableValidationResponse {
|
||
repeated FieldValidation fields = 1;
|
||
}
|
||
|
||
// Field-level validation definition stored on the server and distributed to clients.
|
||
message FieldValidation {
|
||
// MUST match your frontend FormState.dataKey for the column
|
||
string dataKey = 1;
|
||
|
||
// Validation 1: length and counting rules.
|
||
CharacterLimits limits = 10;
|
||
|
||
// Validation 2: position-based character constraints.
|
||
PatternRules pattern = 11;
|
||
|
||
// Exact-value whitelist.
|
||
AllowedValues allowed_values = 12;
|
||
|
||
// Client-side hint that this field participates in external/asynchronous validation UI.
|
||
bool external_validation_enabled = 13;
|
||
|
||
// Client-side formatter metadata. This is intentionally data-only, not executable code.
|
||
optional CustomFormatter formatter = 14;
|
||
|
||
// Client-side display mask metadata. The server stores raw data without mask literals.
|
||
DisplayMask mask = 3;
|
||
|
||
// Field must be provided / treated as required by clients and server enforcement layers.
|
||
bool required = 4;
|
||
}
|
||
|
||
// Character length counting mode
|
||
enum CountMode {
|
||
COUNT_MODE_UNSPECIFIED = 0; // default: same as CHARS
|
||
CHARS = 1;
|
||
BYTES = 2;
|
||
DISPLAY_WIDTH = 3;
|
||
}
|
||
|
||
// Character limit validation (Validation 1).
|
||
// These rules map directly to canvas CharacterLimits.
|
||
message CharacterLimits {
|
||
// When zero, the field is considered "not set". If both min/max are zero,
|
||
// the server should avoid sending this FieldValidation (no validation).
|
||
uint32 min = 1;
|
||
uint32 max = 2;
|
||
|
||
// Optional warning threshold; when unset, no warning threshold is applied.
|
||
optional uint32 warnAt = 3;
|
||
|
||
CountMode countMode = 4; // defaults to CHARS if unspecified
|
||
}
|
||
|
||
// Mask for pretty display only.
|
||
//
|
||
// This is not a validation rule by itself. It exists so clients can render and
|
||
// navigate masked input while still storing raw values server-side.
|
||
message DisplayMask {
|
||
string pattern = 1; // e.g., "(###) ###-####" or "####-##-##"
|
||
string input_char = 2; // e.g., "#"
|
||
optional string template_char = 3; // e.g., "_"
|
||
}
|
||
|
||
// Which positions a pattern rule applies to.
|
||
// This exists instead of a string syntax like "0-3" so the server can validate
|
||
// the structure directly and clients do not need to parse a DSL.
|
||
message PatternPosition {
|
||
PatternPositionKind kind = 1;
|
||
uint32 single = 2;
|
||
uint32 start = 3;
|
||
uint32 end = 4;
|
||
repeated uint32 positions = 5;
|
||
}
|
||
|
||
enum PatternPositionKind {
|
||
PATTERN_POSITION_KIND_UNSPECIFIED = 0;
|
||
PATTERN_POSITION_SINGLE = 1;
|
||
PATTERN_POSITION_RANGE = 2;
|
||
PATTERN_POSITION_FROM = 3;
|
||
PATTERN_POSITION_MULTIPLE = 4;
|
||
}
|
||
|
||
// What type of character constraint a pattern rule applies.
|
||
// This mirrors the typed character filters used by canvas.
|
||
message CharacterConstraint {
|
||
CharacterConstraintKind kind = 1;
|
||
|
||
// Used when kind == CHARACTER_CONSTRAINT_EXACT.
|
||
optional string exact = 2;
|
||
|
||
// Used when kind == CHARACTER_CONSTRAINT_ONE_OF.
|
||
repeated string one_of = 3;
|
||
|
||
// Used when kind == CHARACTER_CONSTRAINT_REGEX.
|
||
optional string regex = 4;
|
||
}
|
||
|
||
enum CharacterConstraintKind {
|
||
CHARACTER_CONSTRAINT_KIND_UNSPECIFIED = 0;
|
||
CHARACTER_CONSTRAINT_ALPHABETIC = 1;
|
||
CHARACTER_CONSTRAINT_NUMERIC = 2;
|
||
CHARACTER_CONSTRAINT_ALPHANUMERIC = 3;
|
||
CHARACTER_CONSTRAINT_EXACT = 4;
|
||
CHARACTER_CONSTRAINT_ONE_OF = 5;
|
||
CHARACTER_CONSTRAINT_REGEX = 6;
|
||
}
|
||
|
||
// One position-based validation rule, similar to canvas PositionFilter.
|
||
message PatternRule {
|
||
PatternPosition position = 1;
|
||
CharacterConstraint constraint = 2;
|
||
}
|
||
|
||
// Client-side formatter metadata.
|
||
// The formatter "type" is intended to be resolved by a client-side formatter registry.
|
||
message CustomFormatter {
|
||
// Formatter type identifier; handled client‑side.
|
||
// Examples: "PSCFormatter", "PhoneFormatter", "CreditCardFormatter", "DateFormatter"
|
||
string type = 1;
|
||
|
||
repeated FormatterOption options = 2;
|
||
optional string description = 3;
|
||
}
|
||
|
||
message FormatterOption {
|
||
string key = 1;
|
||
string value = 2;
|
||
}
|
||
|
||
// Exact-value whitelist configuration.
|
||
// This maps to canvas AllowedValues semantics.
|
||
message AllowedValues {
|
||
repeated string values = 1;
|
||
bool allow_empty = 2;
|
||
bool case_insensitive = 3;
|
||
}
|
||
|
||
// Collection of pattern rules for one field.
|
||
message PatternRules {
|
||
// All rules that make up the validation logic
|
||
repeated PatternRule rules = 1;
|
||
|
||
// Optional human‑readable description for UI/debug purposes
|
||
optional string description = 2;
|
||
}
|
||
|
||
// Service for storing and fetching field-validation definitions.
|
||
service TableValidationService {
|
||
rpc GetTableValidation(GetTableValidationRequest) returns (TableValidationResponse);
|
||
|
||
// Upsert a single field validation definition.
|
||
rpc UpdateFieldValidation(UpdateFieldValidationRequest) returns (UpdateFieldValidationResponse);
|
||
|
||
// Replace the full validation definition set for a table in one transaction.
|
||
rpc ReplaceTableValidation(ReplaceTableValidationRequest) returns (ReplaceTableValidationResponse);
|
||
|
||
// Reusable named rule fragments.
|
||
rpc UpsertValidationRule(UpsertValidationRuleRequest) returns (UpsertValidationRuleResponse);
|
||
rpc ListValidationRules(ListValidationRulesRequest) returns (ListValidationRulesResponse);
|
||
rpc DeleteValidationRule(DeleteValidationRuleRequest) returns (DeleteValidationRuleResponse);
|
||
|
||
// Reusable named sets composed from rules.
|
||
rpc UpsertValidationSet(UpsertValidationSetRequest) returns (UpsertValidationSetResponse);
|
||
rpc ListValidationSets(ListValidationSetsRequest) returns (ListValidationSetsResponse);
|
||
rpc DeleteValidationSet(DeleteValidationSetRequest) returns (DeleteValidationSetResponse);
|
||
|
||
// Snapshot a reusable set onto a concrete table field.
|
||
rpc ApplyValidationSet(ApplyValidationSetRequest) returns (ApplyValidationSetResponse);
|
||
}
|
||
|
||
message UpdateFieldValidationRequest {
|
||
string profileName = 1;
|
||
string tableName = 2;
|
||
string dataKey = 3;
|
||
FieldValidation validation = 4;
|
||
}
|
||
|
||
message UpdateFieldValidationResponse {
|
||
bool success = 1;
|
||
string message = 2;
|
||
}
|
||
|
||
message ReplaceTableValidationRequest {
|
||
string profileName = 1;
|
||
string tableName = 2;
|
||
|
||
// Full replacement set. Fields omitted here are removed from the stored config.
|
||
repeated FieldValidation fields = 3;
|
||
}
|
||
|
||
message ReplaceTableValidationResponse {
|
||
bool success = 1;
|
||
string message = 2;
|
||
}
|
||
|
||
message ValidationRuleDefinition {
|
||
string name = 1;
|
||
optional string description = 2;
|
||
|
||
// Reusable rule fragment. dataKey is ignored by the server for reusable rules.
|
||
FieldValidation validation = 3;
|
||
}
|
||
|
||
message ValidationSetDefinition {
|
||
string name = 1;
|
||
optional string description = 2;
|
||
repeated string ruleNames = 3;
|
||
|
||
// Server-resolved snapshot of all rules in ruleNames order.
|
||
FieldValidation resolvedValidation = 4;
|
||
}
|
||
|
||
message UpsertValidationRuleRequest {
|
||
string profileName = 1;
|
||
ValidationRuleDefinition rule = 2;
|
||
}
|
||
|
||
message UpsertValidationRuleResponse {
|
||
bool success = 1;
|
||
string message = 2;
|
||
}
|
||
|
||
message ListValidationRulesRequest {
|
||
string profileName = 1;
|
||
}
|
||
|
||
message ListValidationRulesResponse {
|
||
repeated ValidationRuleDefinition rules = 1;
|
||
}
|
||
|
||
message DeleteValidationRuleRequest {
|
||
string profileName = 1;
|
||
string name = 2;
|
||
}
|
||
|
||
message DeleteValidationRuleResponse {
|
||
bool success = 1;
|
||
string message = 2;
|
||
}
|
||
|
||
message UpsertValidationSetRequest {
|
||
string profileName = 1;
|
||
ValidationSetDefinition set = 2;
|
||
}
|
||
|
||
message UpsertValidationSetResponse {
|
||
bool success = 1;
|
||
string message = 2;
|
||
}
|
||
|
||
message ListValidationSetsRequest {
|
||
string profileName = 1;
|
||
}
|
||
|
||
message ListValidationSetsResponse {
|
||
repeated ValidationSetDefinition sets = 1;
|
||
}
|
||
|
||
message DeleteValidationSetRequest {
|
||
string profileName = 1;
|
||
string name = 2;
|
||
}
|
||
|
||
message DeleteValidationSetResponse {
|
||
bool success = 1;
|
||
string message = 2;
|
||
}
|
||
|
||
message ApplyValidationSetRequest {
|
||
string profileName = 1;
|
||
string tableName = 2;
|
||
string dataKey = 3;
|
||
string setName = 4;
|
||
}
|
||
|
||
message ApplyValidationSetResponse {
|
||
bool success = 1;
|
||
string message = 2;
|
||
FieldValidation validation = 3;
|
||
}
|