// 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; }