feat(02-06): cache Home's system/update/storage groups and guarantee wallet freshness on re-entry
Demo images / Build & push demo images (push) Failing after 2m29s

- System stats (homeStatus.refresh), update status and cloud storage usage
  are now every-entry, TTL-gated useCachedResource entries (10s/300s/30s),
  hosted in Home.vue rather than inside the homeStatus Pinia store — a
  store's own defineStore(id, setup) runs in a bare effectScope where
  onActivated() silently no-ops (same finding as 02-05's Mesh.vue)
- Wallet is the deliberate exception (T-02-13): a new home.wallet-status
  resource wraps the existing loadWeb5Status() composite fetch and
  revalidates UNCONDITIONALLY on every activation rather than TTL-gated,
  keeps the prior figure rendered throughout, and persist:false (never
  written to sessionStorage). hydrateWalletSnapshot()'s separate localStorage
  path is untouched.
- Read Web5.vue's two existing resources (web5.networking-profits,
  web5.lnd-info) and did NOT share either key: profits is an unrelated
  dataset, and lnd-info's own default persist:true (Web5.vue out of this
  plan's file scope) would leak balance data via its own independent
  refresh cycle regardless of what Home declares, and Home's wallet fetch
  is a strictly broader 7-call composite (not the same single-call dataset)
- dedup:true added to all 12 underlying rpcClient calls (Home.vue's wallet
  composite + checkUpdateStatus, homeStatus.ts's 5 status calls)
- RefreshIndicator wired next to the Home header, bound to the wallet
  resource's loadState
- The websocket wallet-push path and hydrateWalletSnapshot's pre-network
  paint are both left exactly as 02-04 placed them

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-07-30 17:38:01 -04:00
co-authored by Claude Fable 5
parent e6ed5536c9
commit 926fa60691
4 changed files with 476 additions and 34 deletions
+4 -2
View File
@@ -89,7 +89,7 @@ export const useHomeStatusStore = defineStore('homeStatus', () => {
load_avg_1?: number
load_avg_5?: number
load_avg_15?: number
}>({ method: 'system.stats' })
}>({ method: 'system.stats', dedup: true })
stats.cpuPercent = res.cpu_usage_percent
stats.memUsed = res.mem_used_bytes
stats.memTotal = res.mem_total_bytes
@@ -114,6 +114,7 @@ export const useHomeStatusStore = defineStore('homeStatus', () => {
const btc = await rpcClient.call<{ block_height: number; sync_progress: number }>({
method: 'bitcoin.getinfo',
timeout: 5000,
dedup: true,
})
stats.bitcoinSyncPercent = (btc.sync_progress ?? 0) * 100
stats.bitcoinBlockHeight = btc.block_height ?? 0
@@ -181,7 +182,7 @@ export const useHomeStatusStore = defineStore('homeStatus', () => {
key_present: boolean
anchor_connected?: boolean
authenticated_peer_count?: number
}>({ method: 'fips.status' })
}>({ method: 'fips.status', dedup: true })
fipsStatus.value = status
fipsLoadState.value = 'ready'
lastFipsRefreshAt.value = Date.now()
@@ -196,6 +197,7 @@ export const useHomeStatusStore = defineStore('homeStatus', () => {
const res = await rpcClient.call<{ tollgate: { installed: boolean; enabled?: boolean } }>({
method: 'openwrt.get-status',
timeout: 15000,
dedup: true,
})
tollgateStatus.value = { installed: res.tollgate.installed, enabled: res.tollgate.enabled ?? false }
tollgateLoadState.value = 'ready'