RFC-0011: Policy-Driven "Landing" Architecture
- Status: Implemented
- Author(s): @revant.one
- Created: 2026-04-14
Context
Standard application frameworks often hardcode user landing pages (e.g., redirecting all users to /dashboard after login). In multi-app environments like Framework M, landing needs to be dynamic, role-aware, and attribute-aware (e.g., a Supplier landing on a Portal vs. an Admin landing on a Desk). "Redirect hacks" often interfere with SPA routing and API fetches.
Proposed Architecture
1. The Landing Port (Backend)
Landing resolution is moved from imperative code (hardcoded redirects) to a declarative Protocol:
- Protocol:
LandingProtocol. - Contract:
resolve_landing(user_context: UserContext) -> LandingDescriptor.
2. Specialized Adapters
Different implementation patterns can be swapped without changing the framework's core auth flow:
| Adapter | Logic | Use Case |
|---|---|---|
| RBAC (Standard) | Role -> Route mapping | Basic internal apps. |
| ABAC (Attribute) | User.attributes -> Route | Land users based on Branch, Department, or Type. |
| ReBAC (Relation) | User -[member_of]-> Warehouse | Land users based on their relationship to a specific entity. |
3. The Resolution Hierarchy
Redirection is handled statelessly in the "Post-Auth Handshake":
- Explicit Override: If
?to=/pathis present in the URL, the framework honors it immediately (Standard Redirect respect). - Entitlement Filtering: Before resolution, the framework queries the
FeatureEntitlementProtocolto ensure the target module/route is enabled for the tenant. - User Preference: If the
Userhas apersonal_landing_pageset in their metadata (and is entitled to it), it takes priority. - Protocol Resolution: Query the
LandingProtocolfor the "Best Match" route based on active Roles/Permissions. - System Fallback: Redirect to the global default (e.g.,
/dashboard).
4. Decoupling Logic (No-Cliff)
By treating the landing page as a Data Object rather than a HTTP Header (302):
- Single-Page Applications (SPAs) can resolve landing routes without page reloads.
- Mobile apps can interpret the
LandingDescriptorto deep-link into a native screen. - Business logic for "Where should this user go?" is centralized in the active adapter, making it easily testable via TDD.
5. Progressive Decomposition (Data Sovereignty)
To adhere to progressive-decomposition.md (Part 14), the landing architecture ensures that the "Home" experience survives service isolation by moving resolution logic to the Adapter Layer:
- Resolution Autonomy (Adapters): While the
LandingProtocolis pure, its implementations can vary by deployment mode.- In Enterprise Mode, a domain-aware Adapter may resolve the landing page using Pattern A (RPC) to maintain absolute consistency.
- In Indie Mode, a simpler Adapter may use Pattern B (Projection) or local DB lookups.
- Survivability: If a primary domain Adapter (e.g., Supplier Domain) is unreachable, a fallback Middleware-Adapter can resolve a "safe" system route, preventing a total shell failure.
6. SaaS Entitlements (The Control Plane)
Landing pages are often restricted by subscription tiers (e.g., a "Premium Dashboard").
- Entitlement Check: The
LandingProtocolimplementation must verify feature enablement via the sharedFeatureEntitlementProtocol. - Downgrade Handling: If a user's
personal_landing_pageis no longer entitled (due to a subscription downgrade), the hierarchy automatically falls back to the next valid match in Step 4 or 5.
Implementation Details
- Backend: Add a
landing_protocolfield to theSystemConfig. - Entitlements: Integrate
FeatureEntitlementProtocolinto theresolve_landingservice logic. - Frontend: The
AuthHandlercomponent triggers theresolve_landingAPI call upon successful login and updates the local router state.
Unresolved Questions
- Session Management: Should the resolved landing page be cached in the session to avoid re-calculation on every refresh?
- Multiple Matches: If an ABAC adapter returns multiple valid landing pages, how does the UI present a "Choice" to the user?