diff --git a/Cargo.lock b/Cargo.lock index f48dc70b..e5460370 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -207,7 +207,7 @@ dependencies = [ "objc2-foundation", "parking_lot", "percent-encoding", - "windows-sys 0.52.0", + "windows-sys 0.59.0", "x11rb", ] @@ -1161,7 +1161,7 @@ checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "client" -version = "0.8.46" +version = "0.8.48" dependencies = [ "anyhow", "async-trait", @@ -1282,7 +1282,7 @@ dependencies = [ [[package]] name = "common" -version = "0.8.46" +version = "0.8.48" dependencies = [ "prost", "prost-build", @@ -2571,7 +2571,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -2735,7 +2735,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4730,7 +4730,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -5906,7 +5906,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -6590,7 +6590,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -6647,7 +6647,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -6754,7 +6754,7 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "search" -version = "0.8.46" +version = "0.8.48" dependencies = [ "anyhow", "common", @@ -6942,7 +6942,7 @@ dependencies = [ [[package]] name = "server" -version = "0.8.46" +version = "0.8.48" dependencies = [ "anyhow", "bcrypt", @@ -7931,7 +7931,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -8534,7 +8534,7 @@ checksum = "e78122066b0cb818b8afd08f7ed22f7fdbc3e90815035726f0840d0d26c0747a" [[package]] name = "tui-canvas" -version = "0.8.46" +version = "0.8.48" dependencies = [ "anyhow", "arboard", @@ -8565,7 +8565,7 @@ dependencies = [ [[package]] name = "tui-canvas-validation-core" -version = "0.8.46" +version = "0.8.48" dependencies = [ "regex", "serde", @@ -8575,7 +8575,7 @@ dependencies = [ [[package]] name = "tui-pages" -version = "0.8.46" +version = "0.8.48" dependencies = [ "criterion", "crossterm", @@ -9286,7 +9286,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/README.md b/README.md index 6e1f5d06..5522e43c 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,10 @@ TUI accounting system. Client/server application with two extracted open-source libraries. +Column designers default to unconstrained exact decimals. The legacy-compatible +fixed-scale form is an explicit advanced option; see +[`docs/fixed-scale-decimal.md`](docs/fixed-scale-decimal.md). + ## Crates | Crate | What | Published | diff --git a/client b/client index fc712732..1e0b6f9e 160000 --- a/client +++ b/client @@ -1 +1 @@ -Subproject commit fc712732df6521160302fd6ace06261fd8336f53 +Subproject commit 1e0b6f9edea67aaafc99acdbec0cd55dcadb8f05 diff --git a/docs/fixed-scale-decimal.md b/docs/fixed-scale-decimal.md new file mode 100644 index 00000000..ecf03c87 --- /dev/null +++ b/docs/fixed-scale-decimal.md @@ -0,0 +1,26 @@ +# Decimal column policy + +Use the bare `numeric` column type for ordinary exact base-10 values. It stores +the value without a schema-defined decimal-place limit and is the recommended +choice for quantities, percentages, rates, ratios and measurements. Use +`money` for currency amounts; its currency and rounding policy are separate +from this document. + +`decimal(p,s)` is an advanced, opt-in compatibility type for strict external +data contracts. `p` limits the total digits and `s` limits the fractional +digits. It is hidden from the normal table-designer type list until fixed-scale +decimal is enabled for that editing session. + +Fixed scale is intentionally strict: + +- API input outside the declared precision or scale is rejected, never + silently rounded by PostgreSQL. +- A table script targeting a fixed-scale column must round explicitly before + returning its value. +- A fixed-scale type cannot be changed through the table editor after the + table contains data. +- Display precision, allowed increments, minimums and maximums are business + validation concerns; `decimal(p,s)` is not a substitute for them. + +Existing fixed-scale columns remain supported. The opt-in changes discovery, +not storage compatibility. diff --git a/server b/server index 0fd5a16b..cf752c7e 160000 --- a/server +++ b/server @@ -1 +1 @@ -Subproject commit 0fd5a16ba6ac0671daabfa5fcbf34bd24c12d80c +Subproject commit cf752c7ee96c3019573e7c2f5f54571e5c4f93fc diff --git a/web/locales/cs/main.ftl b/web/locales/cs/main.ftl index fefcdf67..3c037f1d 100644 --- a/web/locales/cs/main.ftl +++ b/web/locales/cs/main.ftl @@ -212,6 +212,15 @@ td-precision = Přesnost td-precision-hint = Celkový počet uložených číslic, alespoň 1. td-scale = Desetinná místa td-scale-hint = Číslice za desetinnou čárkou, nejvýše tolik jako přesnost. +td-fixed-decimal-access = Pokročilé číselné typy +td-fixed-decimal-disabled = Pouze doporučené typy +td-fixed-decimal-enabled = Povolit desetinné číslo s pevným měřítkem +td-fixed-decimal-access-hint = Doporučuje se přesný typ NUMERIC. Tuto možnost povolte pouze pro přísný externí datový kontrakt. +td-fixed-decimal-warning-title = Pokročilé desetinné číslo s pevným měřítkem +td-fixed-decimal-warning = Tento typ omezuje celkový počet číslic i desetinná místa. Hodnoty mimo měřítko se odmítnou, výpočty musí zaokrouhlovat explicitně a typ po vložení dat nelze změnit. +td-fixed-decimal-enable-first = Před použitím tohoto typu povolte pokročilé desetinné číslo s pevným měřítkem. +td-exact-decimal = Desetinné číslo — přesné (doporučeno) +td-fixed-decimal-type = Desetinné číslo s pevným měřítkem — pokročilé td-referenced-table = Odkazovaná tabulka td-choose-table = Vyberte tabulku td-group-global = Globální diff --git a/web/locales/en/main.ftl b/web/locales/en/main.ftl index e31c0270..4781bb54 100644 --- a/web/locales/en/main.ftl +++ b/web/locales/en/main.ftl @@ -216,6 +216,15 @@ td-precision = Precision td-precision-hint = Total digits stored, at least 1. td-scale = Scale td-scale-hint = Digits after the point, no more than the precision. +td-fixed-decimal-access = Advanced number types +td-fixed-decimal-disabled = Recommended types only +td-fixed-decimal-enabled = Enable fixed-scale decimal +td-fixed-decimal-access-hint = Exact NUMERIC is recommended. Enable this only for a strict external data contract. +td-fixed-decimal-warning-title = Advanced fixed-scale decimal +td-fixed-decimal-warning = This type limits total and fractional digits. Values outside the declared scale are refused, calculations must round explicitly, and the type cannot be changed after the table contains data. +td-fixed-decimal-enable-first = Enable advanced fixed-scale decimal before using this type. +td-exact-decimal = Decimal — exact (recommended) +td-fixed-decimal-type = Fixed-scale decimal — advanced td-referenced-table = Referenced table td-choose-table = Choose a table td-group-global = Global diff --git a/web/locales/sk/main.ftl b/web/locales/sk/main.ftl index eede2884..fed69c74 100644 --- a/web/locales/sk/main.ftl +++ b/web/locales/sk/main.ftl @@ -212,6 +212,15 @@ td-precision = Presnosť td-precision-hint = Celkový počet uložených číslic, aspoň 1. td-scale = Desatinné miesta td-scale-hint = Číslice za desatinnou čiarkou, najviac toľko ako presnosť. +td-fixed-decimal-access = Pokročilé číselné typy +td-fixed-decimal-disabled = Iba odporúčané typy +td-fixed-decimal-enabled = Povoliť desatinné číslo s pevnou mierkou +td-fixed-decimal-access-hint = Odporúča sa presný typ NUMERIC. Túto možnosť povoľte iba pre prísnu externú dátovú zmluvu. +td-fixed-decimal-warning-title = Pokročilé desatinné číslo s pevnou mierkou +td-fixed-decimal-warning = Tento typ obmedzuje celkový počet číslic aj desatinné miesta. Hodnoty mimo mierky sa odmietnu, výpočty musia zaokrúhľovať explicitne a typ sa po vložení údajov nedá zmeniť. +td-fixed-decimal-enable-first = Pred použitím tohto typu povoľte pokročilé desatinné číslo s pevnou mierkou. +td-exact-decimal = Desatinné číslo — presné (odporúčané) +td-fixed-decimal-type = Desatinné číslo s pevnou mierkou — pokročilé td-referenced-table = Odkazovaná tabuľka td-choose-table = Vyberte tabuľku td-group-global = Globálne diff --git a/web/src/pages/add_table/state.rs b/web/src/pages/add_table/state.rs index 1a286f5e..69dbde55 100644 --- a/web/src/pages/add_table/state.rs +++ b/web/src/pages/add_table/state.rs @@ -61,6 +61,8 @@ pub(crate) struct BuilderForm { #[serde(default)] pub decimal_scale_input: String, #[serde(default)] + pub fixed_decimal_input: String, + #[serde(default)] pub column_indexing_input: String, #[serde(default)] pub column_quantity_ledger_input: String, @@ -128,6 +130,7 @@ impl BuilderForm { link_table_input: self.link_table_input.clone(), decimal_precision_input: self.decimal_precision_input.clone(), decimal_scale_input: self.decimal_scale_input.clone(), + fixed_decimal_input: self.fixed_decimal_input.clone(), indexing_input: self.column_indexing_input.clone(), quantity_ledger_input: self.column_quantity_ledger_input.clone(), required_input: self.column_required_input.clone(), diff --git a/web/src/pages/add_table/ui.rs b/web/src/pages/add_table/ui.rs index bb8dea0f..459766fb 100644 --- a/web/src/pages/add_table/ui.rs +++ b/web/src/pages/add_table/ui.rs @@ -245,11 +245,18 @@ mod tests { assert!(html.contains("Every profile can use this shared table.")); } - /// Every type the server accepts has to be reachable from the picker, or - /// the web UI silently offers less than the backend does. + /// Fixed-scale decimal is the one intentionally gated type; enabling the + /// advanced control makes it reachable without removing server support. #[test] fn the_type_picker_offers_the_parameterised_and_interval_types() { - let html = render_builder(&page()); + let mut state = page(); + let html = render_builder(&state); + + assert!(!html.contains(r#"