> For the complete documentation index, see [llms.txt](https://vitrina-blogerov.gitbook.io/bloggers-showcase/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://vitrina-blogerov.gitbook.io/bloggers-showcase/product-docs/product-docs-en/architecture/overall-system-diagram.md).

# Overall system diagram

{% hint style="info" %}
The platform consists of a shared edge layer and several independent language versions of the application. Each language version is deployed as a separate stack with its own backend, Telegram bot, database, files, and configuration. This approach makes it possible to install, update, and administer versions independently of one another.
{% endhint %}

Incoming HTTP traffic is handled by Caddy. It serves shared static assets and error pages, determines the required language version, and proxies requests to the appropriate backend. Interaction with the Telegram Bot API, AI providers, and publication channels is performed directly from the backend and bot containers. Separate server utilities are used for installation, updates, backups, and removal.

### Users, edge layer, and routing

```mermaid
%%{init: {"flowchart": {"curve": "linear", "nodeSpacing": 30, "rankSpacing": 45, "padding": 24}, "themeVariables": {"fontSize": "22px"}}}%%
flowchart TB
  classDef default fill:#3f3f46,stroke:#71717a,stroke-width:2px,color:#ffffff,font-size:22px

  Browser["User browser"]
  TgMobile["Telegram Mini App<br/>mobile"]
  TgDesktop["Telegram Mini App<br/>desktop"]
  TgWeb["Telegram Web<br/>Mini App"]
  AdminBrowser["Administrator browser"]

  PublicEntry["Public request entry"]
  EdgeCaddy["edge container<br/>Caddy 2"]

  RedirectPage["/opt/bloggers_platform/edge/www/index.html<br/>language-version selection page"]

  LanguageSelection["Selection priority<br/>1. Telegram language<br/>2. Browser language<br/>3. fallback: en, zh, ar, ru"]

  BackendRoutes["Caddy language routes"]

  RUBackend["backend_ru<br/>FastAPI + storefront<br/>admin + API"]
  ENBackend["backend_en<br/>FastAPI + storefront<br/>admin + API"]
  ZHBackend["backend_zh<br/>FastAPI + storefront<br/>admin + API"]
  ARBackend["backend_ar<br/>FastAPI + storefront<br/>admin + API"]

  ErrorPages["/opt/bloggers_platform/edge/www/errors<br/>403 / 404 / 502"]
  EdgeAssets["/opt/bloggers_platform/edge/www/assets<br/>style.css / bg.mp4"]
  EdgeConfig["/opt/bloggers_platform/edge/Caddyfile"]
  EdgeCompose["/opt/bloggers_platform/edge/docker-compose.yml"]
  EdgeNetwork["Docker network<br/>bloggers_edge"]

  Browser -->|"https://domain/"| PublicEntry
  TgMobile -->|"Mini App URL"| PublicEntry
  TgDesktop -->|"Mini App URL"| PublicEntry
  TgWeb -->|"Mini App iframe"| PublicEntry
  AdminBrowser -->|"https://domain/bloggers/{lang}/admin"| PublicEntry

  PublicEntry --> EdgeCaddy

  EdgeCaddy -->|"root /"| RedirectPage
  RedirectPage --> LanguageSelection
  LanguageSelection -->|"redirected request"| BackendRoutes

  EdgeCaddy -->|"direct /bloggers/{lang} request"| BackendRoutes

  BackendRoutes -->|"/bloggers/ru/*"| RUBackend
  BackendRoutes -->|"/bloggers/en/*"| ENBackend
  BackendRoutes -->|"/bloggers/zh/*"| ZHBackend
  BackendRoutes -->|"/bloggers/ar/*"| ARBackend

  EdgeCaddy -->|"/errors/* and 403 / 404 / 502"| ErrorPages
  EdgeCaddy -->|"/assets/*"| EdgeAssets

  EdgeCaddy --- EdgeConfig
  EdgeCaddy --- EdgeCompose
  EdgeCaddy --- EdgeNetwork

  EdgeNetwork --- RUBackend
  EdgeNetwork --- ENBackend
  EdgeNetwork --- ZHBackend
  EdgeNetwork --- ARBackend

  linkStyle default stroke:#9ca3af,stroke-width:2px
```

All user HTTP requests go to the shared Caddy container. This applies to a regular browser, the Telegram Mini App on mobile and desktop clients, Telegram Web, as well as the admin panel. Caddy acts as a single entry point and hides the internal container structure from the external client.

{% hint style="info" %}
When the root address is opened, the server redirects the user to the language-version selection page. First, the Telegram language is taken into account, then the browser language. If no suitable version can be determined, a fixed fallback order is used. After the language is identified, the request is redirected to the corresponding /bloggers/{lang} path and passed to the appropriate backend through the shared Docker network.
{% endhint %}

Caddy also serves shared static assets and error pages. Its configuration, Docker Compose file, and utility files are stored separately from the language applications, so the edge layer can be changed without rebuilding each stack.

### Internal structure of language versions

```mermaid
%%{init: {"flowchart": {"curve": "linear", "nodeSpacing": 28, "rankSpacing": 42, "padding": 24}, "themeVariables": {"fontSize": "22px"}}}%%
flowchart TB
  classDef default fill:#3f3f46,stroke:#71717a,stroke-width:2px,color:#ffffff,font-size:22px

  subgraph RU["RU stack: /opt/bloggers_platform/apps/ru"]
    direction LR

    RUBackend["backend_ru<br/>FastAPI + storefront<br/>admin + API"]
    RUBot["bot_ru<br/>aiogram polling"]
    RUDB[("PostgreSQL ru<br/>bloggers_db")]
    RUAssets["assets ru<br/>photos, media, icons"]

    RUBackend -->|"HTML storefront, admin panel, /api/*"| RUDB
    RUBackend -->|"uploaded files"| RUAssets
    RUBot -->|"settings, users, posts, welcome, AI config"| RUDB
  end

  subgraph EN["EN stack: /opt/bloggers_platform/apps/en"]
    direction LR

    ENBackend["backend_en<br/>FastAPI + storefront<br/>admin + API"]
    ENBot["bot_en<br/>aiogram polling"]
    ENDB[("PostgreSQL en<br/>bloggers_db")]
    ENAssets["assets en<br/>photos, media, icons"]

    ENBackend -->|"HTML storefront, admin panel, /api/*"| ENDB
    ENBackend -->|"uploaded files"| ENAssets
    ENBot -->|"settings, users, posts, welcome, AI config"| ENDB
  end

  subgraph ZH["ZH stack: /opt/bloggers_platform/apps/zh"]
    direction LR

    ZHBackend["backend_zh<br/>FastAPI + storefront<br/>admin + API"]
    ZHBot["bot_zh<br/>aiogram polling"]
    ZHDB[("PostgreSQL zh<br/>bloggers_db")]
    ZHAssets["assets zh<br/>photos, media, icons"]

    ZHBackend -->|"HTML storefront, admin panel, /api/*"| ZHDB
    ZHBackend -->|"uploaded files"| ZHAssets
    ZHBot -->|"settings, users, posts, welcome, AI config"| ZHDB
  end

  subgraph AR["AR stack: /opt/bloggers_platform/apps/ar"]
    direction LR

    ARBackend["backend_ar<br/>FastAPI + storefront<br/>admin + API"]
    ARBot["bot_ar<br/>aiogram polling"]
    ARDB[("PostgreSQL ar<br/>bloggers_db")]
    ARAssets["assets ar<br/>photos, media, icons"]

    ARBackend -->|"HTML storefront, admin panel, /api/*"| ARDB
    ARBackend -->|"uploaded files"| ARAssets
    ARBot -->|"settings, users, posts, welcome, AI config"| ARDB
  end

  style RU fill:none,stroke:#71717a,stroke-width:1px
  style EN fill:none,stroke:#71717a,stroke-width:1px
  style ZH fill:none,stroke:#71717a,stroke-width:1px
  style AR fill:none,stroke:#71717a,stroke-width:1px

  linkStyle default stroke:#9ca3af,stroke-width:2px
```

Each language version is a self-contained set of services. The stack includes a FastAPI backend, an aiogram Telegram bot, PostgreSQL, and a directory for uploaded files. Version settings are stored in a separate .env file, which specifies the application language and the public base path.

The backend serves the storefront, the admin panel, and the API. User, post, settings, and content data are stored in a separate database for that specific language version. Media files and icons are stored in the file directory of the same stack.

The Telegram bot uses the same database as the backend. As a result, changes to settings, users, welcome messages, and AI configuration are available to both services without additional synchronization between different storage systems.

### Telegram bot API

```mermaid
%%{init: {"flowchart": {"curve": "linear", "nodeSpacing": 30, "rankSpacing": 45, "padding": 24}, "themeVariables": {"fontSize": "22px"}}}%%
flowchart TB
  classDef default fill:#3f3f46,stroke:#71717a,stroke-width:2px,color:#ffffff,font-size:22px

  AdminTelegram["Administrator in Telegram bot"]

  RUBot["bot_ru<br/>aiogram polling"]
  ENBot["bot_en<br/>aiogram polling"]
  ZHBot["bot_zh<br/>aiogram polling"]
  ARBot["bot_ar<br/>aiogram polling"]

  TelegramAPI["Telegram Bot API"]

  PublishBus["Channel publication requests"]

  TelegramChannel["Telegram channel<br/>for publications"]

  RUBot <-->|"polling / messages to API<br/>updates from API"| TelegramAPI
  ENBot <-->|"polling / messages to API<br/>updates from API"| TelegramAPI
  ZHBot <-->|"polling / messages to API<br/>updates from API"| TelegramAPI
  ARBot <-->|"polling / messages to API<br/>updates from API"| TelegramAPI

  RUBot -->|"channel posts"| PublishBus
  ENBot -->|"channel posts"| PublishBus
  ZHBot -->|"channel posts"| PublishBus
  ARBot -->|"channel posts"| PublishBus

  PublishBus --> TelegramChannel

  AdminTelegram -->|"admin bot commands"| TelegramAPI

  linkStyle default stroke:#9ca3af,stroke-width:2px
```

Each language stack includes a separate Telegram bot with its own token and settings. The bots run in polling mode: they send requests to the Telegram Bot API, receive updates, and process user or admin commands.

Publishing to the Telegram channel is also done through the corresponding language bot. Content is created within a specific version of the platform, after which the bot sends the prepared message to the configured channel.

Administrator commands go through the same Telegram Bot API. Access to administrative operations is restricted by the settings of the specific bot and the authorization rules implemented in the application.

### Administration and artificial intelligence service providers

```mermaid
%%{init: {"flowchart": {"curve": "linear", "nodeSpacing": 30, "rankSpacing": 45, "padding": 24}, "themeVariables": {"fontSize": "22px"}}}%%
flowchart TB
  classDef default fill:#3f3f46,stroke:#71717a,stroke-width:2px,color:#ffffff,font-size:22px

  AdminBrowser["Administrator browser"]
  AdminAPI["JWT admin API requests"]

  RUBackend["backend_ru"]
  ENBackend["backend_en"]
  ZHBackend["backend_zh"]
  ARBackend["backend_ar"]

  RUBot["bot_ru"]
  ENBot["bot_en"]
  ZHBot["bot_zh"]
  ARBot["bot_ar"]

  BackendAI["Backend AI search requests"]
  BotAI["Bot AI consultant requests"]

  AIProviders["AI providers<br/>OpenAI / Groq / Gemini / OpenRouter"]

  AdminBrowser --> AdminAPI

  AdminAPI -->|"JWT admin API"| RUBackend
  AdminAPI -->|"JWT admin API"| ENBackend
  AdminAPI -->|"JWT admin API"| ZHBackend
  AdminAPI -->|"JWT admin API"| ARBackend

  RUBackend -->|"AI search"| BackendAI
  ENBackend -->|"AI search"| BackendAI
  ZHBackend -->|"AI search"| BackendAI
  ARBackend -->|"AI search"| BackendAI

  BackendAI --> AIProviders

  RUBot -->|"AI consultant"| BotAI
  ENBot -->|"AI consultant"| BotAI
  ZHBot -->|"AI consultant"| BotAI
  ARBot -->|"AI consultant"| BotAI

  BotAI --> AIProviders

  linkStyle default stroke:#9ca3af,stroke-width:2px
```

Web administration is performed through the backend of the selected language version. After authentication, the administrator's browser accesses the protected API using JWT. Each backend works only with its own database and does not modify data from other language stacks.

The backend uses external AI providers for search and data processing functions. Telegram bots access the same providers to operate the AI consultant. The specific provider and connection parameters are determined by the language version's configuration.

Separating backend and Telegram bot requests makes it possible to manage user scenarios independently. At the same time, the credentials and AI service parameters remain part of the configuration of the specific application.

### Installation and updates

```mermaid
%%{init: {"flowchart": {"curve": "linear", "nodeSpacing": 30, "rankSpacing": 45, "padding": 24}, "themeVariables": {"fontSize": "22px"}}}%%
flowchart TB
  classDef default fill:#3f3f46,stroke:#71717a,stroke-width:2px,color:#ffffff,font-size:22px

  Installer["install.sh<br/>installs or updates one language version"]

  PlatformManager["/opt/bloggers_platform/manager.sh<br/>edge regeneration, status, logs"]

  Delivery["deliveri.solodolik.com<br/>install.sh, version archives, error pages"]
  TelegramAPI["Telegram Bot API"]

  AppsRoot["/opt/bloggers_platform/apps<br/>language-version stacks"]

  EdgeRoot["/opt/bloggers_platform/edge<br/>shared edge layer"]

  EnvWriter["Write language .env file"]

  RUEnv["apps/ru/.env<br/>APP_LANGUAGE=ru<br/>PUBLIC_BASE_PATH=/bloggers/ru"]

  ENEnv["apps/en/.env<br/>APP_LANGUAGE=en<br/>PUBLIC_BASE_PATH=/bloggers/en"]

  ZHEnv["apps/zh/.env<br/>APP_LANGUAGE=zh<br/>PUBLIC_BASE_PATH=/bloggers/zh"]

  AREnv["apps/ar/.env<br/>APP_LANGUAGE=ar<br/>PUBLIC_BASE_PATH=/bloggers/ar"]

  Installer -->|"downloads selected archive by install token"| Delivery

  Installer -->|"creates / updates apps/{lang}"| AppsRoot

  Installer --> EnvWriter

  EnvWriter -->|"writes .env"| RUEnv
  EnvWriter -->|"writes .env"| ENEnv
  EnvWriter -->|"writes .env"| ZHEnv
  EnvWriter -->|"writes .env"| AREnv

  Installer -->|"creates shared edge"| EdgeRoot
  Installer -->|"setChatMenuButton"| TelegramAPI

  PlatformManager -->|"regenerates Caddyfile and redirect page"| EdgeRoot

  linkStyle default stroke:#9ca3af,stroke-width:2px
```

The main installation and update are performed by the install.sh script. The script downloads the archive of the selected version from the delivery server, checks the installation token, and creates or updates the apps/{lang} directory. After that, it writes the language version settings to .env and starts the required containers.

During the initial installation, a shared edge layer is also created. For the Telegram bot, a Mini App launch button is configured using the setChatMenuButton method. This makes it possible to perform a basic platform deployment without manually editing Docker Compose and Caddy configuration.

The manager.sh utility manages the platform's shared components. It rebuilds the Caddyfile and the language redirect page based on the versions actually installed, and also provides commands for viewing the status and logs of the edge layer.

### Management, backup, and removal

```mermaid
%%{init: {"flowchart": {"curve": "linear", "nodeSpacing": 30, "rankSpacing": 45, "padding": 24}, "themeVariables": {"fontSize": "22px"}}}%%
flowchart TB
  classDef default fill:#3f3f46,stroke:#71717a,stroke-width:2px,color:#ffffff,font-size:22px

  ContentManager["/opt/bloggers_platform/content.sh<br/>backup, restore, content export"]

  AppManager["apps/{lang}/manager.sh<br/>status, logs, restart, backup, update"]

  Uninstaller["/opt/bloggers_platform/uninstall.sh<br/>complete platform removal"]

  RUDB[("PostgreSQL ru<br/>bloggers_db")]
  ENDB[("PostgreSQL en<br/>bloggers_db")]
  ZHDB[("PostgreSQL zh<br/>bloggers_db")]
  ARDB[("PostgreSQL ar<br/>bloggers_db")]

  RUStack["RU stack<br/>/opt/bloggers_platform/apps/ru"]
  ENStack["EN stack<br/>/opt/bloggers_platform/apps/en"]
  ZHStack["ZH stack<br/>/opt/bloggers_platform/apps/zh"]
  ARStack["AR stack<br/>/opt/bloggers_platform/apps/ar"]

  Platform["/opt/bloggers_platform"]

  Backups["/opt/bloggers_platform/backups<br/>manual, temp, exports"]

  ContentManager -->|"backup / restore / export content"| RUDB
  ContentManager -->|"backup / restore / export content"| ENDB
  ContentManager -->|"backup / restore / export content"| ZHDB
  ContentManager -->|"backup / restore / export content"| ARDB

  ContentManager -->|"stores backups"| Backups

  AppManager -->|"docker compose controls app stack"| RUStack
  AppManager -->|"docker compose controls app stack"| ENStack
  AppManager -->|"docker compose controls app stack"| ZHStack
  AppManager -->|"docker compose controls app stack"| ARStack

  Uninstaller -->|"stops containers, removes apps, edge, volumes"| Platform
  Uninstaller -->|"pre-removal backup"| Backups

  linkStyle default stroke:#9ca3af,stroke-width:2px
```

To manage a separate language version, the apps/{lang}/manager.sh script is used. Through it, you can check container status, view logs, restart the stack, create a backup, or perform an update. The commands apply only to the selected language and do not affect the other versions.

Content operations are performed via content.sh. The utility creates database backups, restores data, and exports the content of language versions. The resulting archives are saved in the shared /opt/bloggers\_platform/backups directory.

Complete platform removal is performed by the uninstall.sh script. Before removal, it can create a backup, after which it stops the containers and removes the applications, the edge layer, and the associated Docker volumes.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://vitrina-blogerov.gitbook.io/bloggers-showcase/product-docs/product-docs-en/architecture/overall-system-diagram.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
