Architecture
WASH PRO CRM components and data flows
Overview
Post controllers
│
▼
Mosquitto (wash/telemetry/# and +/+/#)
│
▼
Message Processor ◄── HTTP :3022 (commands/prices from Dashboard)
│
▼
Dynamic API ──► MongoDB
▲
Dashboard (React) ──────────┤ nginx /api proxy
│ /api/crm/post-device/ → processor
│
pyorch-bridge ─────┤ (Telegram, Admin)
▲ │
│ │
PyOrchestrator ──────┘ (opt.)
│
backup / service account
Docker Compose Services
Main stack (docker-compose.yml)
| Service | Container | Purpose | External access |
|---|---|---|---|
mongodb |
wash-mongodb | CRM database (Dynamic API) | ❌ |
dynamic-api |
wash-dynamic-api | REST API | ✅ :3001 |
dynamic-api-panel |
wash-dynamic-api-panel | Dynamic API Panel | ✅ :8080 |
dashboard |
wash-dashboard | CRM Dashboard | ✅ :80 |
init-seed |
wash-init-seed | One-time CRM initialization | ❌ |
mosquitto |
wash-mosquitto | MQTT telemetry broker | ✅ :1883 (LAN) |
mosquitto-init |
wash-mosquitto-init | system + ACL template |
❌ |
message-processor |
wash-message-processor | MQTT ↔ API, sync passwd/ACL, HTTP :3022 |
❌ |
backup |
wash-backup | mongodump + HTTP files | ❌ |
Optional services
| Service | Condition | Purpose |
|---|---|---|
redis |
REDIS_ENABLED=true + docker-compose.redis.yml |
Cache (profile redis) |
| PyOrchestrator stack | PYORCHESTRATOR_ENABLED=true |
See table below |
PyOrchestrator (docker-compose.pyorchestrator.yml)
| Service | External access | Purpose |
|---|---|---|
pyorch-backend |
✅ :8000 |
FastAPI |
pyorchestrator-panel |
✅ :8090 |
Control Plane UI |
pyorch-mcp |
✅ :8010 |
MCP for AI agents |
pyorch-bridge |
❌ (via Dashboard) | CRM Telegram bots |
pyorch-runtime |
❌ | Python sandbox |
pyorch-scheduler |
❌ | Schedules |
pyorch-postgres |
❌ | Metadata |
pyorch-redis |
❌ | Job queue |
pyorch-minio |
❌ | Workspace |
pyorch-prometheus/grafana/loki/promtail |
profile pyorch-observability |
Metrics and logs |
Details: Embedded services.
Docker Networks
| Network | Type | Purpose |
|---|---|---|
wash-internal |
internal | MongoDB, message-processor, backup (no internet access) |
wash-external |
bridge | Dashboard, API, Mosquitto (port 1883 for LAN) |
MongoDB is not published externally. MQTT (:1883) is available on the local network for post controllers.
Telemetry Flow
Inbound (post → CRM)
- Controller publishes JSON to topic
{dt_pref}/{serial}/state/{suffix}(native protocol) orwash/telemetry/{type}(legacy), QoS 1, with post login from CRM. - Mosquitto checks ACL: post can write only to topics of its own
serialNumber. message-processor(assystem) subscribes towash/telemetry/#and+/+/#.- Serial number for CRM is taken from the topic (payload with foreign serial is ignored).
- Post is found by serial in
/api/crm/posts. - Data is written to CRM endpoints (
post-states,cards, statistics…). - Each message is duplicated to the log
/api/crm/telemetry. - Processing errors → DLQ
wash/dlq.
MQTT sync: on post save or POST /api/crm/post-device/mqtt/sync-users, message-processor recreates passwd and acl in DATA_DIR/mosquitto/config/. Mosquitto reloads files without restart.
Types: mode/state, card, statistics, finance, equipment, event, settings, prices, command.
Outbound (CRM → post)
- Dashboard → nginx
/api/crm/post-device/…→ HTTPmessage-processor:3022. - User JWT validated via
/api/profile. - Publish to
{dt_pref}/{serial}/set/pricesorset/command. - Prices and command metadata saved in
posts.settings. - Outbound messages logged to telemetry.
Details: MQTT — post control.
Initialization (init-seed)
- 11 CRM endpoint groups, 52 endpoints
- RBAC: Administrator, Operator, Viewer, Service
- RUB currency, discount types 1–5, backup/archive/telegram settings
- Idempotent — safe to re-run
./scripts/run-init-seed.sh
Data directory (DATA_DIR)
Default ./data on the host (bind mount). Rebuild and docker compose down do not delete these files.
| Path | Data |
|---|---|
mongodb/ |
CRM MongoDB |
backups/ |
Backup files |
mosquitto/data/ |
MQTT persistence |
mosquitto/config/ |
MQTT passwd, ACL, mosquitto.conf |
pyorchestrator/ |
PostgreSQL, Redis, MinIO, runtime (opt.) |
Details: data/README.md.
Dynamic API Platform (vendored v1.5.13)
Vendored copy of Dynamic API Platform with WASH patches.
| In WASH | Upstream-only |
|---|---|
Runtime engine for /api/crm/* |
K8s / MongoDB replica set deploy |
Panel :8080 (embedded build) |
Standalone in-app updater |
Update: ./scripts/update-dynamic-api.sh |
npm run k8s:deploy |
In-app updater is disabled: UPDATE_EXECUTOR_ENABLED=false.
PyOrchestrator (vendored v0.1.10)
Vendored copy of PyOrchestrator.
Default in .env.example: PYORCHESTRATOR_ENABLED=true, but the stack starts only if the variable is true in your .env and ./scripts/start.sh attaches the overlay.
Update:
./scripts/update-pyorchestrator.sh
docker compose -f docker-compose.yml -f docker-compose.pyorchestrator.yml up -d --build