Skip to content

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/2 before 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.