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:
| Role | Description | Key Capabilities |
|---|---|---|
owner | Cooperative or Company founder | Full system control, billing, member approval, voting resolutions. |
admin | Operational administrator | Member management, knowledge base editing, scheduling configs. |
technician | Field / Maintenance technician | Device control, telemetry monitoring, technician queue work orders. |
auditor | Compliance & financial oversight | Financial ledger audits, governance declaration oversight, read-only balance. |
member | Cooperative member / Citizen | Energy consumption view, personal wallet balance, voting in governance polls. |
viewer | Read-only visitor | Read-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