Skip to content

State Management & Multi-Tenancy

State Management & Multi-Tenancy

PLANOVI is designed as a multi-tenant enterprise architecture. A single authenticated user can belong to multiple workspaces, such as private commercial companies (company) and democratic energy cooperatives (cooperative).


State Management Architecture

The application uses Flutter’s provider package. The state hierarchy is structured into three distinct scopes:

graph TD
    App[MaterialApp Root] --> GlobalScope[1. Global Root Providers]
    GlobalScope --> AuthP[AuthProvider]
    GlobalScope --> ThemeP[ThemeProvider]
    GlobalScope --> MaintP[MaintenanceProvider]
    
    GlobalScope --> TenantScope["2. Tenant & Session Context"]
    TenantScope --> TenantSession[TenantSessionProvider]
    TenantScope --> WorkspaceContext[WorkspaceContextProvider]
    TenantScope --> RbacContext[RbacContextProvider]

    TenantScope --> FeatureScope[3. Feature Providers]
    FeatureScope --> EnergyP["EnergyCoopProvider & TelemetryProvider"]
    FeatureScope --> DeviceP[DeviceControlProvider]
    FeatureScope --> GovP[GovernanceProvider]
    FeatureScope --> JarvisP[JarvisChatProvider]
    FeatureScope --> WorkOrderP[WorkOrderProvider]

Multi-Tenancy Models

Workspace Types

Workspaces are categorized using the WorkspaceType enum:

  • company: Standard commercial workspace (CRM, Dealflow, Team calendars, Business documents).
  • cooperative: Energy cooperative workspace (Solar farms, Battery storage, Democratic voting, Member ledger, Field technician queue).
enum WorkspaceType {
company,
cooperative,
}

Tenant Roles & Permissions

Within a tenant session, users are assigned a TenantRole:

RoleDescriptionKey Capabilities
ownerCooperative or Company founderFull system control, billing, member approval, voting resolutions.
adminOperational administratorMember management, knowledge base editing, scheduling configs.
technicianField / Maintenance technicianDevice control, telemetry monitoring, technician queue work orders.
auditorCompliance & financial oversightFinancial ledger audits, governance declaration oversight, read-only balance.
memberCooperative member / CitizenEnergy consumption view, personal wallet balance, voting in governance polls.
viewerRead-only visitorRead-only dashboard access with no mutation capabilities.

Airlock & Session Health

The TenantSessionProvider implements a resilience state machine called Airlock (AirlockStatus):

  • healthy: Active real-time WebSocket connection to Supabase and valid JWT.
  • syncing: Background reconciliation or workspace context switch in progress.
  • degraded: Network connectivity drops; reads are serviced from cached SharedPreferences where possible.
  • offline: No internet connectivity; mutations are queued or rejected safely with user-facing alerts.

Tenant Switching Lifecycle

When a user switches between workspaces, the application guarantees data isolation by flushing feature caches:

sequenceDiagram
    actor User
    participant Shell as "Navigation / Topbar"
    participant TSP as TenantSessionProvider
    participant RBAC as RbacContextProvider
    participant Cache as "Local State / Feature Providers"

    User->>Shell: Selects new Workspace
    Shell->>TSP: switchWorkspace(newWorkspaceId, workspaceType)
    TSP->>TSP: Set status = AirlockStatus.syncing
    TSP->>Cache: Clear active feature state (telemetry, chat, ledgers)
    TSP->>RBAC: resolvePermissionsForCompany(newCompanyId)
    RBAC->>RBAC: Load role & granted permission keys
    TSP->>TSP: Persist last active workspace in SharedPreferences
    TSP->>TSP: Set status = AirlockStatus.healthy
    TSP->>Shell: notifyListeners() -> UI updates navigation & available menus