--- title: Compose country-specific summaries from existing country data contracts date: 2026-07-14 category: design-patterns module: Country Intel problem_type: design_pattern component: frontend_stimulus severity: medium applies_when: - A country needs a bespoke overview without changing generic country pages - Existing domain clients already expose the needed data and attribution tags: [country-intel, china, source-attribution, progressive-loading] --- # Compose country-specific summaries from existing country data contracts ## Context A country deep dive can need a domain-specific overview that does not fit the generic economic rows. The durable pattern is to compose that overview from the country page's existing data contracts, rather than creating a parallel aggregate endpoint or silently re-fetching the same sources. This was applied to the China overview opened in [Issue #5277](https://github.com/koala73/worldmonitor/issues/5277) and is pending in [PR #5297](https://github.com/koala73/worldmonitor/pull/5297) at documentation time. ## Guidance Create a small, UI-owned view model with one group per required domain. `ChinaCountrySummaryGroup` gives every group an explicit state (`loading`, `available`, `partial`, `stale`, or `unavailable`) and holds its source-attributed signals in `src/components/CountryBriefPanel.ts`. Keep the state calculation with the orchestration code so the panel only renders the model it receives. ```ts function chinaSummaryState(signals, expectedSignals) { if (signals.length === 0) return 'unavailable'; if (signals.every((signal) => signal.stale)) return 'stale'; return signals.length < expectedSignals || signals.some((signal) => signal.stale) ? 'partial' : 'available'; } ``` In `src/app/country-intel.ts`, reuse the existing IMF and stock promises, then compose the dedicated groups from the already established China macro, BIS credit, shipping, sector-exposure, energy, aviation, and hazard paths. Every displayed signal keeps its source and preserves an observation or retrieval time only when its contract supplies one; the card must not fabricate one from the brief-open time or turn a freshness timestamp into a health claim. Guard asynchronous updates with both the request token and the current country code before rendering. `CountryIntelManager` only publishes China groups while the same request is current and the active panel still represents `CN`; `CountryDeepDivePanel.updateChinaCountrySummary` applies the same code check. This prevents a late China request from populating a country selected afterward. Do not bypass existing access boundaries for a richer country card. `fetchMultiSectorExposure` relies on `fetchCountryChokepointIndex`, which returns an empty result without premium access. Treat the absent optional signal as `partial` or `unavailable`, while retaining public data such as shipping rates where it is already public. Render source text with DOM text nodes, per-group polite status regions, and a responsive single-column layout. The regression test in `tests/china-country-summary.test.mts` exercises all five groups, stale and partial states, a country change, lower-case country codes, and an attribution string that resembles markup. ## Why This Matters Reusing established contracts keeps source-specific normalization, entitlement rules, cached hydration, and failure handling in one place. The explicit view model also makes degraded states visible instead of presenting a mix of late, stale, and unavailable values as a complete summary. ## When to Apply - A single country needs a clear, domain-oriented overview alongside the unchanged generic page. - The required facts already have maintained clients, hydration, or RPC contracts. - The source set can be incomplete, stale, gated, or arrive after a user changes country. ## Examples For China, the card contains five independently rendered groups: macro and policy, market and credit, trade and supply chain, energy, and availability. A group may render a partial result when one of its underlying public sources is absent, while a premium-gated trade detail remains absent for anonymous users. The generic page receives no China-specific card for another country. ## Related - [Reject degraded China macro snapshots at the seed publish boundary](../logic-errors/reject-degraded-china-macro-seed-publication.md) - [Issue #5277](https://github.com/koala73/worldmonitor/issues/5277)