table validation for the client from the server

This commit is contained in:
Priec
2026-05-03 10:34:59 +02:00
parent 90f8aedc3b
commit 0600d3deaa
5 changed files with 437 additions and 61 deletions

View File

@@ -2,31 +2,55 @@
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; if a field is omitted,
// no validation is applied (default unspecified).
// 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 (extensible for future kinds)
// 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;
// Current: only CharacterLimits. More rules can be added later.
// Validation 1: length and counting rules.
CharacterLimits limits = 10;
// Future expansion:
PatternRules pattern = 11; // Validation 2
optional CustomFormatter formatter = 14; // Validation 4 custom formatting logic
// 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;
// ExternalValidation external = 13;
// CustomFormatter formatter = 14;
// Field must be provided / treated as required by clients and server enforcement layers.
bool required = 4;
}
@@ -38,7 +62,8 @@ enum CountMode {
DISPLAY_WIDTH = 3;
}
// Character limit validation (Validation 1)
// 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).
@@ -51,39 +76,91 @@ message CharacterLimits {
CountMode countMode = 4; // defaults to CHARS if unspecified
}
// Mask for pretty display
// 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., "_"
}
// One positionbased validation rule, similar to CharacterFilter + PositionRange
message PatternRule {
// Range descriptor: how far the rule applies
// Examples:
// - "0" → Single position 0
// - "0-3" → Range 0..3 inclusive
// - "from:5" → From position 5 onward
// - "0,2,5" → Multiple discrete positions
string range = 1;
// Character filter type, caseinsensitive keywords:
// "ALPHABETIC", "NUMERIC", "ALPHANUMERIC",
// "ONEOF(<chars>)", "EXACT(:)", "CUSTOM(<name>)"
string filter = 2;
// 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 clientside.
// Examples: "PSCFormatter", "PhoneFormatter", "CreditCardFormatter", "DateFormatter"
string type = 1;
// Optional freetext note or parameters (e.g. locale, pattern)
optional string description = 2;
repeated FormatterOption options = 2;
optional string description = 3;
}
// Collection of pattern rules for one field
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;
@@ -92,11 +169,15 @@ message PatternRules {
optional string description = 2;
}
// Service to fetch validations for a table
// 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);
}
message UpdateFieldValidationRequest {
@@ -110,3 +191,16 @@ 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;
}