# mykhailoshes/scale-angine architecture

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

- Interactive diagram: https://gitdiagram.com/mykhailoshes/scale-angine
- Repository: https://github.com/mykhailoshes/scale-angine

## Overview

#### Purpose and runtime

Scale Engine is an Electron desktop gateway between Mettler Toledo scale folders and a remote SFTP middleware. Electron hosts a NestJS application in its main process; no HTTP server or separate service process is started. The renderer is a plain HTML/CSS/JS control UI.

Entry points: `src/main/main.ts`, `src/main/preload.ts`, and `src/renderer/renderer.js`.

#### Electron shell and UI boundary

The Electron main process creates the application window, exposes constrained preload APIs, and translates renderer actions into IPC requests. The renderer manages configuration input, Start/Stop controls, connection status, and streamed activity logs.

Key paths:
- `src/main/main.ts`
- `src/main/preload.ts`
- `src/main/ipc.ts`
- `src/main/ipc-channels.ts`
- `src/renderer/renderer.js`

The renderer does not directly access filesystem, SFTP, or Nest services; those capabilities remain in the main-process IPC boundary.

#### Nest application composition

NestJS supplies the dependency-injected service layer embedded in Electron. Bootstrap initializes the Nest context, while the root module assembles configuration, SFTP transport, watchers, and the agent orchestrator.

Key paths:
- `src/main/nest/bootstrap.ts`
- `src/main/nest/app.module.ts`
- `src/main/nest/agent/agent.module.ts`

#### Configuration and credential persistence

Configuration stores the SFTP URL, assigned folder name, and local Import/Export directories in Electron `userData` as `scale-engine-config.json`. The configuration service encrypts SFTP passwords through Electron `safeStorage`, supports legacy plaintext migration, and is used by IPC and agent startup.

Key paths:
- `src/main/nest/config/config.service.ts`
- `src/main/nest/config/config.types.ts`
- `src/main/nest/config/config.module.ts`

This is the main persistence and OS-security boundary; encrypted storage relies on platform facilities such as Windows DPAPI and macOS Keychain.

#### Agent lifecycle orchestration

The agent service is the operational state machine behind Start and Stop. Start persists configuration, establishes SFTP connectivity, and activates both directional watchers. Stop halts watchers and closes the SFTP session. It also governs whether reconnect behavior should continue after transport loss.

Key paths:
- `src/main/nest/agent/agent.service.ts`
- `src/main/nest/sftp/sftp.service.ts`
- `src/main/nest/watcher/watcher.module.ts`

#### Shared SFTP transport

A single `ssh2-sftp-client` wrapper owns the remote session for both watchers. It targets the middleware’s `/upload` hierarchy, observes `end`, `close`, and `error` failures, and reconnects with exponential backoff while the agent remains running.

Key paths:
- `src/main/nest/sftp/sftp.service.ts`
- `src/main/nest/sftp/sftp.module.ts`

External dependency: an SFTP server hosting shared import/export and processed folders.

#### Bidirectional file-transfer stages

The export watcher polls the local scale Export directory, ignores recently modified files to avoid mid-write reads, uploads receipt XML to `/upload/import`, then archives the local file under `<Export>/processed` with a timestamped name.

The import watcher polls `/upload/<FolderName>/export/`, downloads product XML into the local scale Import directory, then moves the remote source into its `processed` folder.

Key paths:
- `src/main/nest/watcher/export-watcher.service.ts`
- `src/main/nest/watcher/import-watcher.service.ts`

#### Logging and operational feedback

Services publish activity and error events through an in-process logger bus. IPC mirrors these events to the renderer, where failures and connection state drive the activity log and status indicator.

Key paths:
- `src/main/nest/logger.service.ts`
- `src/main/ipc.ts`
- `src/renderer/index.html`

Main entry points: [`src/main/nest/agent/agent.service.ts`](https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/agent/agent.service.ts) (Agent Lifecycle), [`src/main/ipc.ts`](https://github.com/mykhailoshes/scale-angine/blob/main/src/main/ipc.ts) (IPC Bridge), [`src/main/nest/sftp/sftp.service.ts`](https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/sftp/sftp.service.ts) (SFTP Transport), [`src/main/nest/watcher/export-watcher.service.ts`](https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/watcher/export-watcher.service.ts) (Export Watcher)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_electron["Electron UI"]
  node_renderer["Control UI<br/>renderer<br/>[renderer.js]"]
  node_preload["Preload API<br/>[preload.ts]"]
  node_electron_main["Electron Main<br/>main process<br/>[main.ts]"]
  node_ipc["IPC Bridge<br/>IPC handlers<br/>[ipc.ts]"]
  node_ipc_channels["IPC Channels<br/>IPC contract<br/>[ipc-channels.ts]"]
end

subgraph group_nest["Embedded NestJS"]
  node_nest_bootstrap["Nest Bootstrap<br/>application context<br/>[bootstrap.ts]"]
  node_app_module["Root Module<br/>Nest module<br/>[app.module.ts]"]
  node_agent{{"Agent Lifecycle<br/>orchestrator<br/>[agent.service.ts]"}}
  node_agent_module["Agent Module<br/>Nest module<br/>[agent.module.ts]"]
  node_config[("Configuration Service<br/>credential store<br/>[config.service.ts]")]
  node_config_module["Configuration Module<br/>Nest module<br/>[config.module.ts]"]
  node_logger["Logger Bus<br/>in-process events<br/>[logger.service.ts]"]
  node_config_file[("User Data Config<br/>encrypted file")]
end

subgraph group_transfer["File Transfer"]
  node_sftp{{"SFTP Transport<br/>shared session<br/>[sftp.service.ts]"}}
  node_export_watcher["Export Watcher<br/>outbound watcher"]
  node_import_watcher["Import Watcher<br/>inbound watcher"]
  node_local_folders[("Scale Import / Export<br/>local filesystem")]
  node_sftp_server[("Middleware SFTP Server<br/>external SFTP")]
end

node_renderer -->|"uses API"| node_preload
node_preload -->|"IPC requests"| node_ipc
node_ipc -->|"uses contract"| node_ipc_channels
node_electron_main -->|"hosts"| node_nest_bootstrap
node_nest_bootstrap -->|"initializes"| node_app_module
node_app_module -->|"imports"| node_agent_module
node_ipc -->|"Start / Stop"| node_agent
node_ipc -->|"read / save settings"| node_config
node_agent -->|"persists startup config"| node_config
node_config -->|"encrypted credentials"| node_config_file
node_agent -->|"connect / disconnect"| node_sftp
node_agent -->|"activates"| node_export_watcher
node_agent -->|"activates"| node_import_watcher
node_export_watcher -->|"polls Export; archives"| node_local_folders
node_export_watcher -->|"uploads receipt XML"| node_sftp
node_import_watcher -->|"downloads product XML"| node_sftp
node_import_watcher -->|"writes Import"| node_local_folders
node_sftp -->|"shared remote session"| node_sftp_server
node_sftp -->|"transport events"| node_logger
node_agent -->|"lifecycle events"| node_logger
node_logger -->|"activity / errors"| node_ipc
node_ipc -->|"status and logs"| node_renderer

click node_renderer "https://github.com/mykhailoshes/scale-angine/blob/main/src/renderer/renderer.js"
click node_preload "https://github.com/mykhailoshes/scale-angine/blob/main/src/main/preload.ts"
click node_electron_main "https://github.com/mykhailoshes/scale-angine/blob/main/src/main/main.ts"
click node_ipc "https://github.com/mykhailoshes/scale-angine/blob/main/src/main/ipc.ts"
click node_ipc_channels "https://github.com/mykhailoshes/scale-angine/blob/main/src/main/ipc-channels.ts"
click node_nest_bootstrap "https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/bootstrap.ts"
click node_app_module "https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/app.module.ts"
click node_agent "https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/agent/agent.service.ts"
click node_agent_module "https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/agent/agent.module.ts"
click node_config "https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/config/config.service.ts"
click node_config_module "https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/config/config.module.ts"
click node_sftp "https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/sftp/sftp.service.ts"
click node_export_watcher "https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/watcher/export-watcher.service.ts"
click node_import_watcher "https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/watcher/import-watcher.service.ts"
click node_logger "https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/logger.service.ts"

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_renderer,node_preload,node_electron_main,node_ipc,node_ipc_channels toneBlue
class node_nest_bootstrap,node_app_module,node_agent,node_agent_module,node_config,node_config_module,node_logger,node_config_file toneAmber
class node_sftp,node_export_watcher,node_import_watcher,node_local_folders,node_sftp_server toneMint
```

## Components

### Electron UI

- [Control UI](https://github.com/mykhailoshes/scale-angine/blob/main/src/renderer/renderer.js): renderer · Configuration, Start/Stop, status, and activity log. · `src/renderer/renderer.js`
- [Preload API](https://github.com/mykhailoshes/scale-angine/blob/main/src/main/preload.ts): preload · Exposes constrained main-process capabilities. · `src/main/preload.ts`
- [Electron Main](https://github.com/mykhailoshes/scale-angine/blob/main/src/main/main.ts): main process · Creates the application window and hosts Nest. · `src/main/main.ts`
- [IPC Bridge](https://github.com/mykhailoshes/scale-angine/blob/main/src/main/ipc.ts): IPC handlers · Translates UI actions and mirrors operational events. · `src/main/ipc.ts`
- [IPC Channels](https://github.com/mykhailoshes/scale-angine/blob/main/src/main/ipc-channels.ts): IPC contract · `src/main/ipc-channels.ts`

### Embedded NestJS

Runs inside the Electron main process.

- [Nest Bootstrap](https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/bootstrap.ts): application context · Initializes the embedded dependency-injection context. · `src/main/nest/bootstrap.ts`
- [Root Module](https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/app.module.ts): Nest module · Assembles configuration, transport, watchers, and agent. · `src/main/nest/app.module.ts`
- [Agent Lifecycle](https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/agent/agent.service.ts): orchestrator · Starts and stops transport and both directional watchers. · `src/main/nest/agent/agent.service.ts`
- [Agent Module](https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/agent/agent.module.ts): Nest module · `src/main/nest/agent/agent.module.ts`
- [Configuration Service](https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/config/config.service.ts): credential store · Encrypts SFTP passwords and migrates legacy plaintext settings. · `src/main/nest/config/config.service.ts`
- [Configuration Module](https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/config/config.module.ts): Nest module · `src/main/nest/config/config.module.ts`
- [Logger Bus](https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/logger.service.ts): in-process events · Publishes activity and error events. · `src/main/nest/logger.service.ts`
- **User Data Config**: encrypted file · scale-engine-config.json in Electron userData.

### File Transfer

- [SFTP Transport](https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/sftp/sftp.service.ts): shared session · Owns one session and reconnects with backoff while running. · `src/main/nest/sftp/sftp.service.ts`
- [Export Watcher](https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/watcher/export-watcher.service.ts): outbound watcher · Uploads stable receipt XML and archives local sources. · `src/main/nest/watcher/export-watcher.service.ts`
- [Import Watcher](https://github.com/mykhailoshes/scale-angine/blob/main/src/main/nest/watcher/import-watcher.service.ts): inbound watcher · Downloads product XML and moves remote sources to processed. · `src/main/nest/watcher/import-watcher.service.ts`
- **Scale Import / Export**: local filesystem · Configured scale folders, including local processed exports.
- **Middleware SFTP Server**: external SFTP · Hosts upload, export, and processed folders.

## Connections

- Control UI → Preload API: uses API
- Preload API → IPC Bridge: IPC requests
- IPC Bridge → IPC Channels: uses contract
- Electron Main → Nest Bootstrap: hosts
- Nest Bootstrap → Root Module: initializes
- Root Module → Agent Module: imports
- IPC Bridge → Agent Lifecycle: Start / Stop
- IPC Bridge → Configuration Service: read / save settings
- Agent Lifecycle → Configuration Service: persists startup config
- Configuration Service → User Data Config: encrypted credentials
- Agent Lifecycle → SFTP Transport: connect / disconnect
- Agent Lifecycle → Export Watcher: activates
- Agent Lifecycle → Import Watcher: activates
- Export Watcher → Scale Import / Export: polls Export; archives
- Export Watcher → SFTP Transport: uploads receipt XML
- Import Watcher → SFTP Transport: downloads product XML
- Import Watcher → Scale Import / Export: writes Import
- SFTP Transport → Middleware SFTP Server: shared remote session
- SFTP Transport → Logger Bus: transport events
- Agent Lifecycle → Logger Bus: lifecycle events
- Logger Bus → IPC Bridge: activity / errors
- IPC Bridge → Control UI: status and logs
