Apps Overview¶
This page is the high-level map of the platform’s applications. For each app, its package docstring appears below; the per-app sub-page lists the app’s top-level leaf modules and subpackages, each with their own docstring. Every entry links through to the corresponding detailed API reference; class-level documentation lives there, not here.
Primary applications¶
emiflow¶
Emiflow — the emission calculation and reporting engine of the platform.
Emiflow turns business activity — freight movements, energy use, waste treatment — into auditable greenhouse-gas figures (gCO2e per tkm for transports, gCO2e per t for treatments), persists those figures in an append-only booking journal, and renders them as compliance-ready documents. It is the application that justifies the platform’s existence: emissions are not estimated here, they are accounted for.
Domain overview¶
The emiflow domain is built around four interlocking concepts:
Transport chains. A
TransportChainis one consignment from consignor to consignee, broken into orderedTransportChainElement(TCE) hops. The consignment’s payload is described once at the chain level as one or moreFreightItemrows — quantified material allocated to the chain and carried unchanged through every TCE. Each TCE then references aTransportOperation, the activity definition that pairs anEmitter(vehicle, machine) with anEnergyCarrier(fuel) and an activity type, so the same operation can be reused across many chains.Treatments. A
Treatmentis a recipe: which materials go in, which come out, which emitter and energy carrier are involved, and how the resulting emissions are allocated to the outputs (by weight or manually). ATreatmentOperationis an instance of that recipe with concrete input and output lines.Emission intensities. An
EmissionIntensityis the calculated per-activity factor (gCO2e per tkm or gCO2e per t) for a transport operation, treatment operation, or emitter. The intensity carries every input variable it was computed from, so results stay reproducible and audit-traceable.Booking records. An
EmissionBookingRecordis an immutable journal entry of calculated emissions, broken down byLifecycleCategory(LCC). The LCC split lets reports present well-to-tank, tank-to-wheel, and well-to-wheel figures side by side without recomputation.
Upstream reference data is published as EmissionsCatalog
bundles (for example the public GLEC extract) and per-tenant catalogs
can override or extend the shipped factors. Per-tenant configuration
lives in a singleton Settings row and the related
TransportChainDefaults and BusinessCentralSettings
records.
Package layout¶
Emiflow follows the platform-wide fat services / thin views convention. The major subpackages are:
models— ORM models grouped one module per bounded sub-domain (booking, catalog, dataimport, intensity, operation, reporting, settings, signals, tegos, transport, treatment).services— business logic: transport-chain and treatment emission calculators, fluentTransportChainbuilders, product carbon footprint (PCF) roll-ups, document generators for reports, per-tenant tonnage accounting for subscription billing, vehicle heuristics, and visitor implementations driven byTransportChain.accept.views— Django class-based views exposing the per-domain CRUD bundles and ad-hoc workflows (file import, treatment-operation allocation, reporting, settings).forms,tables,filter,widgets— Django forms, django-tables2 tables, django-filterFilterSets, and custom widgets that surface the models in the web UI.api— DRF router and viewsets mounted underapi/for machine consumers.dataimport— staging-to-final pipeline that turns rows from bulk spreadsheet imports into real transport chains.catalog— ingest utilities for third-party emission catalog files (distinct fromcatalog, which holds the resulting ORM models).templatetags— Jinja2 template tags used by the emiflow UI templates.management— Django management commands.
Top-level modules cover cross-cutting concerns:
apps— DjangoAppConfigthat contributes the Emissions settings-menu category (Emitters, Transport Defaults, Lifecycle Categories, Energy Carriers) and hooks the emiflow updater into theferrobase_updatemanagement command.urls— URL configuration under theemiflownamespace, registering the dashboard, the per-domain CRUD bundles, the ad-hoc workflow endpoints, and the REST API.metrics— Prometheus metrics for per-tenant tonnage usage and per-organisation tonnage limits, used by subscription billing and overage alerting.
External integrations¶
Emiflow integrates with Microsoft Dynamics 365 Business Central through two distinct apps hosted on that platform:
Built-in emissions app. The connector in
businesscentraltargets the emissions module that ships with Business Central itself, syncing master data with the Microsoft-provided app (through RAPIDSTART files). Per-tenant connection details live inBusinessCentralSettings.TEGOS app. TEGOS is a waste-management extension app for Business Central. Order documents originating in TEGOS are parsed into the in-memory value objects defined in
tegosand converted into transport chains and freight items.
Actually, the apps are not directly targeted, but require Ferrosoft apps acting as an adapter for these apps:
bc-emiflow(needed to consume the RAPIDSTART file)bc-emiflow-for-tegos(providing TEGOS-specific stuff atopbc-emiflow)
ferrobase¶
Ferrobase — the load-bearing foundation of the Ferrosoft platform.
Ferrobase is the framework on which every other Ferrosoft application is built. It owns the multi-tenant request pipeline, the identity and access model, the subscription and feature-gating system, the file substrate, the shared reference data, the dependency-injection container, the real-time frontend update channel, and the menu / settings extension points. Other apps register against ferrobase; ferrobase imports none of them. If a Ferrosoft application is a storey of the building, ferrobase is the slab and the steel.
Domain overview¶
The ferrobase domain centres on a small set of long-lived entities that every other app links against:
Organisations and tenants. An
Organizationis a customer; it owns one or moreTenantworkspaces. Each tenant is fully isolated — its own PostgreSQL role, its own database, its own configuration — and is selected per request by the multi-tenant middleware (see below).Identity and access.
Userextends Django’sAbstractUserand is backed by ZITADEL for authentication.APITokencovers machine access. One-time flows like password reset and account activation are issued as access-key documents (PasswordResetRequest,AccountActivationRequest) built onAccessKeyMixin.Subscriptions and feature gating. A
SubscriptionPlanpairs an organisation with the set ofAppFeatures it has licensed;FeatureAssignmentbinds those features to individual tenants. Platform apps consult the assignment before exposing menu entries or routes, so the same codebase can serve customers on different tiers without branching.Files. A
StoredFilelives inside aDirectorywith optionalFileAccessGrantrows scoping visibility per user or organisation; content is delegated to a pluggable storage backend so file data never sits in the application database.Shared reference data.
Country,Language,TimeZone,Material,BusinessPartner,CompanySite,Salutation, and theIDSequence/IdSequenceConfigpair back the drop-downs, look-ups, and human-readable identifiers that every other app reuses.
Multi-tenancy¶
Tenancy is ferrobase’s defining cross-cutting concern. The active
Tenant for a request is stored in a
ContextVar defined in
context, set by
TenantMiddleware
on the way in and read by both synchronous views and asynchronous
Channels consumers without any explicit argument passing. ORM queries
are dispatched by
TenantRouter to
the matching database alias; provisioning — PostgreSQL role and
database creation, migration application, fixture loading — lives in
tenant_mgm. The result is
that downstream apps write ordinary Django code and the tenant
boundary is enforced underneath them.
Cross-cutting infrastructure¶
A handful of platform utilities turn the domain models into a running system, and stay open as extension points for other apps:
The DI container in
containers(built withdependency_injector) is initialised inFerrobaseConfig.ready, wired into the cheapyq task queue and selected services, and parameterised through theFERROBASE_CONTAINERsettings block.The shared HTTPX client is managed by
contextas an ASGI lifespan manager so every outbound HTTP call — most prominently the ZITADEL adapter — reuses a single connection pool.The frontend update channel.
FrontendUIUpdaterserialisesElement/UpdateSpectrees and broadcasts them over a Django Channels group, so server-side state changes repaint UI fragments live without a full page reload.Generic CRUD.
genericdefines the platform’s gold-standard class-based views —CreateView,UpdateView,DeleteView,ListView,FilterView,TableView— paired withmodel_crud_routesto mint URL patterns from them. Other apps build their CRUD on top, not on raw Django.Menu registration.
SettingsMenuRegistrycollectsMenuItemcontributions from every installed app’sAppConfigso the settings navigation is composed at startup rather than hard-coded.
Package layout¶
models— ORM models grouped by concern:base(UUID model and the mixin familyAccessKey,Address,Coordinates,ReadOnly),identity(organisations, tenants, users, API tokens),subscription(plans, features, assignments),file(stored files, access grants),shared(countries, languages, materials, partners, sites, ID sequences, menu items),registry(lookup-table back ends), plusdecimal,fields,units, andbuiltin.services— business logic: the ZITADEL IAM adapter, tenant provisioning, user management, onboarding, scientific unit conversion, the cheapyq task-queue glue, image CAPTCHA, password-reset email dispatch, Server-Sent Events client, static-file serving, cleanup tasks, and platform updaters.views— the generic CRUD framework plus per-domain views for users, organisations, tenants, settings, groups, materials, partners, files, API tokens, and the dashboard index.middleware— request-pipeline middleware:tenant(per-request routing plusTenantRouter),cache,language,asgi, andappmeta.tenant— the active-tenantContextVar, tenant-scoped query helpers, and the forms / tables that surface tenants in the UI.api— base DRF infrastructure (exception handlers, router, base serializers, base viewsets) that the app-level REST APIs build on.auth— role definitions used by the permission system.forms— base form mixins (copy,fields,model_forms).session— password-reset session forms and templated email dispatch.tables— reusable django-tables2 columns and base tables with platform rendering for currency, units, dates, arrays, inline edit, and summing footers.templatetags— template helpers spanning Bootstrap 5 widgets, datetime / decimal formatting, IAM checks, menu rendering, and the AJAX / HTMX loading-indicator glue.management— Django management commands, includingferrobase_update, the umbrella updater other apps hook into.
Top-level modules cover cross-cutting concerns:
apps— DjangoAppConfigthat builds the DI container, registers the HTTPX lifespan manager, and exposes theAppMeta,MenuItem, andSettingsMenuRegistryextension types other apps use.containers—dependency_injectorContainerwiring.consumers— Django Channels WebSocket consumers used by the frontend update channel.context— ASGI lifespan context manager for the shared HTTPX client.context_processors— Django template context processors.encodings— character-encoding detection and the catalogue of supported text encodings.filter— base django-filterFilterSetdefinitions reused across apps.frontend— primitives for pushing real-time UI updates over Channels.templating— utilities for rendering Django templates from raw strings.urls— root URL configuration for the ferrobase application.
External integrations¶
Ferrobase carries the platform’s interfaces to the outside world so downstream apps don’t have to:
ZITADEL. The IAM provider behind every authenticated request.
zitadelwraps the ZITADEL IAM v2 REST API for user, organisation, and project management; end users authenticate over ZITADEL’s OIDC flows and are mirrored into ferrobase’sUserrecords.PostgreSQL multi-tenancy. Tenant provisioning in
tenant_mgmcreates one PostgreSQL role and database per tenant and runs migrations and fixtures against it;TenantRouterdispatches each ORM query to the right alias at runtime.Django Channels over Redis / Valkey. The channel layer carries the frontend update broadcasts and any other WebSocket traffic served by
consumers.HTTPX. All outbound HTTP — ZITADEL, file storage backends, third-party APIs called from downstream apps — flows through the shared connection pool managed by the lifespan context manager in
context.