Skip to content

Architecture (C4)

The Money Marche estate as a C4 model: architecture/workspace.dsl (Structurizr DSL, ADR-0016). CI validates the model with the Structurizr CLI and exports each view to Mermaid for this page (backlog B26). Elements tagged Unverified (dashed border) still need confirmation by the owning agent.

To change the model, edit architecture/workspace.dsl; to see it locally with the views, run Structurizr Lite, or the CLI export below and then mkdocs serve:

structurizr.sh export -workspace architecture/workspace.dsl -format mermaid -output docs/architecture/generated

Drawn from the model directly

These views come from tools/docs/c4_mermaid.py. CI draws the same model with the Structurizr CLI. Dashed borders: unverified.

Landscape

flowchart LR
  client(["<b>Client / visitor</b><br/><small>Person</small>"])
  atul(["<b>Atul (owner)</b><br/><small>Person</small>"])
  ajay(["<b>Ajay (devops)</b><br/><small>Person</small>"])
  amfi["<b>AMFI</b><br/><small>NAV history, scheme master, AUM, TER, pe…</small>"]
  amcs["<b>AMC websites</b><br/><small>Monthly factsheets (51 AMCs)</small>"]
  advisorkhoj["<b>AdvisorKhoj</b><br/><small>Portfolio holdings source</small>"]
  nse["<b>NSE indices</b><br/><small>Index values for benchmarks</small>"]
  estate["<b>Money Marche platform</b><br/><small>Distribution of insurance, investments a…</small>"]
  pe["<b>Portfolio Engine (PE)</b><br/><small>Portfolio construction, objective select…</small>"]
  mcrm["<b>MCRM</b><br/><small>Catalogue, CRM and product models; owns …</small>"]
  mmdep["<b>MMDEP</b><br/><small>Engineering programme: collector, harnes…</small>"]
  client -->|"Browses, enquires"| estate
  atul -->|"PROCEED, decisions (Actions)"| mmdep
  ajay -->|"Operates the server"| estate
  estate -->|"Downloads NAV history, scheme data, AUM, TER, performance"| amfi
  estate -->|"Portfolio ingestion"| advisorkhoj
  estate -->|"Index values"| nse
  estate -->|"Factsheets (planned parsers)"| amcs
  mmcronScheduler -->|"Reads job schedule"| mmcronRegistry
  mmcronScheduler -->|"Starts a run"| mmcronFetch
  mmcronFetch -->|"Downloads"| amfi
  mmcronFetch -->|"Downloads factsheets and portfolio disclosures"| amcs
  mmcronFetch -->|"Stores raw file and manifest"| mmcronRaw
  mmcronAdapters -->|"Reads raw file"| mmcronRaw
  mmcronAdapters -->|"Parsed records"| mmcronValidate
  mmcronValidate -->|"Valid records only"| mmcronPublish
  mmcronPublish -->|"Production writes (target; Atul approves enabling)"| apiIngest
  mmcronPublish -->|"Staging writes"| estate
  apiIngest -->|"Every write is checked"| apiSecurity
  apiCatalogue -->|"Reads"| apiDataAccess
  apiMfData -->|"Reads"| apiDataAccess
  apiIngest -->|"Idempotent upserts"| apiDataAccess
  apiApp -->|"Reads/writes application data"| apiDataAccess
  apiHealth -->|"DB reachability, NAV freshness"| apiDataAccess
  apiDataAccess -->|"Catalogue and application data"| estate
  pe -->|"GET /api/schemes, /api/scheme/nav, /api/index/nav"| estate
  mcrm -->|"Catalogue contracts (category, product)"| estate
  mmdep -->|"Read-only health and data checks (collector)"| estate
  classDef person fill:#08427b,color:#fff,stroke:#052e56
  classDef internal fill:#1f5e7a,color:#fff,stroke:#123a4c
  classDef external fill:#8a8a8a,color:#fff,stroke:#666
  classDef container fill:#438dd5,color:#fff,stroke:#2e6295
  classDef unverified stroke-dasharray:5 5,stroke-width:2px
  class client person
  class atul person
  class ajay person
  class amfi external
  class amcs external
  class advisorkhoj external
  class advisorkhoj unverified
  class nse external
  class nse unverified
  class estate internal
  class pe internal
  class mcrm internal
  class mmdep internal

Estate containers

flowchart LR
  client(["<b>Client / visitor</b><br/><small>Person</small>"])
  amfi["<b>AMFI</b><br/><small>NAV history, scheme master, AUM, TER, pe…</small>"]
  advisorkhoj["<b>AdvisorKhoj</b><br/><small>Portfolio holdings source</small>"]
  nse["<b>NSE indices</b><br/><small>Index values for benchmarks</small>"]
  amcs["<b>AMC websites</b><br/><small>Monthly factsheets (51 AMCs)</small>"]
  pe["<b>Portfolio Engine (PE)</b><br/><small>Portfolio construction, objective select…</small>"]
  mcrm["<b>MCRM</b><br/><small>Catalogue, CRM and product models; owns …</small>"]
  mmdep["<b>MMDEP</b><br/><small>Engineering programme: collector, harnes…</small>"]
  subgraph estate["Money Marche platform"]
    wwwSite["<b>Production website</b><br/><small>WordPress/PHP on Apache</small>"]
    stgSite["<b>Staging website</b><br/><small>WordPress/PHP on Apache</small>"]
    webapp["<b>Web app (webapp-sakai)</b><br/><small>Web app</small>"]
    api["<b>API (production)</b><br/><small>Python/Flask + gevent</small>"]
    stgapi["<b>API (staging)</b><br/><small>Python/Flask + gevent</small>"]
    mmcron["<b>MM-Cron</b><br/><small>Python, server crontab + AWS Lambda (nav…</small>"]
    wwwDb[("<b>moneymarche_www</b><br/><small>MariaDB</small>")]
    mmData[("<b>mm_data</b><br/><small>MariaDB</small>")]
    stgDbs[("<b>mm_api_staging / mm_nav_staging</b><br/><small>MariaDB</small>")]
    mongo[("<b>MongoDB (NAV/product)</b><br/><small>MongoDB Atlas</small>")]
    crm["<b>SuiteCRM</b><br/><small>PHP</small>"]
    mautic["<b>Mautic</b><br/><small>PHP</small>"]
  end
  client -->|"Browses, enquires"| wwwSite
  client -->|"Uses calculators"| webapp
  wwwSite -->|"Reads catalogue, NAV, categories"| api
  stgSite -->|"Reads (staging)"| stgapi
  webapp -->|"Reads"| api
  wwwSite -->|"Direct DB reads (to be removed: API-only plan)"| wwwDb
  api -->|"Reads/writes catalogue and app data"| wwwDb
  api -->|"Reads NAV/market data; /save-nav writes funds_nav"| mmData
  api -->|"NAV/product operations"| mongo
  api -->|"CRM entities, leads"| crm
  stgapi -->|"Reads/writes (never mm_data)"| stgDbs
  mmcron -->|"Downloads NAV history, scheme data, AUM, TER, performance"| amfi
  mmcron -->|"Portfolio ingestion"| advisorkhoj
  mmcron -->|"Index values"| nse
  mmcron -->|"POST /save-nav"| api
  mmcron -->|"Direct writes (tmp tables, AUM, TER, portfolios)"| mmData
  mmcron -->|"Catalogue writes (mm_product, fund details)"| wwwDb
  mmcron -->|"Factsheets (planned parsers)"| amcs
  mmcron -->|"Staging runs through write routes (staging key)"| stgapi
  mmcronPublish -->|"Staging writes"| stgapi
  apiDataAccess -->|"Catalogue and application data"| wwwDb
  apiDataAccess -->|"NAV and market data"| mmData
  pe -->|"GET /api/schemes, /api/scheme/nav, /api/index/nav"| api
  mcrm -->|"Catalogue contracts (category, product)"| api
  mmdep -->|"Read-only health and data checks (collector)"| api
  mmdep -->|"Smoke checks"| stgapi
  classDef person fill:#08427b,color:#fff,stroke:#052e56
  classDef internal fill:#1f5e7a,color:#fff,stroke:#123a4c
  classDef external fill:#8a8a8a,color:#fff,stroke:#666
  classDef container fill:#438dd5,color:#fff,stroke:#2e6295
  classDef unverified stroke-dasharray:5 5,stroke-width:2px
  class client person
  class amfi external
  class advisorkhoj external
  class advisorkhoj unverified
  class nse external
  class nse unverified
  class amcs external
  class pe internal
  class mcrm internal
  class mmdep internal
  class wwwSite container
  class stgSite container
  class webapp container
  class webapp unverified
  class api container
  class stgapi container
  class mmcron container
  class wwwDb container
  class mmData container
  class stgDbs container
  class mongo container
  class crm container
  class mautic container
  class mautic unverified