From 7109be803b1b8c49f6703ada6a860c50aa7cacb6 Mon Sep 17 00:00:00 2001 From: Filipriec Date: Mon, 24 Aug 2026 00:03:09 +0200 Subject: [PATCH] docs on the exchange rates proto file --- common/proto/exchange_rates.proto | 38 +++++++++++++++++++++ common/src/proto/descriptor.bin | Bin 191347 -> 193520 bytes common/src/proto/komp_ac.exchange_rates.rs | 34 ++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/common/proto/exchange_rates.proto b/common/proto/exchange_rates.proto index bd9c82d8..72ecd709 100644 --- a/common/proto/exchange_rates.proto +++ b/common/proto/exchange_rates.proto @@ -2,17 +2,55 @@ syntax = "proto3"; package komp_ac.exchange_rates; +// 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; } diff --git a/common/src/proto/descriptor.bin b/common/src/proto/descriptor.bin index 0e67ea935a6acd14d400e2feb3d940d93a0dd419..f45b2ca7ebcb90be6b4a6b959edb1b5c035afcfd 100644 GIT binary patch delta 8596 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 CX_b%w diff --git a/common/src/proto/komp_ac.exchange_rates.rs b/common/src/proto/komp_ac.exchange_rates.rs index 56ea9ddf..d3d48a46 100644 --- a/common/src/proto/komp_ac.exchange_rates.rs +++ b/common/src/proto/komp_ac.exchange_rates.rs @@ -213,12 +213,29 @@ pub struct AddProfileCurrencySourceRequest { #[prost(bool, tag = "4")] pub make_default: bool, } +/// 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. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum ExchangeRateDateRule { + /// Sentinel for an omitted date rule; never a selectable business option. Unspecified = 0, + /// Latest valid publication strictly before the transaction date. PreviousPublication = 1, + /// Latest valid publication on or before the financial-statement date. OnOrBeforeDate = 2, + /// An explicitly chosen publication date. Requires specific_rate_date and an + /// audit reason; an official date must be a real provider publication date. SpecificPublicationDate = 3, } impl ExchangeRateDateRule { @@ -251,12 +268,29 @@ impl ExchangeRateDateRule { } } } +/// 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". #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum ExchangeRateSource { + /// Sentinel for an omitted source; never a selectable business option. Unspecified = 0, + /// An immutable observation imported from the configured official provider. Official = 1, + /// A reusable user-maintained quote stored in custom_exchange_rates. SavedCustom = 2, + /// A one-off quote carried only by this request and its audit evidence. Manual = 3, } impl ExchangeRateSource {