Concepts¶
These pages explain the ideas that cut across the MSFLib modules. Read them once and the module pages become easier to follow, because every module builds on the same few primitives.
| Concept | What it answers | Lives in |
|---|---|---|
| Tiered configuration | How does one setting get a different value per tenant, workspace or user? | msflib.core.config, msflib-workspace-config |
| Policy | How do I resolve structured settings across tiers, and explain which tier won? | msflib.policy |
| Scopes, tenancy and workspaces | Who is the caller acting for, and how does that identity reach queries and keys? | msflib.scope, msflib-tenancy |
| Event bus | How do modules react to each other without importing each other? | msflib.eventbus |
| Dependency injection | How are request-scoped dependencies wired into your app? | deps.py in each module |
| Seeding | How do I load initial or demo data from a YAML file? | msflib.seed |
How they fit together¶
A request arrives and your host app resolves the caller through the dependencies returned by the module deps.py factories (dependency injection). Those identities become a ScopeEnvelope (scopes). Services use the scope to read rows and to resolve settings that may differ for that tenant, workspace or user (tiered configuration, policy). When something notable happens, such as an account being created, the action emits an event and other modules react (event bus). On a fresh database, the seeder loads the first rows.
None of this is mandatory. A single-tenant app with no workspaces can use ModuleSettingsBase and the event bus and ignore the rest.