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 TransportChain is one consignment from consignor to consignee, broken into ordered TransportChainElement (TCE) hops. The consignment’s payload is described once at the chain level as one or more FreightItem rows — quantified material allocated to the chain and carried unchanged through every TCE. Each TCE then references a TransportOperation, the activity definition that pairs an Emitter (vehicle, machine) with an EnergyCarrier (fuel) and an activity type, so the same operation can be reused across many chains.

  • Treatments. A Treatment is 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). A TreatmentOperation is an instance of that recipe with concrete input and output lines.

  • Emission intensities. An EmissionIntensity is 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 EmissionBookingRecord is an immutable journal entry of calculated emissions, broken down by LifecycleCategory (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, fluent TransportChain builders, product carbon footprint (PCF) roll-ups, document generators for reports, per-tenant tonnage accounting for subscription billing, vehicle heuristics, and visitor implementations driven by TransportChain.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-filter FilterSets, and custom widgets that surface the models in the web UI.

  • api — DRF router and viewsets mounted under api/ 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 from catalog, 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 — Django AppConfig that contributes the Emissions settings-menu category (Emitters, Transport Defaults, Lifecycle Categories, Energy Carriers) and hooks the emiflow updater into the ferrobase_update management command.

  • urls — URL configuration under the emiflow namespace, 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 businesscentral targets 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 in BusinessCentralSettings.

  • 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 tegos and 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 atop bc-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 Organization is a customer; it owns one or more Tenant workspaces. 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. User extends Django’s AbstractUser and is backed by ZITADEL for authentication. APIToken covers machine access. One-time flows like password reset and account activation are issued as access-key documents (PasswordResetRequest, AccountActivationRequest) built on AccessKeyMixin.

  • Subscriptions and feature gating. A SubscriptionPlan pairs an organisation with the set of AppFeatures it has licensed; FeatureAssignment binds 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 StoredFile lives inside a Directory with optional FileAccessGrant rows 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 the IDSequence / IdSequenceConfig pair 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 with dependency_injector) is initialised in FerrobaseConfig.ready, wired into the cheapyq task queue and selected services, and parameterised through the FERROBASE_CONTAINER settings block.

  • The shared HTTPX client is managed by context as an ASGI lifespan manager so every outbound HTTP call — most prominently the ZITADEL adapter — reuses a single connection pool.

  • The frontend update channel. FrontendUIUpdater serialises Element / UpdateSpec trees and broadcasts them over a Django Channels group, so server-side state changes repaint UI fragments live without a full page reload.

  • Generic CRUD. generic defines the platform’s gold-standard class-based views — CreateView, UpdateView, DeleteView, ListView, FilterView, TableView — paired with model_crud_routes to mint URL patterns from them. Other apps build their CRUD on top, not on raw Django.

  • Menu registration. SettingsMenuRegistry collects MenuItem contributions from every installed app’s AppConfig so 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 family AccessKey, 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), plus decimal, fields, units, and builtin.

  • 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 plus TenantRouter), cache, language, asgi, and appmeta.

  • tenant — the active-tenant ContextVar, 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, including ferrobase_update, the umbrella updater other apps hook into.

Top-level modules cover cross-cutting concerns:

  • apps — Django AppConfig that builds the DI container, registers the HTTPX lifespan manager, and exposes the AppMeta, MenuItem, and SettingsMenuRegistry extension types other apps use.

  • containersdependency_injector Container wiring.

  • 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-filter FilterSet definitions 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. zitadel wraps 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’s User records.

  • PostgreSQL multi-tenancy. Tenant provisioning in tenant_mgm creates one PostgreSQL role and database per tenant and runs migrations and fixtures against it; TenantRouter dispatches 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.

Auxiliary applications

befundung

dataimport

ferromaps

reporting