syntax = "proto3"; package komp_ac.analytics; import "google/protobuf/struct.proto"; // Runs read-only analytical SQL over runtime-defined profile tables. // Public SQL uses table and column aliases; physical ordinal column names are // resolved inside the server and are never exposed by this API. service AnalyticsService { // Lists the alias-visible analytical tables for one profile. rpc GetAnalyticsCatalog(GetAnalyticsCatalogRequest) returns (GetAnalyticsCatalogResponse); // Executes one read-only SELECT query and streams typed result batches. rpc ExecuteAnalyticsQuery(ExecuteAnalyticsQueryRequest) returns (stream AnalyticsResultBatch); } message GetAnalyticsCatalogRequest { // Required PostgreSQL profile/schema name. string profile_name = 1; } message GetAnalyticsCatalogResponse { string profile_name = 1; repeated AnalyticsTable tables = 2; } message AnalyticsTable { int64 table_definition_id = 1; string name = 2; repeated AnalyticsCatalogColumn columns = 3; repeated AnalyticsTableLink links = 4; string base_currency = 5; } message AnalyticsCatalogColumn { // Current public alias. Physical ordinal names are intentionally omitted. string name = 1; string field_type = 2; bool is_system = 3; string rounding = 4; } message AnalyticsTableLink { // Public foreign-key column on the source table, e.g. department_id. string source_column = 1; string linked_table = 2; bool required = 3; } message ExecuteAnalyticsQueryRequest { // Required profile whose tables form the query's complete visible catalog. string profile_name = 1; // Exactly one read-only SELECT query. Table and column names are public aliases. string sql = 2; // Result cap. Zero uses the server default; the server maximum still applies. uint32 max_rows = 3; } message AnalyticsResultColumn { string name = 1; string data_type = 2; } message AnalyticsValue { oneof kind { google.protobuf.NullValue null_value = 1; bool bool_value = 2; int64 int64_value = 3; uint64 uint64_value = 4; double double_value = 5; string string_value = 6; bytes bytes_value = 7; } } message AnalyticsResultRow { repeated AnalyticsValue values = 1; } message AnalyticsResultBatch { // Present on the first batch and omitted from later data batches. repeated AnalyticsResultColumn columns = 1; repeated AnalyticsResultRow rows = 2; // The final message contains no rows and carries completion metadata. bool is_final = 3; bool truncated = 4; uint64 row_count = 5; uint64 elapsed_ms = 6; }