migration can gain functionality of table definition from now on2

This commit is contained in:
Priec
2026-09-08 16:38:21 +02:00
parent d8663d946f
commit 4a378a5c1e
9 changed files with 751 additions and 219 deletions

2
client

Submodule client updated: 7687c80524...4bb6a4b07a

View File

@@ -12,7 +12,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.type_attribute(".komp_ac.common", serde) .type_attribute(".komp_ac.common", serde)
.type_attribute(".komp_ac.document_data", serde) .type_attribute(".komp_ac.document_data", serde)
.type_attribute( .type_attribute(
".komp_ac.document_data.TypstTemplateVersion", ".komp_ac.document_data.DocumentTemplateVersion",
"#[derive(Eq)]", "#[derive(Eq)]",
) )
.type_attribute(".komp_ac.ecb", serde) .type_attribute(".komp_ac.ecb", serde)

View File

@@ -2,15 +2,30 @@ syntax = "proto3";
package komp_ac.document_data; package komp_ac.document_data;
service DocumentDataService { service DocumentDataService {
rpc RegisterTypstTemplate(RegisterTypstTemplateRequest) returns (RegisterTypstTemplateResponse); rpc RegisterDocumentTemplate(RegisterDocumentTemplateRequest) returns (RegisterDocumentTemplateResponse);
rpc ListTypstTemplates(ListTypstTemplatesRequest) returns (ListTypstTemplatesResponse); rpc ListDocumentTemplates(ListDocumentTemplatesRequest) returns (ListDocumentTemplatesResponse);
rpc ListEnabledTypstTemplates(ListEnabledTypstTemplatesRequest) returns (ListTypstTemplatesResponse); rpc ListEnabledDocumentTemplates(ListEnabledDocumentTemplatesRequest) returns (ListDocumentTemplatesResponse);
rpc SaveDocument(SaveDocumentRequest) returns (SaveDocumentResponse); rpc SaveDocument(SaveDocumentRequest) returns (SaveDocumentResponse);
rpc UpdateDocument(UpdateDocumentRequest) returns (UpdateDocumentResponse); rpc UpdateDocument(UpdateDocumentRequest) returns (UpdateDocumentResponse);
rpc RenderTextDocument(RenderTextDocumentRequest) returns (RenderTextDocumentResponse);
rpc FinalizeDocument(FinalizeDocumentRequest) returns (FinalizeDocumentResponse);
rpc GetArchivedDocument(GetArchivedDocumentRequest) returns (GetArchivedDocumentResponse);
rpc GetDocuments(GetDocumentsRequest) returns (GetDocumentsResponse); rpc GetDocuments(GetDocumentsRequest) returns (GetDocumentsResponse);
rpc GetDocument(GetDocumentRequest) returns (GetDocumentResponse); rpc GetDocument(GetDocumentRequest) returns (GetDocumentResponse);
rpc GetDocumentVersion(GetDocumentVersionRequest) returns (GetDocumentVersionResponse); rpc GetDocumentVersion(GetDocumentVersionRequest) returns (GetDocumentVersionResponse);
rpc GetTypstTemplateVersion(GetTypstTemplateVersionRequest) returns (GetTypstTemplateVersionResponse); rpc GetDocumentTemplateVersion(GetDocumentTemplateVersionRequest) returns (GetDocumentTemplateVersionResponse);
}
enum DocumentFormat {
DOCUMENT_FORMAT_UNSPECIFIED = 0;
DOCUMENT_FORMAT_TYPST = 1;
DOCUMENT_FORMAT_PLAIN_TEXT = 2;
}
enum DocumentState {
DOCUMENT_STATE_UNSPECIFIED = 0;
DOCUMENT_STATE_DRAFT = 1;
DOCUMENT_STATE_FINALIZED = 2;
} }
message SourceRecord { message SourceRecord {
@@ -25,29 +40,32 @@ message SaveDocumentRequest {
string template_name = 2; string template_name = 2;
string data_json = 3; string data_json = 3;
int64 expected_template_version_id = 4; int64 expected_template_version_id = 4;
string profile_name = 5;
} }
message RegisterTypstTemplateRequest { message RegisterDocumentTemplateRequest {
string template_name = 1; string template_name = 1;
string input_table_name = 2; string input_table_name = 2;
string typst_source = 3; string template_source = 3;
string typst_compiler_version = 4; string renderer_version = 4;
DocumentFormat format = 5;
} }
message RegisterTypstTemplateResponse { message RegisterDocumentTemplateResponse {
TypstTemplateVersion template_version = 1; DocumentTemplateVersion template_version = 1;
} }
message ListTypstTemplatesRequest { message ListDocumentTemplatesRequest {
string search = 1; string search = 1;
uint32 limit = 2; uint32 limit = 2;
DocumentFormat format = 3;
} }
message ListTypstTemplatesResponse { message ListDocumentTemplatesResponse {
repeated TypstTemplateVersion templates = 1; repeated DocumentTemplateVersion templates = 1;
} }
message ListEnabledTypstTemplatesRequest { message ListEnabledDocumentTemplatesRequest {
string profile_name = 1; string profile_name = 1;
} }
@@ -62,6 +80,8 @@ message SaveDocumentResponse {
message UpdateDocumentRequest { message UpdateDocumentRequest {
int64 document_id = 1; int64 document_id = 1;
string data_json = 2; string data_json = 2;
string profile_name = 3;
int32 expected_version_number = 4;
} }
message UpdateDocumentResponse { message UpdateDocumentResponse {
@@ -76,6 +96,7 @@ message GetDocumentsRequest {
optional string template_name = 3; optional string template_name = 3;
optional string source_profile_name = 4; optional string source_profile_name = 4;
optional string source_table_name = 5; optional string source_table_name = 5;
string profile_name = 6;
} }
enum DocumentDataChangeKind { enum DocumentDataChangeKind {
@@ -96,6 +117,9 @@ message Document {
string updated_at = 9; string updated_at = 9;
int64 template_version_id = 10; int64 template_version_id = 10;
string data_sha256 = 11; string data_sha256 = 11;
string profile_name = 12;
DocumentState state = 13;
optional int64 archive_id = 14;
} }
message GetDocumentsResponse { message GetDocumentsResponse {
@@ -104,6 +128,7 @@ message GetDocumentsResponse {
message GetDocumentRequest { message GetDocumentRequest {
int64 document_id = 1; int64 document_id = 1;
string profile_name = 2;
} }
message GetDocumentResponse { message GetDocumentResponse {
@@ -113,40 +138,90 @@ message GetDocumentResponse {
message GetDocumentVersionRequest { message GetDocumentVersionRequest {
int64 document_id = 1; int64 document_id = 1;
int32 version_number = 2; int32 version_number = 2;
string profile_name = 3;
} }
message GetDocumentVersionResponse { message GetDocumentVersionResponse {
optional Document document = 1; optional Document document = 1;
} }
message GetTypstTemplateVersionRequest { message GetDocumentTemplateVersionRequest {
int64 template_version_id = 1; int64 template_version_id = 1;
int64 document_id = 2; int64 document_id = 2;
string profile_name = 3;
} }
message TypstTemplateVersion { message DocumentTemplateVersion {
int64 id = 1; int64 id = 1;
int64 template_id = 2; int64 template_id = 2;
string template_name = 3; string template_name = 3;
int32 version = 4; int32 version = 4;
string source_code = 5; string source_code = 5;
string source_sha256 = 6; string source_sha256 = 6;
string typst_compiler_version = 7; string renderer_version = 7;
string created_at = 8; string created_at = 8;
string input_table_name = 9; string input_table_name = 9;
repeated string field_paths = 10; repeated string field_paths = 10;
repeated TypstTemplateFieldBinding field_bindings = 11; repeated DocumentTemplateFieldBinding field_bindings = 11;
DocumentFormat format = 12;
} }
// One profile-specific source mapping for an enabled template version. // One profile-specific source mapping for an enabled template version.
message TypstTemplateFieldBinding { message DocumentTemplateFieldBinding {
string field_path = 1; string field_path = 1;
string collection_path = 2; string collection_path = 2;
string column_name = 3; string column_name = 3;
string source_table_name = 4; string source_table_name = 4;
string source_column_name = 5; string source_column_name = 5;
string source_profile_name = 6;
} }
message GetTypstTemplateVersionResponse { message GetDocumentTemplateVersionResponse {
optional TypstTemplateVersion template_version = 1; optional DocumentTemplateVersion template_version = 1;
}
message RenderTextDocumentRequest {
string profile_name = 1;
int64 document_id = 2;
int32 expected_version_number = 3;
}
message RenderTextDocumentResponse {
string text = 1;
string renderer_version = 2;
string data_sha256 = 3;
}
message FinalizeDocumentRequest {
string profile_name = 1;
int64 document_id = 2;
int32 expected_version_number = 3;
// Typst output is compiled by the caller with the pinned template and data.
// Plain-text output is rendered by the server; these fields must be empty.
bytes rendered_output = 4;
string renderer_version = 5;
}
message FinalizeDocumentResponse {
int64 archive_id = 1;
string output_sha256 = 2;
}
message GetArchivedDocumentRequest {
string profile_name = 1;
int64 archive_id = 2;
}
message ArchivedDocument {
int64 id = 1;
Document document = 2;
DocumentTemplateVersion template_version = 3;
DocumentFormat format = 4;
bytes output = 5;
string output_sha256 = 6;
string finalized_at = 7;
}
message GetArchivedDocumentResponse {
optional ArchivedDocument document = 1;
} }

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -25,10 +25,10 @@ use common::proto::komp_ac::accounting::{
use common::proto::komp_ac::common::Empty; use common::proto::komp_ac::common::Empty;
use common::proto::komp_ac::document_data::{ use common::proto::komp_ac::document_data::{
GetDocumentRequest, GetDocumentResponse, GetDocumentVersionRequest, GetDocumentVersionResponse, GetDocumentRequest, GetDocumentResponse, GetDocumentVersionRequest, GetDocumentVersionResponse,
GetDocumentsRequest, GetDocumentsResponse, GetTypstTemplateVersionRequest, GetDocumentsRequest, GetDocumentsResponse, GetDocumentTemplateVersionRequest,
GetTypstTemplateVersionResponse, ListEnabledTypstTemplatesRequest, GetDocumentTemplateVersionResponse, ListEnabledDocumentTemplatesRequest,
ListTypstTemplatesRequest, ListTypstTemplatesResponse, RegisterTypstTemplateRequest, ListDocumentTemplatesRequest, ListDocumentTemplatesResponse, RegisterDocumentTemplateRequest,
RegisterTypstTemplateResponse, SaveDocumentRequest, SaveDocumentResponse, RegisterDocumentTemplateResponse, SaveDocumentRequest, SaveDocumentResponse,
UpdateDocumentRequest, UpdateDocumentResponse, UpdateDocumentRequest, UpdateDocumentResponse,
document_data_service_client::DocumentDataServiceClient, document_data_service_client::DocumentDataServiceClient,
}; };
@@ -122,7 +122,9 @@ impl GrpcClient {
let table_definition_client = TableDefinitionClient::new(channel.clone()); let table_definition_client = TableDefinitionClient::new(channel.clone());
let table_script_client = TableScriptClient::new(channel.clone()); let table_script_client = TableScriptClient::new(channel.clone());
let tables_data_client = TablesDataClient::new(channel.clone()); let tables_data_client = TablesDataClient::new(channel.clone());
let document_data_client = DocumentDataServiceClient::new(channel.clone()); let document_data_client = DocumentDataServiceClient::new(channel.clone())
.max_decoding_message_size(64 * 1024 * 1024)
.max_encoding_message_size(64 * 1024 * 1024);
let search_client = SearchGrpc::new(channel.clone()); let search_client = SearchGrpc::new(channel.clone());
let table_validation_client = TableValidationServiceClient::new(channel.clone()); let table_validation_client = TableValidationServiceClient::new(channel.clone());
let accounting_client = AccountingClient::new(channel.clone()); let accounting_client = AccountingClient::new(channel.clone());
@@ -1092,45 +1094,46 @@ impl GrpcClient {
Ok(response.into_inner()) Ok(response.into_inner())
} }
pub async fn list_enabled_typst_templates( pub async fn list_enabled_document_templates(
&mut self, &mut self,
profile_name: String, profile_name: String,
) -> Result<ListTypstTemplatesResponse> { ) -> Result<ListDocumentTemplatesResponse> {
let request = self.authenticated_request(ListEnabledTypstTemplatesRequest { let request = self.authenticated_request(ListEnabledDocumentTemplatesRequest {
profile_name, profile_name,
})?; })?;
let response = self let response = self
.document_data_client .document_data_client
.list_enabled_typst_templates(request) .list_enabled_document_templates(request)
.await .await
.context("gRPC ListEnabledTypstTemplates call failed")?; .context("gRPC ListEnabledDocumentTemplates call failed")?;
Ok(response.into_inner()) Ok(response.into_inner())
} }
pub async fn list_typst_templates( pub async fn list_document_templates(
&mut self, &mut self,
format: common::proto::komp_ac::document_data::DocumentFormat,
search: String, search: String,
limit: u32, limit: u32,
) -> Result<ListTypstTemplatesResponse> { ) -> Result<ListDocumentTemplatesResponse> {
let request = self.authenticated_request(ListTypstTemplatesRequest { search, limit })?; let request = self.authenticated_request(ListDocumentTemplatesRequest { search, limit, format: format.into() })?;
let response = self let response = self
.document_data_client .document_data_client
.list_typst_templates(request) .list_document_templates(request)
.await .await
.context("gRPC ListTypstTemplates call failed")?; .context("gRPC ListDocumentTemplates call failed")?;
Ok(response.into_inner()) Ok(response.into_inner())
} }
pub async fn register_typst_template( pub async fn register_document_template(
&mut self, &mut self,
request: RegisterTypstTemplateRequest, request: RegisterDocumentTemplateRequest,
) -> Result<RegisterTypstTemplateResponse> { ) -> Result<RegisterDocumentTemplateResponse> {
let request = self.authenticated_request(request)?; let request = self.authenticated_request(request)?;
let response = self let response = self
.document_data_client .document_data_client
.register_typst_template(request) .register_document_template(request)
.await .await
.context("gRPC RegisterTypstTemplate call failed")?; .context("gRPC RegisterDocumentTemplate call failed")?;
Ok(response.into_inner()) Ok(response.into_inner())
} }
@@ -1186,16 +1189,46 @@ impl GrpcClient {
Ok(response.into_inner()) Ok(response.into_inner())
} }
pub async fn get_typst_template_version( pub async fn get_document_template_version(
&mut self, &mut self,
request: GetTypstTemplateVersionRequest, request: GetDocumentTemplateVersionRequest,
) -> Result<GetTypstTemplateVersionResponse> { ) -> Result<GetDocumentTemplateVersionResponse> {
let request = self.authenticated_request(request)?; let request = self.authenticated_request(request)?;
let response = self let response = self
.document_data_client .document_data_client
.get_typst_template_version(request) .get_document_template_version(request)
.await .await
.context("gRPC GetTypstTemplateVersion call failed")?; .context("gRPC GetDocumentTemplateVersion call failed")?;
Ok(response.into_inner())
}
pub async fn render_text_document(
&mut self,
request: common::proto::komp_ac::document_data::RenderTextDocumentRequest,
) -> Result<common::proto::komp_ac::document_data::RenderTextDocumentResponse> {
let request = self.authenticated_request(request)?;
let response = self.document_data_client.render_text_document(request).await
.context("gRPC render_text_document call failed")?;
Ok(response.into_inner())
}
pub async fn finalize_document(
&mut self,
request: common::proto::komp_ac::document_data::FinalizeDocumentRequest,
) -> Result<common::proto::komp_ac::document_data::FinalizeDocumentResponse> {
let request = self.authenticated_request(request)?;
let response = self.document_data_client.finalize_document(request).await
.context("gRPC finalize_document call failed")?;
Ok(response.into_inner())
}
pub async fn get_archived_document(
&mut self,
request: common::proto::komp_ac::document_data::GetArchivedDocumentRequest,
) -> Result<common::proto::komp_ac::document_data::GetArchivedDocumentResponse> {
let request = self.authenticated_request(request)?;
let response = self.document_data_client.get_archived_document(request).await
.context("gRPC get_archived_document call failed")?;
Ok(response.into_inner()) Ok(response.into_inner())
} }

View File

@@ -1,5 +1,5 @@
pub use common::typst_contract::{TypstContract, TypstContractError}; pub use common::typst_contract::{TypstContract, TypstContractError};
use common::proto::komp_ac::document_data::TypstTemplateVersion; use common::proto::komp_ac::document_data::DocumentTemplateVersion;
/// Parses the first meaningful declaration from stored Typst source for the /// Parses the first meaningful declaration from stored Typst source for the
/// admin mapping workflow. It must be the literal `komp_ac_fields` tuple; /// admin mapping workflow. It must be the literal `komp_ac_fields` tuple;
@@ -13,7 +13,7 @@ pub fn parse_contract(source: &str) -> Result<TypstContract, TypstContractError>
/// workflows should retain `version.id` separately and send it back when they /// workflows should retain `version.id` separately and send it back when they
/// submit the reviewed table mapping. /// submit the reviewed table mapping.
pub fn parse_template_version( pub fn parse_template_version(
version: &TypstTemplateVersion, version: &DocumentTemplateVersion,
) -> Result<TypstContract, TypstContractError> { ) -> Result<TypstContract, TypstContractError> {
parse_contract(&version.source_code) parse_contract(&version.source_code)
} }
@@ -21,7 +21,7 @@ pub fn parse_template_version(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{parse_contract, parse_template_version}; use super::{parse_contract, parse_template_version};
use common::proto::komp_ac::document_data::TypstTemplateVersion; use common::proto::komp_ac::document_data::DocumentTemplateVersion;
#[test] #[test]
fn exposes_typst_fields_to_client_workflows() { fn exposes_typst_fields_to_client_workflows() {
@@ -35,7 +35,7 @@ mod tests {
["invoice.number", "items[].quantity"] ["invoice.number", "items[].quantity"]
); );
let version = TypstTemplateVersion { let version = DocumentTemplateVersion {
id: 42, id: 42,
source_code: r#"#let komp_ac_fields = ("invoice.number",)"#.to_string(), source_code: r#"#let komp_ac_fields = ("invoice.number",)"#.to_string(),
..Default::default() ..Default::default()

2
server

Submodule server updated: f00542d009...7f652545a4