Skip to content

04 Architecture

Source page: 04-architecture.html

4. Architecture summary (v1)

   ACQUISITION                    PLATFORM                       ACTIVATION
   County/recorder ──┐   ┌─────────────────────────────┐  ┌──► Mail house API
   Permit portals ───┼──►│   Phoenix (Elixir umbrella)  │  ├──► Ad audiences
   NOAA storm data ──┤   │  GraphQL │ REST │ Channels   │  ├──► Email drips
   Enrichment APIs ◄─┤   │ ┌───────┐ ┌────────┐ ┌─────┐ │  └──► Canvass lists
   (segment-gated)   │   │ │ CRM & │ │ Autom. │ │ AI* │ │
                     │   │ │ sales │ │ engine │ │layer│ │   CRM VALVE
   Website snippet   │   │ └───────┘ │(ObanPro)│ └─────┘ │   engagement-triggered
     │               │   │ ┌────────────────────────┐   │   promotion + outcome
     ▼               │   │ │ Prospect data engine   │   │◄──► sync (built-in CRM
   RudderStack +   ─┼──►│ │ ingest·hygiene·segment │   │    or external, e.g.
   PostHog (self-  │
     hosted heatmaps) │   │ └────────────────────────┘   │    JobNimbus API)
                     │   │  PubSub · ETS/Cachex         │
                     │   └───────────┬──────────────────┘
                     │               │
                     │  ┌────────────▼─────────────────┐   ┌────────────┐
                     └─►│ PostgreSQL + TimescaleDB      │   │ S3 / CDN   │
                        │ + PostGIS                     │   │ OpenSearch │
                        │ · CRM system of record        │   └────────────┘
                        │ · prospect warehouse (schema- │
                        │   isolated; parcels, storms,  │
                        │   lineage, suppression)       │
                        │ · event log (transactional)   │
                        │ · Oban queues · pgvector      │
                        │ · analytics + cont. aggregates│
                        └───────────────────────────────┘
   Webhooks (Twilio, Stripe, suppliers, measurements) ──► Phoenix
   Deferred by trigger: Kafka/Redpanda · ClickHouse
   *AI layer = local purpose-tuned LLM served by vLLM (GPU pool) + pgvector
  • Umbrella application, modular by OTP app — Core CRM, Automation Engine, AI Layer share one deployment initially, splittable later without rewrites.
  • Automation engine isolated by process — workflow executions run under their own supervision tree so runaway automations never degrade API latency.
  • All state changes write to the event log in the same transaction — automations, audit, and projections consume one log via cursors and never disagree; the tracking firehose is kept on a separate RudderStack path.
  • One Absinthe schema is the API source of truth — mobile, web islands, and public GraphQL share it; the REST facade delegates to the same contexts.
  • The React/LiveView boundary is explicit and permanent — LiveView owns CRUD-and-collaboration surfaces; React owns the two canvas-style editors.
  • The prospect warehouse sits upstream of the CRM behind a one-way valve — raw records never enter the CRM; engagement promotes, outcomes flow back, and field-level lineage makes provider retention/purge and attribution enforceable.