Files
komp_ac/common/proto/exchange_rates.proto
2026-09-07 18:27:43 +02:00

210 lines
7.3 KiB
Protocol Buffer

syntax = "proto3";
package komp_ac.exchange_rates;
import "table_definition.proto";
import "common.proto";
// Selects WHICH DATE supplies the rate; this is independent of where the rate
// comes from. These are not four user-facing choices: UNSPECIFIED is protobuf's
// zero-value sentinel and is rejected when an explicit selection is supplied.
//
// User-facing mapping:
// - "Automatic official rate" uses PREVIOUS_PUBLICATION for an ordinary
// transaction, or ON_OR_BEFORE_DATE for a financial statement.
// - "Official rate from another date" uses SPECIFIC_PUBLICATION_DATE together
// with source OFFICIAL, a specific_rate_date, and an audit reason.
// - A saved custom rate still uses one of these rules to determine which dated
// custom-rate record applies.
enum ExchangeRateDateRule {
// Sentinel for an omitted date rule; never a selectable business option.
EXCHANGE_RATE_DATE_RULE_UNSPECIFIED = 0;
// Latest valid publication strictly before the transaction date.
EXCHANGE_RATE_DATE_RULE_PREVIOUS_PUBLICATION = 1;
// Latest valid publication on or before the financial-statement date.
EXCHANGE_RATE_DATE_RULE_ON_OR_BEFORE_DATE = 2;
// An explicitly chosen publication date. Requires specific_rate_date and an
// audit reason; an official date must be a real provider publication date.
EXCHANGE_RATE_DATE_RULE_SPECIFIC_PUBLICATION_DATE = 3;
}
// Selects WHERE THE RATE VALUE comes from; date selection is controlled by
// ExchangeRateDateRule above. These are not four user-facing choices:
// UNSPECIFIED is protobuf's zero-value sentinel and is rejected.
//
// Current user-facing mapping:
// - "Automatic official rate" and "Official rate from another date" are both
// OFFICIAL; they differ only in ExchangeRateDateRule.
// - "Saved custom rate" is SAVED_CUSTOM: a reusable row already persisted in
// the profile's custom_exchange_rates table.
// - MANUAL is the current transaction-local, one-off quote path. If the product
// supports only persisted manual rates, this value and manual_foreign_units
// should be removed and SAVED_CUSTOM should be presented as "Manual rate".
enum ExchangeRateSource {
// Sentinel for an omitted source; never a selectable business option.
EXCHANGE_RATE_SOURCE_UNSPECIFIED = 0;
// An immutable observation imported from the configured official provider.
EXCHANGE_RATE_SOURCE_OFFICIAL = 1;
// A reusable user-maintained quote stored in custom_exchange_rates.
EXCHANGE_RATE_SOURCE_SAVED_CUSTOM = 2;
// A one-off quote carried only by this request and its audit evidence.
EXCHANGE_RATE_SOURCE_MANUAL = 3;
}
message ExchangeRateSelection {
ExchangeRateDateRule date_rule = 1;
ExchangeRateSource source = 2;
optional string specific_rate_date = 3;
optional string manual_foreign_units = 4;
string reason = 5;
// Omit to use the profile's current default source for the currency.
// An explicit different source must be enabled for the same direct pair and
// is recorded as an audited per-event override.
optional string rate_source_id = 6;
}
service ExchangeRateService {
// Lists the direct-rate providers compiled into and registered by this
// server instance. Clients use these stable IDs when configuring profiles.
rpc ListRateSources(komp_ac.common.Empty)
returns (ListRateSourcesResponse);
rpc PreviewDirectConversion(PreviewDirectConversionRequest)
returns (PreviewDirectConversionResponse);
rpc ListConversionEvidence(ListConversionEvidenceRequest)
returns (ListConversionEvidenceResponse);
rpc GetProfileExchangeRateSettings(GetProfileExchangeRateSettingsRequest)
returns (ProfileExchangeRateSettings);
rpc AddProfileCurrencySource(AddProfileCurrencySourceRequest)
returns (ProfileForeignCurrency);
}
message RateSourceProvider {
string id = 1;
}
message ListRateSourcesResponse {
repeated RateSourceProvider sources = 1;
}
message PreviewDirectConversionRequest {
string original_amount = 1;
string original_currency = 2;
string conversion_basis_date = 3;
string profile_name = 4;
optional ExchangeRateSelection exchange_rate_selection = 5;
}
message PreviewDirectConversionResponse {
string original_amount = 1;
string original_currency = 2;
string converted_amount = 3;
string accounting_currency = 4;
string conversion_basis_date = 5;
string determination_method = 6;
komp_ac.table_definition.MoneyRounding rounding_method = 7;
optional string rate_date = 8;
optional string accounting_units = 9;
optional string foreign_currency = 10;
optional string foreign_units = 11;
string source_id = 12;
optional int64 official_observation_id = 13;
optional string observation_hash = 14;
optional string source_payload_hash = 15;
optional string rate_fetched_at = 16;
optional int64 import_batch_id = 17;
optional string source_endpoint = 18;
optional int64 custom_rate_table_definition_id = 19;
optional int64 custom_rate_record_id = 20;
optional int64 custom_rate_row_revision = 21;
optional string custom_rate_note = 22;
ExchangeRateDateRule applied_date_rule = 23;
ExchangeRateSource applied_source = 24;
string selection_reason = 25;
string module_id = 26;
string provider_evidence_json = 27;
}
message ListConversionEvidenceRequest {
string profile_name = 1;
string table_name = 2;
int64 record_id = 3;
string column_name = 4;
int32 limit = 5;
optional int64 before_evidence_id = 6;
}
message ConversionEvidence {
int64 evidence_id = 1;
int64 row_revision = 2;
string original_amount = 3;
string original_currency = 4;
string converted_amount = 5;
string accounting_currency = 6;
string accounting_units = 7;
string foreign_currency = 8;
string foreign_units = 9;
string conversion_context = 10;
string conversion_basis_date = 11;
string determination_method = 12;
komp_ac.table_definition.MoneyRounding rounding_method = 13;
optional string rate_date = 14;
string source_id = 15;
optional int64 official_observation_id = 16;
optional string observation_hash = 17;
optional string source_payload_hash = 18;
optional string rate_fetched_at = 19;
optional int64 import_batch_id = 20;
optional string source_endpoint = 21;
string evidence_created_at = 22;
optional int64 custom_rate_table_definition_id = 23;
optional int64 custom_rate_record_id = 24;
optional int64 custom_rate_row_revision = 25;
optional string custom_rate_note = 26;
string selection_reason = 27;
optional string selected_by_user_id = 28;
string module_id = 29;
string provider_evidence_json = 30;
}
message ListConversionEvidenceResponse {
bool has_exchange = 1;
repeated ConversionEvidence evidence = 2;
bool has_more = 3;
}
message GetProfileExchangeRateSettingsRequest { string profile_name = 1; }
message ProfileForeignCurrency {
string currency = 1;
string default_source_id = 2;
repeated ProfileCurrencySource sources = 3;
}
message ProfileCurrencySource {
string source_id = 1;
bool coverage_complete = 2;
optional string verified_from_date = 3;
optional string verified_through_date = 4;
}
message ProfileExchangeRateSettings {
string profile_name = 1;
string accounting_currency = 2;
repeated string enabled_source_ids = 3;
repeated ProfileForeignCurrency foreign_currencies = 4;
}
message AddProfileCurrencySourceRequest {
string profile_name = 1;
string currency = 2;
string source_id = 3;
bool make_default = 4;
}