Documentation menu

Connections

Live Service Connection Map (3D)

Simulate AutoTelegramForward in 3D: verified component links, protocol boundaries and the request paths you can replay packet by packet.

Verified against the checkout built for v2.2.4 · updated 20 Oct 2026

On this page

Imports tell you how one language is arranged. Connections tell you how the system behaves: 23 links across 16 components, every one of them derived from a real call site in the checkout. Orbit the map, then replay one of the 3 traced paths and watch a packet cross the same boundaries a live message crosses.

3D connection simulation

Scenario
Viewdrag to orbit · scroll to zoom · click a node to focus
16 components · 23 links
mtprotoeventhttpsqlgrpcproxylive packet

A post is forwarded

From an incoming Telegram update to a delivered copy in every target chat, with the durable queue absorbing rate limits.

  1. 1

    Update arrives @ telegram-cloud

    MTProto push from the source chat the session is authorised for.

    PIPELINE:INGESTPIPELINE:DIALOG_FETCH
  2. 2

    Normalise @ core-ingest

    Album items are aggregated and the update is turned into a domain event.

  3. 3

    Resolve policy @ core-pipeline

    Matching tasks, per-source/policy overrides, whitelists and blacklists.

    PIPELINE:POLICYPIPELINE:POLICY_TARGETPIPELINE:NO_RULESPIPELINE:NO_MATCH
  4. 4

    Filter & rewrite @ core-pipeline

    Filters, cleaner, shortcodes, replacements — and the optional AI pass.

    PIPELINE:FILTERPIPELINE:CLEANERPIPELINE:TRANSFORMPIPELINE:AI_REWRITE
  5. 5

    Rewrite (optional) @ ai-rewriter

    Only when the task enables it; an unreachable provider passes the text through.

    PIPELINE:AI_REWRITE
  6. 6

    Enqueue per target @ core-queue

    One durable job per target with an ordering key, so bursts keep their order.

    PIPELINE:ENQUEUE
  7. 7

    Lease & deliver @ core-queue

    Lease-based workers with exponential backoff and FloodWait-aware rescheduling.

    PIPELINE:RETRYPIPELINE:FLOODWAIT
  8. 8

    Delivered @ telegram-cloud

    Copy mode or native forward, into the target chat or forum topic.

    PIPELINE:DELIVERED
  9. 9

    Recorded @ logger-svc

    Every stage, drop and outcome lands in the log store with a correlation id.

    PIPELINE:DROPPIPELINE:FILTER_DROPPIPELINE:DUP_FILTERPIPELINE:DELIVERY_FAILPIPELINE:DELIVERY_TIMEOUT

Trace

  • Pick a scenario to replay a real request path.

A post is forwarded

From an incoming Telegram update to a delivered copy in every target chat, with the durable queue absorbing rate limits.

9 steps · 6 components touched

An operator edits a task

A dashboard write travels through the gateway, the REST control plane and gRPC into the engine — with optimistic concurrency and an audit trail.

8 steps · 8 components touched

An event is investigated

Live logs, the diagnostic window and the dead-letter queue: how an operator answers "what happened to that message?".

6 steps · 6 components touched

Protocol boundaries

12 boundaries, and the file that proves each one. A boundary is where a version mismatch, a timeout or a serialization change becomes visible — which is exactly why they are worth listing instead of hiding behind "microservices".

api → core

gRPC :50051

Every rule, session and delivery command crosses this boundary as a protobuf RPC.

verified in: api/internal/grpcclient/grpcclient.go, api/internal/grpcclient/rpc_auth_test.go, api/internal/handlers/system.go

api → logger

gRPC :50052

The API writes its own logs, audits and latency events to the same central store.

verified in: api/internal/handlers/system.go, api/internal/handlers/system_test.go, api/main.go

core → logger

gRPC :50052

Pipeline stages emit [PIPELINE:*] events through the shared log client.

verified in: core/application/pipeline.py, core/config.py, core/main.py

core → AI rewriter

HTTP OpenAI-compatible

Optional rewrite pass. Unreachable provider degrades to pass-through, never to data loss.

verified in: core/infrastructure/ai/providers.py, core/infrastructure/ai/transformer.py

Web gateway → api

HTTP reverse proxy + SSE

Server-side proxy keeps the API key out of the browser and streams the live log feed.

verified in: web/backend/src/main.rs, web/frontend/.catalog-build/fr.js, web/frontend/src/locales/fr.ts

web-frontend → Web gateway

fetch /api/v1/*

The React app only ever talks to its own origin; the gateway owns upstream addressing.

verified in: web/frontend/src/api.ts

mobile → api

HTTPS + bearer token

Same REST contract as the dashboard, with offline-tolerant error surfaces.

verified in: mobile/lib/core/api_client.dart, mobile/lib/core/app_state.dart, mobile/lib/core/env.dart

DevOps CLI → api

HTTP health + config probes

Diagnostics read the same endpoints an operator would curl.

verified in: atfcli/application/gateways.py, atfcli/application/use_cases/logs.py, atfcli/application/use_cases/ops.py

root → Web gateway

Caddy reverse proxy

Optional --profile tls terminates TLS and forwards to the gateway.

verified in: Caddyfile

contracts → api

protoc / buf

The Go stubs and the Python servicers are both generated from one .proto file.

verified in: api/proto/autoforward.pb.go, api/proto/autoforward_grpc.pb.go

contracts → core

protoc / buf

One schema, two runtimes; a mismatch fails at the gRPC boundary, not in production.

verified in: core/infrastructure/grpc_server/account_servicer.py, core/infrastructure/grpc_server/admin_servicer.py, core/infrastructure/grpc_server/internal_auth.py

website → root

build-time ingestion

The site derives its numbers from the same files a contributor edits.

verified in: website/scripts/sync-architecture.mjs

Container topology

The compose file is the deployment truth, and it is where the dependency order actually lives: the engine waits for the logger, the API waits for the engine, the gateway waits for the API. The TLS edge is an optional profile, so a minimal install runs four containers instead of five.

6 declared services (1 behind a profile)
ServiceContainerBuildPortsWaits forNetwork
redisatf-redisredis:7.4.11-alpine3.21internal only—atf-net
loggeratf-loggerDockerfile.logger-rustinternal only—atf-net
coreatf-coreDockerfile.coreinternal onlyloggeratf-net
apiatf-apiDockerfile.api8080:8080coreatf-net
webatf-webDockerfile.web8088:8088apiatf-net
caddyatf-caddycaddy:2-alpine80:80 443:443webatf-net

38 environment keys are declared across the stack, and 5 service defines a healthcheck. The compose gate on this site also verifies that no credential is committed as a literal default — the one place it found fallback values is listed under open items on the atlas overview.

gRPC surface

One .proto file, 13 services, 78 methods and 141 message types — generated into Go stubs for the control plane and Python servicers for the engine. A mismatch cannot reach production silently: the call simply does not exist.

78 RPCs defined in proto/autoforward.proto
ServiceMethodsDomainSample methods
SessionControlService9 SessionListSessions StartLogin SubmitCode SubmitPassword
ForwardRuleControlService11 ForwardRuleListRules GetRule CreateRule UpdateRule
DeliveryControlService4 DeliveryGetDeliveryStats ListDeadLetter ReplayDeadLetter PurgeDeadLetter
FilterControlService4 FilterListFilters CreateFilter UpdateFilter DeleteFilter
AIControlService11 AIListAIConfigs CreateAIConfig UpdateAIConfig DeleteAIConfig
SystemStatusControlService3 SystemStatusGetSystemStats GetLogPolicy SetLogPolicy
AuditControlService1 AuditQueryAuditEvents
LogControlService4 LogLog QueryLogs LogStats PurgeLogs
BackupControlService2 BackupBackupExport BackupImport
AccountControlService8 AccountRegisterAccount LoginAccount ValidateToken IssueWebToken
AdminControlService11 AdminGetOverview ListUsers SetUserStatus Broadcast
BotTokenControlService5 BotTokenListBotTokens CreateBotToken DeleteBotToken GetBotDefaults
TaskControlService5 TaskCreateTask GetTask ListTasks CancelTask

Log vocabulary

63 distinct stage tags, 175 occurrences, parsed out of the engine's source. This is the vocabulary an operator greps for when something did not arrive — which is why the flows above quote these tags instead of inventing their own names.

PIPELINE:AI_REWRITE ×21PIPELINE:BRANDING ×18PIPELINE:DIALOG_FETCH ×14PIPELINE:CHAT_LIST ×8PIPELINE:DELIVERED ×7PIPELINE:DROP ×6PIPELINE:ROUTE ×6PIPELINE:FILTER_DROP ×5PIPELINE:TRANSFORM ×5PIPELINE:AUTO_PAUSE ×4PIPELINE:CLEANER ×4PIPELINE:POLICY ×4PIPELINE:DUP_FILTER ×3PIPELINE:FILTER ×3PIPELINE:KEYWORD_REPLY ×3PIPELINE:PAUSED ×3PIPELINE:RESTRICTED_BYPASS ×3PIPELINE:ADVANCED ×2PIPELINE:AUTO_DELETE ×2PIPELINE:CLEAN ×2PIPELINE:DISPATCH ×2PIPELINE:ENQUEUE ×2PIPELINE:FLOODWAIT ×2PIPELINE:LOOP_SKIP ×2PIPELINE:NORMALIZE ×2PIPELINE:NOTIFY ×2PIPELINE:POLICY_TARGET ×2PIPELINE:SYNC_EDIT_FILTER_DROP ×2PIPELINE:TIME_LIMITED ×2PIPELINE:ACCOUNT_BLOCKED ×1

Links that do not exist

The topology is defined as much by what is missing. Each of the following is a search over the checkout that came back empty on this build — a negative claim the site re-checks rather than asserts once.

Mobile speaks no gRPC

The mobile client never dials the engine directly: every call goes through the REST control plane.

searched: mobile/lib

No secrets in the browser bundle

Neither the API key, the master key nor the AI provider address is shipped to the browser.

searched: web/frontend/src

No label chosen by a language branch

A localised label is never picked by a hardcoded ternary — the catalogue lookup does it, and it falls back to English. (The language switcher itself still shows the target language natively, which is the point of a switcher.)

searched: core/infrastructure/telegram , core/application , atfcli

Two separate databases

The logger never opens the engine database — the log store is its own file.

searched: logger , rust/logger/src

The engine opens no HTTP port

The engine is reachable only over gRPC; there is no HTTP server inside the core.

searched: core

The links here are the runtime view. For the code-level view — which module imports which, and where the coupling is concentrated — open the dependency atlas, or go back to the atlas overview.