app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit 47d7a18d4a424f2a090c59aa19c527b2ed7b6300
parent ff95654e0167622a823df215b42269f9ff26c7f1
Author: triesap <tyson@radroots.org>
Date:   Fri,  3 Jul 2026 07:44:53 +0000

runtime: rename fallback projection terms

- rename farm-rules derived profile inputs to seed terminology
- remove fallback wording from locale and account display tests
- add fallback to production and schema retired-term guards
- validate studio format, source guards, and desktop check through extbuild

Diffstat:
Mcrates/desktop/src/runtime.rs | 41+++++++++++++++++++----------------------
Mcrates/desktop/src/source_guards.rs | 11+++++++++++
Mcrates/desktop/src/window.rs | 4++--
Mcrates/i18n/src/lib.rs | 4++--
Mcrates/store/src/interop.rs | 2+-
5 files changed, 35 insertions(+), 27 deletions(-)

diff --git a/crates/desktop/src/runtime.rs b/crates/desktop/src/runtime.rs @@ -3602,13 +3602,11 @@ impl DesktopAppRuntimeState { let farm_id = self .selected_farm_id() .ok_or(DesktopAppRuntimeFarmRulesError::FarmRequired)?; - let fallback_profile = self.fallback_farm_profile(farm_id); + let seed_profile = self.seed_farm_profile(farm_id); let projection = self .sqlite_store_for_farm_rules()? .load_farm_rules(farm_id) - .map(|projection| { - prepare_loaded_farm_rules_projection(projection, &fallback_profile) - })?; + .map(|projection| prepare_loaded_farm_rules_projection(projection, &seed_profile))?; Ok(projection) } @@ -3621,14 +3619,14 @@ impl DesktopAppRuntimeState { let farm_id = self .selected_farm_id() .ok_or(DesktopAppRuntimeFarmRulesError::FarmRequired)?; - let fallback_profile = self.fallback_farm_profile(farm_id); - let normalized = normalize_farm_rules_projection(projection, &fallback_profile); + let seed_profile = self.seed_farm_profile(farm_id); + let normalized = normalize_farm_rules_projection(projection, &seed_profile); let saved_projection = { let sqlite_store = self.sqlite_store_for_farm_rules()?; sqlite_store.save_farm_rules(&normalized)?; let mut refreshed = sqlite_store.load_farm_rules(farm_id)?; - refreshed = prepare_loaded_farm_rules_projection(refreshed, &fallback_profile); + refreshed = prepare_loaded_farm_rules_projection(refreshed, &seed_profile); let saved_farm = FarmSummary { farm_id, @@ -5413,8 +5411,8 @@ impl DesktopAppRuntimeState { state } - fn fallback_farm_profile(&self, farm_id: FarmId) -> FarmProfileRecord { - fallback_farm_profile_for_projection(farm_id, self.state_store.farm_setup_projection()) + fn seed_farm_profile(&self, farm_id: FarmId) -> FarmProfileRecord { + seed_farm_profile_for_projection(farm_id, self.state_store.farm_setup_projection()) } fn load_products_list_for_query( @@ -8384,11 +8382,10 @@ fn load_selected_account_context_with_options( product_editor_draft, ) = match today_farm_id { Some(farm_id) => { - let fallback_profile = - fallback_farm_profile_for_projection(farm_id, &farm_setup_projection); + let seed_profile = seed_farm_profile_for_projection(farm_id, &farm_setup_projection); let farm_rules_projection = sqlite_store.load_farm_rules(farm_id).map(|projection| { - prepare_loaded_farm_rules_projection(projection, &fallback_profile) + prepare_loaded_farm_rules_projection(projection, &seed_profile) })?; let today_projection = sqlite_store.load_today_agenda(Some(farm_id))?; let products_query = continuity_state.seller.products_query.clone(); @@ -9210,7 +9207,7 @@ fn selected_farm_id_from_context( }) } -fn fallback_farm_profile_for_projection( +fn seed_farm_profile_for_projection( farm_id: FarmId, farm_setup_projection: &FarmSetupProjection, ) -> FarmProfileRecord { @@ -9234,10 +9231,10 @@ fn fallback_farm_profile_for_projection( fn prepare_loaded_farm_rules_projection( mut projection: FarmRulesProjection, - fallback_profile: &FarmProfileRecord, + seed_profile: &FarmProfileRecord, ) -> FarmRulesProjection { if projection.farm_profile.is_none() { - projection.farm_profile = Some(fallback_profile.clone()); + projection.farm_profile = Some(seed_profile.clone()); } normalize_pickup_location_defaults(&mut projection.pickup_locations); @@ -9247,20 +9244,20 @@ fn prepare_loaded_farm_rules_projection( fn normalize_farm_rules_projection( mut projection: FarmRulesProjection, - fallback_profile: &FarmProfileRecord, + seed_profile: &FarmProfileRecord, ) -> FarmRulesProjection { let mut farm_profile = projection .farm_profile .take() - .unwrap_or_else(|| fallback_profile.clone()); - farm_profile.farm_id = fallback_profile.farm_id; + .unwrap_or_else(|| seed_profile.clone()); + farm_profile.farm_id = seed_profile.farm_id; farm_profile.display_name = farm_profile.display_name.trim().to_owned(); farm_profile.timezone = farm_profile.timezone.trim().to_owned(); farm_profile.currency_code = farm_profile.currency_code.trim().to_uppercase(); projection.farm_profile = Some(farm_profile); for pickup_location in &mut projection.pickup_locations { - pickup_location.farm_id = fallback_profile.farm_id; + pickup_location.farm_id = seed_profile.farm_id; pickup_location.label = pickup_location.label.trim().to_owned(); pickup_location.address_line = pickup_location.address_line.trim().to_owned(); pickup_location.directions = pickup_location @@ -9271,12 +9268,12 @@ fn normalize_farm_rules_projection( } if let Some(operating_rules) = projection.operating_rules.as_mut() { - operating_rules.farm_id = fallback_profile.farm_id; + operating_rules.farm_id = seed_profile.farm_id; operating_rules.substitution_policy = operating_rules.substitution_policy.trim().to_owned(); } for fulfillment_window in &mut projection.fulfillment_windows { - fulfillment_window.farm_id = fallback_profile.farm_id; + fulfillment_window.farm_id = seed_profile.farm_id; fulfillment_window.label = fulfillment_window.label.trim().to_owned(); fulfillment_window.starts_at = fulfillment_window.starts_at.trim().to_owned(); fulfillment_window.ends_at = fulfillment_window.ends_at.trim().to_owned(); @@ -9284,7 +9281,7 @@ fn normalize_farm_rules_projection( } for blackout_period in &mut projection.blackout_periods { - blackout_period.farm_id = fallback_profile.farm_id; + blackout_period.farm_id = seed_profile.farm_id; blackout_period.label = blackout_period.label.trim().to_owned(); blackout_period.starts_at = blackout_period.starts_at.trim().to_owned(); blackout_period.ends_at = blackout_period.ends_at.trim().to_owned(); diff --git a/crates/desktop/src/source_guards.rs b/crates/desktop/src/source_guards.rs @@ -1274,6 +1274,10 @@ const STRICT_SDK_BOUNDARY_FORBIDDEN_PATTERNS: &[SdkBoundaryForbiddenPattern] = & reason: "app production sources must not keep retired SDK audit scaffolding", }, SdkBoundaryForbiddenPattern { + pattern: "fallback", + reason: "app production sources must use explicit default or seed terminology", + }, + SdkBoundaryForbiddenPattern { pattern: "ORDER_SUBMIT_OPERATION_KIND", reason: "app production sources must use trade workflow operation kinds", }, @@ -1594,6 +1598,7 @@ const APP_STORE_RETIRED_SCHEMA_TERMS: &[&str] = &[ "compat", "shim", "deprecated", + "fallback", "dual_read", "dual_write", "dual-read", @@ -1635,6 +1640,12 @@ fn strict_sdk_boundary_scanner_rejects_unexcepted_new_production_paths() { .iter() .any(|finding| finding.pattern == "status_client(") ); + let default_term_findings = unexcepted_sdk_boundary_patterns( + "crates/desktop/src/runtime.rs", + "fn project() { let fallback_profile = profile; }", + ); + assert_eq!(default_term_findings.len(), 1); + assert_eq!(default_term_findings[0].pattern, "fallback"); assert!( unexcepted_sdk_boundary_patterns( "crates/desktop/src/accounts.rs", diff --git a/crates/desktop/src/window.rs b/crates/desktop/src/window.rs @@ -16634,7 +16634,7 @@ mod tests { } #[test] - fn settings_account_display_uses_label_before_npub_fallback() { + fn settings_account_display_uses_label_before_npub_default() { let labeled = AccountSummary { account_id: "account_1".to_owned(), npub: "npub1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq".to_owned(), @@ -16651,7 +16651,7 @@ mod tests { } #[test] - fn settings_account_npub_fallback_stays_compact() { + fn settings_account_npub_default_stays_compact() { assert_eq!( abbreviated_npub("npub1sxczrq2dp4jtehcm8mtemj975u5ytf2d7mc6dpuuq3rzkjzr76ls5lkheq"), "npub1sxczr...5lkheq" diff --git a/crates/i18n/src/lib.rs b/crates/i18n/src/lib.rs @@ -52,8 +52,8 @@ fn normalize_host_locale(host_locale: &str) -> String { return DEFAULT_LOCALE_ID.to_owned(); } - let without_fallbacks = trimmed.split(':').next().unwrap_or(DEFAULT_LOCALE_ID); - let without_encoding = without_fallbacks + let primary_locale_segment = trimmed.split(':').next().unwrap_or(DEFAULT_LOCALE_ID); + let without_encoding = primary_locale_segment .split('.') .next() .unwrap_or(DEFAULT_LOCALE_ID) diff --git a/crates/store/src/interop.rs b/crates/store/src/interop.rs @@ -8800,7 +8800,7 @@ mod tests { } #[test] - fn app_authored_records_with_non_uuid_tags_do_not_fallback_to_cli_identity() { + fn app_authored_records_with_non_uuid_tags_do_not_rebind_to_cli_identity() { let app_store = AppSqliteStore::open(DatabaseTarget::InMemory).expect("open app sqlite store"); let events = local_events_store();