From 7263003684d9a205e562558c1fa7ba8b7137bacb Mon Sep 17 00:00:00 2001 From: Filipriec Date: Tue, 1 Sep 2026 10:21:34 +0200 Subject: [PATCH] option values are aliased always from now on --- common/proto/table_definition.proto | 32 +++++ common/src/proto/descriptor.bin | Bin 217811 -> 219529 bytes common/src/proto/komp_ac.table_definition.rs | 134 ++++++++++++++++++- server | 2 +- 4 files changed, 166 insertions(+), 2 deletions(-) diff --git a/common/proto/table_definition.proto b/common/proto/table_definition.proto index 045c08c3..bba0b921 100644 --- a/common/proto/table_definition.proto +++ b/common/proto/table_definition.proto @@ -62,6 +62,10 @@ service TableDefinition { // Physical column names and identities remain unchanged. rpc SetColumnPresentation(SetColumnPresentationRequest) returns (SetColumnPresentationResponse); + // Replaces the optional user-visible aliases for a fixed-option column. + // Stored values remain stable machine values and scripts never depend on labels. + rpc SetColumnOptionAliases(SetColumnOptionAliasesRequest) returns (SetColumnOptionAliasesResponse); + // Shows or hides one column in bundled data-entry forms. This is presentation // metadata only: hidden columns remain available to data APIs, scripts and // backend calculations. @@ -525,6 +529,10 @@ message ColumnBehavior { // True when bundled data-entry clients should not render this column. // This is not an authorization boundary; data APIs still expose the column. bool hidden_from_forms = 6; + + // User-selected labels for stable option values. Empty means clients display + // the canonical value. Writes may submit either value or alias. + repeated OptionValueAlias option_value_aliases = 7; } // A script that targets a specific column in a table. @@ -561,6 +569,30 @@ message SetColumnPresentationResponse { int64 row_version = 4; } +// One stable machine value and its optional user-visible/input alias. +message OptionValueAlias { + string value = 1; + string alias = 2; +} + +message SetColumnOptionAliasesRequest { + string profile_name = 1; + string table_name = 2; + int64 column_id = 3; + // Partial sets are supported; omitted values use their canonical spelling. + // An empty list removes every alias from the column. + repeated OptionValueAlias aliases = 4; + int64 expected_row_version = 5; +} + +message SetColumnOptionAliasesResponse { + bool success = 1; + string message = 2; + int64 column_id = 3; + repeated OptionValueAlias aliases = 4; + int64 row_version = 5; +} + message SetColumnFormVisibilityRequest { string profile_name = 1; string table_name = 2; diff --git a/common/src/proto/descriptor.bin b/common/src/proto/descriptor.bin index 9d971a776789dd15770a2ec64b31cc4450aa26d0..2e2427d9b7c280df490af7c428f6bca2225239bb 100644 GIT binary patch delta 15034 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 delta 13779 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 diff --git a/common/src/proto/komp_ac.table_definition.rs b/common/src/proto/komp_ac.table_definition.rs index 38150198..a9e9ca17 100644 --- a/common/src/proto/komp_ac.table_definition.rs +++ b/common/src/proto/komp_ac.table_definition.rs @@ -524,7 +524,7 @@ pub struct TableDetail { } /// Server-owned behavior for one logical column returned in table details. #[derive(serde::Serialize, serde::Deserialize)] -#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ColumnBehavior { /// True when the server created the column as a companion of another column. #[prost(bool, tag = "1")] @@ -545,6 +545,10 @@ pub struct ColumnBehavior { /// This is not an authorization boundary; data APIs still expose the column. #[prost(bool, tag = "6")] pub hidden_from_forms: bool, + /// User-selected labels for stable option values. Empty means clients display + /// the canonical value. Writes may submit either value or alias. + #[prost(message, repeated, tag = "7")] + pub option_value_aliases: ::prost::alloc::vec::Vec, } /// A script that targets a specific column in a table. #[derive(serde::Serialize, serde::Deserialize)] @@ -599,6 +603,45 @@ pub struct SetColumnPresentationResponse { #[prost(int64, tag = "4")] pub row_version: i64, } +/// One stable machine value and its optional user-visible/input alias. +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct OptionValueAlias { + #[prost(string, tag = "1")] + pub value: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub alias: ::prost::alloc::string::String, +} +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SetColumnOptionAliasesRequest { + #[prost(string, tag = "1")] + pub profile_name: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub table_name: ::prost::alloc::string::String, + #[prost(int64, tag = "3")] + pub column_id: i64, + /// Partial sets are supported; omitted values use their canonical spelling. + /// An empty list removes every alias from the column. + #[prost(message, repeated, tag = "4")] + pub aliases: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "5")] + pub expected_row_version: i64, +} +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SetColumnOptionAliasesResponse { + #[prost(bool, tag = "1")] + pub success: bool, + #[prost(string, tag = "2")] + pub message: ::prost::alloc::string::String, + #[prost(int64, tag = "3")] + pub column_id: i64, + #[prost(message, repeated, tag = "4")] + pub aliases: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "5")] + pub row_version: i64, +} #[derive(serde::Serialize, serde::Deserialize)] #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct SetColumnFormVisibilityRequest { @@ -1391,6 +1434,37 @@ pub mod table_definition_client { ); self.inner.unary(req, path, codec).await } + /// Replaces the optional user-visible aliases for a fixed-option column. + /// Stored values remain stable machine values and scripts never depend on labels. + pub async fn set_column_option_aliases( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/komp_ac.table_definition.TableDefinition/SetColumnOptionAliases", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new( + "komp_ac.table_definition.TableDefinition", + "SetColumnOptionAliases", + ), + ); + self.inner.unary(req, path, codec).await + } /// Shows or hides one column in bundled data-entry forms. This is presentation /// metadata only: hidden columns remain available to data APIs, scripts and /// backend calculations. @@ -1586,6 +1660,15 @@ pub mod table_definition_server { tonic::Response, tonic::Status, >; + /// Replaces the optional user-visible aliases for a fixed-option column. + /// Stored values remain stable machine values and scripts never depend on labels. + async fn set_column_option_aliases( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; /// Shows or hides one column in bundled data-entry forms. This is presentation /// metadata only: hidden columns remain available to data APIs, scripts and /// backend calculations. @@ -2319,6 +2402,55 @@ pub mod table_definition_server { }; Box::pin(fut) } + "/komp_ac.table_definition.TableDefinition/SetColumnOptionAliases" => { + #[allow(non_camel_case_types)] + struct SetColumnOptionAliasesSvc(pub Arc); + impl< + T: TableDefinition, + > tonic::server::UnaryService + for SetColumnOptionAliasesSvc { + type Response = super::SetColumnOptionAliasesResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::set_column_option_aliases( + &inner, + request, + ) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = SetColumnOptionAliasesSvc(inner); + let codec = tonic_prost::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } "/komp_ac.table_definition.TableDefinition/SetColumnFormVisibility" => { #[allow(non_camel_case_types)] struct SetColumnFormVisibilitySvc(pub Arc); diff --git a/server b/server index bcccf825..825a5bcf 160000 --- a/server +++ b/server @@ -1 +1 @@ -Subproject commit bcccf8253ce0c2e53d2c1e840e843a9a8ad226a7 +Subproject commit 825a5bcf321655ba3821718eae817982f1e40e5d