Skip to main content

Navigation, identity, and configuration at scale

Cross-feature mechanisms need central policy but decentralized integration.

Features expose destination contracts or commands using stable IDs/serializable arguments, not their internal screen classes or domain graphs. The app shell composes the graph and owns global links, tabs and authentication gates.

sealed interface AppDestination {
data class OrderDetails(val orderId: OrderId) : AppDestination
data class SignIn(val returnTo: ReturnToken) : AppDestination
}

Validate external deep links, handle absent/on-demand features, version routes, preserve return intent and avoid leaking secrets/PII in URLs or saved arguments.

Authentication/session​

One identity platform owns token storage/refresh, account switching, logout propagation, step-up authentication and session state. Features request authorized capabilities; they do not read raw refresh tokens. Server remains authoritative. Logout is a cross-feature transaction: cancel/account-scope work, clear protected caches, revoke tokens and prevent stale UI reappearance.

Configuration​

Use a typed registry with owner/default/expiry/scope. Separate build environment, operational flag, experiment, user setting, entitlement and enterprise managed configuration. Define precedence explicitly:

server authorization > enterprise policy > account entitlement
> operational safety config > user preference > packaged default

The exact precedence is product-specific; document conflicts and offline behavior. No feature should invent its own config client/cache.

Practical mistakes​

  • ❌ feature A directly imports feature B implementation.
  • ✅ navigate through app-owned contracts and stable IDs.
  • ❌ every feature refreshes tokens independently.
  • ✅ serialize/deduplicate refresh in the identity layer.
  • ❌ one Boolean mixes entitlement, experiment and release.
  • ✅ separate decisions with distinct guarantees.