# enming73/digital-twin architecture

> Architecture diagram of the GitHub repository enming73/digital-twin, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-11). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/enming73/digital-twin
- Repository: https://github.com/enming73/digital-twin

## Overview

SMT Digital Twin Studio is a synthetic SMT-line demonstration with a standalone browser workflow and an optional remote stack. In the browser, users run or control a deterministic production simulation, inspect the 3D line and analytics, and trace boards; remote mode instead displays read-only backend state and supports historical seek and MES trace lookup. The optional Go simulator publishes events to a twin backend, which exposes APIs and can add durable history and offline recovery. Some backend and simulator connections are documented in the README but their implementation excerpts were not sampled.

Main entry points: [`src/app/App.tsx`](https://github.com/enming73/digital-twin/blob/main/src/app/App.tsx) (Studio app), [`src/simulation/engine.ts`](https://github.com/enming73/digital-twin/blob/main/src/simulation/engine.ts) (Simulation engine), [`backend/internal/api/http.go`](https://github.com/enming73/digital-twin/blob/main/backend/internal/api/http.go) (REST and WebSocket API), [`backend/internal/ingest/mqtt.go`](https://github.com/enming73/digital-twin/blob/main/backend/internal/ingest/mqtt.go) (MQTT ingestion)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_browser["Browser experience"]
  node_app["Studio app<br/>[App.tsx]"]
  node_scene["Factory scene<br/>[Factory.tsx]"]
  node_stations["Station model<br/>[stations.ts]"]
  node_dashboard["Production dashboard<br/>[Dashboard.tsx]"]
  node_traceui["Remote trace UI<br/>[RemoteTrace.tsx]"]
end

subgraph group_local["Local production demo"]
  node_engine["Simulation engine<br/>[engine.ts]"]
  node_scenario["Scenario data<br/>[scenario.ts]"]
  node_analytics["Production analytics<br/>[analytics.ts]"]
  node_replay["Local replay<br/>[replay.ts]"]
  node_presentation["Guided presentation<br/>[presentation.ts]"]
end

subgraph group_remote["Remote twin view"]
  node_remoteclient["Remote client<br/>[remoteClient.ts]"]
  node_projection["Remote projection<br/>[projection.ts]"]
  node_remoteadapter["Remote scene adapter<br/>[remoteAdapter.ts]"]
  node_motion["Remote motion<br/>[remoteMotion.ts]"]
  node_historyclient["History client"]
  node_mesclient["MES client<br/>[mesClient.ts]"]
end

subgraph group_sim["Simulator and ingestion"]
  node_simulator["Go simulator<br/>[main.go]"]
  node_simengine["Simulation engine<br/>[engine.go]"]
  node_runner["Scenario runner<br/>[runner.go]"]
  node_outbox[("Durable outbox<br/>[service.go]")]
  node_publisher["MQTT publisher<br/>[mqtt.go]"]
end

subgraph group_backend["Twin backend"]
  node_backendmain["Backend service<br/>[main.go]"]
  node_ingest["MQTT ingestion<br/>[mqtt.go]"]
  node_contract["Event contract<br/>[event.go]"]
  node_twin["Twin state<br/>[store.go]"]
  node_api["REST and WebSocket API<br/>[http.go]"]
  node_mes["Mock MES fixtures<br/>[fixtures.go]"]
  node_postgres[("PostgreSQL history<br/>[events.go]")]
  node_historical["Historical replay<br/>[historical.go]"]
  node_recovery["Offline recovery<br/>[coordinator.go]"]
end

node_user(("Viewer"))
node_mqtt["MQTT broker"]
node_sourceapi["Durable source API"]

node_user -->|"uses"| node_app
node_app -->|"runs locally"| node_engine
node_app -->|"starts remote"| node_remoteclient
node_app -->|"seeks history"| node_historyclient
node_app -->|"renders"| node_scene
node_app -->|"renders"| node_dashboard
node_app -->|"renders"| node_traceui
node_scenario -->|"configures"| node_engine
node_engine -->|"supplies events"| node_analytics
node_engine -->|"supplies events"| node_replay
node_engine -->|"drives"| node_presentation
node_scene -->|"uses layout"| node_stations
node_dashboard -->|"computes metrics"| node_analytics
node_remoteclient -->|"applies messages"| node_projection
node_app -->|"adapts state"| node_remoteadapter
node_remoteadapter -->|"updates motion"| node_motion
node_traceui -->|"requests trace"| node_mesclient
node_historyclient -->|"validates snapshot"| node_projection
node_simulator -.->|"runs scenarios"| node_runner
node_runner -.->|"advances"| node_simengine
node_simulator -.->|"persists events"| node_outbox
node_simulator -.->|"publishes events"| node_publisher
node_publisher -.->|"publishes MQTT"| node_mqtt
node_mqtt -.->|"delivers events"| node_ingest
node_backendmain -.->|"starts ingestion"| node_ingest
node_ingest -.->|"validates events"| node_contract
node_ingest -.->|"updates state"| node_twin
node_backendmain -.->|"serves APIs"| node_api
node_api -.->|"reads projection"| node_twin
node_api -.->|"serves trace data"| node_mes
node_twin -.->|"persists events"| node_postgres
node_historical -.->|"reads history"| node_postgres
node_api -.->|"serves replay"| node_historical
node_recovery -.->|"repairs from"| node_sourceapi
node_app -.->|"reads remotely"| node_api

click node_app "https://github.com/enming73/digital-twin/blob/main/src/app/App.tsx"
click node_scene "https://github.com/enming73/digital-twin/blob/main/src/scene/Factory.tsx"
click node_stations "https://github.com/enming73/digital-twin/blob/main/src/data/stations.ts"
click node_dashboard "https://github.com/enming73/digital-twin/blob/main/src/components/Dashboard.tsx"
click node_traceui "https://github.com/enming73/digital-twin/blob/main/src/components/RemoteTrace.tsx"
click node_engine "https://github.com/enming73/digital-twin/blob/main/src/simulation/engine.ts"
click node_scenario "https://github.com/enming73/digital-twin/blob/main/src/data/scenario.ts"
click node_analytics "https://github.com/enming73/digital-twin/blob/main/src/domain/analytics.ts"
click node_replay "https://github.com/enming73/digital-twin/blob/main/src/domain/replay.ts"
click node_presentation "https://github.com/enming73/digital-twin/blob/main/src/presentation/presentation.ts"
click node_remoteclient "https://github.com/enming73/digital-twin/blob/main/src/twin/remoteClient.ts"
click node_projection "https://github.com/enming73/digital-twin/blob/main/src/twin/projection.ts"
click node_remoteadapter "https://github.com/enming73/digital-twin/blob/main/src/twin/remoteAdapter.ts"
click node_motion "https://github.com/enming73/digital-twin/blob/main/src/scene/remoteMotion.ts"
click node_historyclient "https://github.com/enming73/digital-twin/blob/main/src/twin/historicalClient.ts"
click node_mesclient "https://github.com/enming73/digital-twin/blob/main/src/twin/mesClient.ts"
click node_simulator "https://github.com/enming73/digital-twin/blob/main/simulator/cmd/simulator/main.go"
click node_simengine "https://github.com/enming73/digital-twin/blob/main/simulator/internal/engine/engine.go"
click node_runner "https://github.com/enming73/digital-twin/blob/main/simulator/internal/runner/runner.go"
click node_outbox "https://github.com/enming73/digital-twin/blob/main/simulator/internal/outbox/service.go"
click node_publisher "https://github.com/enming73/digital-twin/blob/main/simulator/internal/publisher/mqtt.go"
click node_backendmain "https://github.com/enming73/digital-twin/blob/main/backend/cmd/twin-backend/main.go"
click node_ingest "https://github.com/enming73/digital-twin/blob/main/backend/internal/ingest/mqtt.go"
click node_contract "https://github.com/enming73/digital-twin/blob/main/backend/internal/contract/event.go"
click node_twin "https://github.com/enming73/digital-twin/blob/main/backend/internal/twin/store.go"
click node_api "https://github.com/enming73/digital-twin/blob/main/backend/internal/api/http.go"
click node_mes "https://github.com/enming73/digital-twin/blob/main/backend/internal/mes/fixtures.go"
click node_postgres "https://github.com/enming73/digital-twin/blob/main/backend/internal/persistence/events.go"
click node_historical "https://github.com/enming73/digital-twin/blob/main/backend/internal/replay/historical.go"
click node_recovery "https://github.com/enming73/digital-twin/blob/main/backend/internal/recovery/coordinator.go"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_scene,node_stations,node_dashboard,node_traceui,node_user toneBlue
class node_engine,node_scenario,node_analytics,node_replay,node_presentation toneAmber
class node_remoteclient,node_projection,node_remoteadapter,node_motion,node_historyclient,node_mesclient,node_sourceapi toneMint
class node_simulator,node_simengine,node_runner,node_outbox,node_publisher toneRose
class node_backendmain,node_ingest,node_contract,node_twin,node_api,node_mes,node_postgres,node_historical,node_recovery,node_mqtt toneIndigo
```

## Components

### Browser experience

- [Studio app](https://github.com/enming73/digital-twin/blob/main/src/app/App.tsx): `src/app/App.tsx`
- [Factory scene](https://github.com/enming73/digital-twin/blob/main/src/scene/Factory.tsx): `src/scene/Factory.tsx`
- [Station model](https://github.com/enming73/digital-twin/blob/main/src/data/stations.ts): `src/data/stations.ts`
- [Production dashboard](https://github.com/enming73/digital-twin/blob/main/src/components/Dashboard.tsx): `src/components/Dashboard.tsx`
- [Remote trace UI](https://github.com/enming73/digital-twin/blob/main/src/components/RemoteTrace.tsx): `src/components/RemoteTrace.tsx`

### Local production demo

- [Simulation engine](https://github.com/enming73/digital-twin/blob/main/src/simulation/engine.ts): `src/simulation/engine.ts`
- [Scenario data](https://github.com/enming73/digital-twin/blob/main/src/data/scenario.ts): `src/data/scenario.ts`
- [Production analytics](https://github.com/enming73/digital-twin/blob/main/src/domain/analytics.ts): `src/domain/analytics.ts`
- [Local replay](https://github.com/enming73/digital-twin/blob/main/src/domain/replay.ts): `src/domain/replay.ts`
- [Guided presentation](https://github.com/enming73/digital-twin/blob/main/src/presentation/presentation.ts): `src/presentation/presentation.ts`

### Remote twin view

- [Remote client](https://github.com/enming73/digital-twin/blob/main/src/twin/remoteClient.ts): `src/twin/remoteClient.ts`
- [Remote projection](https://github.com/enming73/digital-twin/blob/main/src/twin/projection.ts): `src/twin/projection.ts`
- [Remote scene adapter](https://github.com/enming73/digital-twin/blob/main/src/twin/remoteAdapter.ts): `src/twin/remoteAdapter.ts`
- [Remote motion](https://github.com/enming73/digital-twin/blob/main/src/scene/remoteMotion.ts): `src/scene/remoteMotion.ts`
- [History client](https://github.com/enming73/digital-twin/blob/main/src/twin/historicalClient.ts): `src/twin/historicalClient.ts`
- [MES client](https://github.com/enming73/digital-twin/blob/main/src/twin/mesClient.ts): `src/twin/mesClient.ts`

### Simulator and ingestion

- [Go simulator](https://github.com/enming73/digital-twin/blob/main/simulator/cmd/simulator/main.go): `simulator/cmd/simulator/main.go`
- [Simulation engine](https://github.com/enming73/digital-twin/blob/main/simulator/internal/engine/engine.go): `simulator/internal/engine/engine.go`
- [Scenario runner](https://github.com/enming73/digital-twin/blob/main/simulator/internal/runner/runner.go): `simulator/internal/runner/runner.go`
- [Durable outbox](https://github.com/enming73/digital-twin/blob/main/simulator/internal/outbox/service.go): `simulator/internal/outbox/service.go`
- [MQTT publisher](https://github.com/enming73/digital-twin/blob/main/simulator/internal/publisher/mqtt.go): `simulator/internal/publisher/mqtt.go`

### Twin backend

- [Backend service](https://github.com/enming73/digital-twin/blob/main/backend/cmd/twin-backend/main.go): `backend/cmd/twin-backend/main.go`
- [MQTT ingestion](https://github.com/enming73/digital-twin/blob/main/backend/internal/ingest/mqtt.go): `backend/internal/ingest/mqtt.go`
- [Event contract](https://github.com/enming73/digital-twin/blob/main/backend/internal/contract/event.go): `backend/internal/contract/event.go`
- [Twin state](https://github.com/enming73/digital-twin/blob/main/backend/internal/twin/store.go): `backend/internal/twin/store.go`
- [REST and WebSocket API](https://github.com/enming73/digital-twin/blob/main/backend/internal/api/http.go): `backend/internal/api/http.go`
- [Mock MES fixtures](https://github.com/enming73/digital-twin/blob/main/backend/internal/mes/fixtures.go): `backend/internal/mes/fixtures.go`
- [PostgreSQL history](https://github.com/enming73/digital-twin/blob/main/backend/internal/persistence/events.go): `backend/internal/persistence/events.go`
- [Historical replay](https://github.com/enming73/digital-twin/blob/main/backend/internal/replay/historical.go): `backend/internal/replay/historical.go`
- [Offline recovery](https://github.com/enming73/digital-twin/blob/main/backend/internal/recovery/coordinator.go): `backend/internal/recovery/coordinator.go`

### Other components

- **Viewer**
- **MQTT broker**
- **Durable source API**

## Connections

- Viewer → Studio app: uses (evidence: `README.md`)
- Studio app → Simulation engine: runs locally (evidence: `src/app/App.tsx`)
- Studio app → Remote client: starts remote (evidence: `src/app/App.tsx`)
- Studio app → History client: seeks history (evidence: `src/app/App.tsx`)
- Studio app → Factory scene: renders (evidence: `src/app/App.tsx`)
- Studio app → Production dashboard: renders (evidence: `src/app/App.tsx`)
- Studio app → Remote trace UI: renders (evidence: `src/app/App.tsx`)
- Scenario data → Simulation engine: configures (evidence: `src/data/scenario.ts`)
- Simulation engine → Production analytics: supplies events (evidence: `src/domain/analytics.ts`)
- Simulation engine → Local replay: supplies events (evidence: `src/domain/replay.ts`)
- Simulation engine → Guided presentation: drives (evidence: `src/presentation/presentation.ts`)
- Factory scene → Station model: uses layout (evidence: `src/scene/Factory.tsx`)
- Production dashboard → Production analytics: computes metrics (evidence: `src/components/Dashboard.tsx`)
- Remote client → Remote projection: applies messages (evidence: `src/twin/remoteClient.ts`)
- Studio app → Remote scene adapter: adapts state (evidence: `src/app/App.tsx`)
- Remote scene adapter → Remote motion: updates motion (evidence: `src/twin/remoteAdapter.ts`)
- Remote trace UI → MES client: requests trace (evidence: `src/components/RemoteTrace.tsx`)
- History client → Remote projection: validates snapshot (evidence: `src/twin/historicalClient.ts`)
- Go simulator → Scenario runner: runs scenarios (evidence: `README.md`)
- Scenario runner → Simulation engine: advances (evidence: `README.md`)
- Go simulator → Durable outbox: persists events (evidence: `README.md`)
- Go simulator → MQTT publisher: publishes events (evidence: `README.md`)
- MQTT publisher → MQTT broker: publishes MQTT (evidence: `README.md`)
- MQTT broker → MQTT ingestion: delivers events (evidence: `README.md`)
- Backend service → MQTT ingestion: starts ingestion (evidence: `README.md`)
- MQTT ingestion → Event contract: validates events (evidence: `README.md`)
- MQTT ingestion → Twin state: updates state (evidence: `README.md`)
- Backend service → REST and WebSocket API: serves APIs (evidence: `README.md`)
- REST and WebSocket API → Twin state: reads projection (evidence: `README.md`)
- REST and WebSocket API → Mock MES fixtures: serves trace data (evidence: `README.md`)
- Twin state → PostgreSQL history: persists events (evidence: `README.md`)
- Historical replay → PostgreSQL history: reads history (evidence: `README.md`)
- REST and WebSocket API → Historical replay: serves replay (evidence: `README.md`)
- Offline recovery → Durable source API: repairs from (evidence: `README.md`)
- Studio app → REST and WebSocket API: reads remotely (evidence: `README.md`)
