5. Building Blocks (C4 Level 2 + 3)¶
Finnest is a supervised modular monolith — one Elixir release containing 21 OTP applications. This section shows them at two zoom levels.
Level 2 — Containers¶
Containers are the major deployable units. For Finnest these are the processes that run on a production host, plus the external systems from §3 Context.
Interactive container browser
The static Mermaid diagram below gives the one-screen overview. For click-through drill-down with per-container pages, dependency arrows, and pan/zoom SVG, use the interactive C4 browser →.
C4Container
title Containers — Finnest (C4 Level 2)
Person(hrAdmin, "HR Administrator", "Commercial + IRAP")
Person(worker, "Worker", "Mobile-first")
Person_Ext(client, "Client", "Portal")
System_Boundary(finnest, "Finnest") {
Container(phoenixWeb, "Phoenix Web", "Elixir / Phoenix 1.8 / Bandit / LiveView", "HTTP entry, LiveView UI, Channels, sessions")
Container(obanWorkers, "Oban Workers", "Elixir / Oban 2.21", "Background jobs — payroll calc, notification fan-out, AI workflow continuation")
Container(agentSwarm, "AI Agent Swarm", "Elixir / GenServer / BEAM", "Three-tier agents — conversational, workflow, autonomous")
Container(mcpServers, "MCP Servers", "Elixir / MCP", "One per domain — typed tool publication")
ContainerDb(eventStore, "Event Store", "PostgreSQL table + triggers", "Append-only, hash-chained, 7-year retention, IRAP audit log")
Container(goProxy, "Go Edge Proxy", "Go (~500 LOC)", "IRAP ONLY — FIDO2, 15-min sessions, origin pinning, Bedrock-only egress")
Container(flutterMobile, "Flutter Mobile App", "Flutter / Dart / SQLite", "Worker + Manager + Client — four roles, offline queue")
}
SystemDb_Ext(postgres, "PostgreSQL 17", "Single cluster — relational + JSONB + pub/sub")
System_Ext(bedrock, "AWS Bedrock (Sydney)", "AI — IRAP")
System_Ext(anthropic, "Anthropic Direct", "AI — commercial")
Rel(hrAdmin, phoenixWeb, "Uses", "HTTPS")
Rel(client, phoenixWeb, "Uses", "HTTPS")
Rel(worker, flutterMobile, "Uses", "on-device")
Rel(flutterMobile, goProxy, "IRAP tenant traffic", "HTTPS")
Rel(flutterMobile, phoenixWeb, "Commercial tenant traffic", "HTTPS")
Rel(goProxy, phoenixWeb, "Forwards validated", "HTTP loopback")
Rel(phoenixWeb, mcpServers, "Invokes tools (Cmd+K, actions)")
Rel(phoenixWeb, agentSwarm, "Delegates conversational")
Rel(phoenixWeb, eventStore, "Reads projections")
Rel(agentSwarm, mcpServers, "Invokes typed tools")
Rel(agentSwarm, obanWorkers, "Enqueues long-running")
Rel(agentSwarm, bedrock, "AI invoke", "HTTPS (IRAP)")
Rel(agentSwarm, anthropic, "AI invoke", "HTTPS (commercial)")
Rel(obanWorkers, mcpServers, "Invokes typed tools")
Rel(obanWorkers, eventStore, "Emits events")
Rel(mcpServers, eventStore, "Writes events")
Rel(phoenixWeb, postgres, "Ecto", "TCP")
Rel(obanWorkers, postgres, "Jobs + Ecto", "TCP")
UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1")
| Container | Technology | Responsibility |
|---|---|---|
| Phoenix Web | Elixir / Phoenix 1.8 / LiveView / Bandit | HTTP entry, LiveView UI, Phoenix Channels, session management |
| Oban Workers | Elixir / Oban 2.21 | Background jobs — payroll calc, notification fan-out, AI workflow continuation |
| AI Agent Swarm | Elixir GenServers | Conversational / workflow / autonomous agents (see agents.md) |
| MCP Servers | Elixir | One per domain — typed tool publication |
| PostgreSQL 17 | PostgreSQL | Relational data + JSONB + event store + pub/sub (LISTEN/NOTIFY) + cache + search (tsvector) |
| Flutter Mobile | Flutter / Dart | Worker + Manager + Client companion app (see mobile.md) |
| Go Proxy | Go (~500 LOC) | IRAP deployment boundary only — WAF + session-limit enforcement |
Level 3 — Components (the 21 OTP apps by tier)¶
The 21 applications are grouped into five domain tiers plus infrastructure. Tier assignment reflects compile-time dependencies, not runtime priority.
Tier 1 — Core domains (8 apps)¶
Foundation domains. Every higher-tier app depends on some of these. Ship order in Phase 0–1. Failure of any Tier 1 app degrades the whole system.
| App | Purpose |
|---|---|
finnest_core |
Repo, correlation IDs, tenant primitives, auth supervisor |
finnest_people |
Workers, managers, clients, org / office structure |
finnest_recruit |
Applicant tracking, job ads, interview scheduling |
finnest_onboard |
Induction, document collection, credential verification kickoff |
finnest_roster |
Shift scheduling, availability, swap approvals |
finnest_timekeep |
Clock in/out, timesheets, break tracking, overtime flags |
finnest_reach |
Outbound communication — SMS, email, push, in-app |
finnest_pulse |
Dashboards, aggregations, metrics |
Tier 2 — Essential domains (4 apps)¶
Business-critical but not required for every workflow. Ship in Phases 2–3.
| App | Purpose |
|---|---|
finnest_payroll |
Award interpretation, pay calculation, ABA file export |
finnest_clients |
Client portal, timesheet approval, invoicing |
finnest_safety |
Incident reports, hazard register, toolbox talks |
finnest_assets |
Equipment, PPE, vehicle allocation with compliance gates |
Tier 3 — Growth domains (3 apps)¶
Revenue-expansion features. Ship post-GA.
| App | Purpose |
|---|---|
finnest_quotes |
Client quotes, margin calculation, win/loss tracking |
finnest_learn |
Credential lifecycle, LMS port, refresher reminders |
finnest_benefits |
Salary packaging, leave loading, discretionary benefits |
Tier 4 — Industry-specific (3 apps)¶
Enabled per org based on industry profile. Never branched in core code.
| App | Purpose |
|---|---|
finnest_compliance |
Credential verification, Fair Work checks, industry-specific rules |
finnest_fatigue |
Rest-break calculation (transport, mining) |
finnest_clearance |
Security clearances (defence, finance, government) |
Tier 5 — People Excellence (1 app)¶
| App | Purpose |
|---|---|
finnest_performance |
Reviews, goals, competency tracking, 360° feedback |
Infrastructure (2 apps)¶
| App | Purpose |
|---|---|
finnest_agents |
AI agent orchestration, BudgetGuard, tool registry, memory |
finnest_web |
Phoenix endpoint, LiveView layouts, Cmd+K command bar |
How the blocks communicate¶
- Events — the default. Tier 1 → Tier 2 → Tier 3+ propagate as events on the shared event store. Never synchronous.
- Compliance gate — the one documented synchronous cross-domain call:
Compliance.check/2before writes in five domains. Ratified in ADR-011-F. - MCP tools — every domain publishes its capabilities via MCP; agents and UI consume via the same interface.
- Pub/Sub — PostgreSQL LISTEN/NOTIFY for real-time notifications to LiveView and mobile clients.
See 8. Crosscutting Concerns for the full rules.