Frontend Delivery Strategy
The Angelis platform is delivered through three distinct frontend experiences, each targeting a specific audience and interaction context.
| Experience | Channel | Audience |
|---|---|---|
| The Super App | Mobile (iOS & Android) | Workers, Supervisors, Managers |
| Worker Web | Web browser | Workers, Supervisors, Managers |
| Admincenter | Web browser | Tenant Admins, Miinsys Superadmins |
This documentation focuses on the mobile and worker web experiences. The Admincenter is a more traditional single-page application (SPA) and is documented separately.
Why Two Different Strategies?
Section titled “Why Two Different Strategies?”The mobile and web channels solve different problems, so they use different architectural approaches.
On mobile, the main challenge is that a single app must be released through app stores (Apple App Store, Google Play). Releasing an update requires a review process, which can take days. To let teams move fast without blocking each other, the app is split into isolated feature modules that can evolve independently — but they’re all packaged together into one release.
On web, browsers can load JavaScript from any URL at runtime. This means we can go further: instead of just isolating code at build time, we can deploy each domain’s frontend independently and have the browser load it on the fly. This is the microfrontend pattern.
graph LR subgraph Mobile["Mobile Strategy"] direction TB MA["Single Flutter App\n(The Super App)"] MA --> MM["Feature Modules\nbundled at build time"] end
subgraph Web["Web Strategy"] direction TB WA["Shell App\n(Main Web App)"] WA -->|loads remotely at runtime| WM["Domain MFEs\ndeployed independently"] endShared Principles
Section titled “Shared Principles”Regardless of channel, both strategies follow the same organizing principle:
- A main/shell module owns the app container and handles cross-cutting concerns: authentication, routing, theming, company selection, and feature flags.
- Domain modules are self-contained: each module owns its own pages, state, API calls, and business logic. A domain module should never reach into another domain module’s internals.
This makes the codebase easier to navigate for junior engineers — when you’re working on a domain, you stay within its folder/module and rarely need to understand the rest of the app.