# evanray-team/xray-image-server architecture

> Architecture diagram of the GitHub repository evanray-team/xray-image-server, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-10-01). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/evanray-team/xray-image-server
- Repository: https://github.com/evanray-team/xray-image-server

## Overview

Xray Image Server accepts HTTP requests and produces PNGs from registered image templates, with rendering dispatched through a worker pool. Its main product branches are maimai music/player imagery and the themed constant-table background pipeline. Shared rendering handles validation, fonts, SVG generation and rasterization; game logic and asset access support the domain templates. The README documents optional PostgreSQL/OSS-backed online assets. Some links are limited to imports and README statements because several runtime modules were not excerpted.

Main entry points: [`core/render-template.ts`](https://github.com/evanray-team/xray-image-server/blob/main/core/render-template.ts) (Template engine), [`core/index.ts`](https://github.com/evanray-team/xray-image-server/blob/main/core/index.ts) (Server startup), [`core/asset.ts`](https://github.com/evanray-team/xray-image-server/blob/main/core/asset.ts) (Asset manager), [`core/mai-logic.ts`](https://github.com/evanray-team/xray-image-server/blob/main/core/mai-logic.ts) (Game logic)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_http["HTTP service"]
  node_server["Server startup<br/>[index.ts]"]
  node_render_api["Render endpoint<br/>[render.post.ts]"]
  node_ping_api["Ping endpoint<br/>[ping.get.ts]"]
  node_logger["Logging<br/>[logger.ts]"]
end

subgraph group_render["Render runtime"]
  node_render_service["Render service<br/>[render-service.ts]"]
  node_worker_pool["Worker pool<br/>[worker-pool.ts]"]
  node_worker["Render worker<br/>[render-worker.ts]"]
  node_worker_protocol["Worker protocol<br/>[worker-types.ts]"]
  node_template_engine["Template engine<br/>[render-template.ts]"]
  node_config["Configuration<br/>[config.ts]"]
end

subgraph group_mai["Maimai imagery"]
  node_mai_music["Music info image<br/>[maiMusicInfo.tsx]"]
  node_mai_best50["Best 50 image"]
  node_mai_records["Music record image"]
  node_mai_collection["Collection status"]
  node_mai_scores["Score list image"]
  node_mai_logic["Game logic<br/>[mai-logic.ts]"]
  node_mai_constants["Game constants<br/>[mai-constants.ts]"]
  node_table_template["Constant table"]
  node_table_background["Table background"]
  node_theme_registry["Theme registry<br/>[theme-index.tsx]"]
  node_theme_modules["Table themes"]
  node_credits["Theme credits<br/>[theme-credits.tsx]"]
end

subgraph group_assets["Assets and data"]
  node_assets_manager["Asset manager<br/>[asset.ts]"]
  node_database[("SQL database")]
  node_oss["Tencent COS"]
end

node_client(("HTTP client"))

node_client -->|"requests render"| node_render_api
node_client -->|"checks health"| node_ping_api
node_server -->|"initializes"| node_render_service
node_server -->|"registers"| node_ping_api
node_server -->|"registers"| node_render_api
node_render_service -->|"initializes pool"| node_worker_pool
node_worker_pool -->|"creates worker"| node_worker
node_worker_pool -->|"uses messages"| node_worker_protocol
node_worker -->|"uses messages"| node_worker_protocol
node_worker -->|"renders with"| node_template_engine
node_template_engine -->|"loads fonts"| node_assets_manager
node_render_api -.->|"dispatches render"| node_render_service
node_mai_music -->|"defines template"| node_template_engine
node_mai_best50 -->|"defines template"| node_template_engine
node_mai_records -->|"defines template"| node_template_engine
node_mai_collection -->|"defines template"| node_template_engine
node_mai_scores -->|"defines template"| node_template_engine
node_mai_music -->|"uses game logic"| node_mai_logic
node_mai_records -->|"uses game logic"| node_mai_logic
node_mai_best50 -->|"uses game logic"| node_mai_logic
node_mai_scores -->|"uses game logic"| node_mai_logic
node_mai_music -->|"uses constants"| node_mai_constants
node_mai_records -->|"uses constants"| node_mai_constants
node_table_template -->|"defines template"| node_template_engine
node_table_background -->|"prepares theme"| node_theme_registry
node_theme_registry -->|"dispatches themes"| node_theme_modules
node_theme_modules -->|"loads credits"| node_credits
node_theme_modules -->|"loads imagery"| node_assets_manager
node_mai_logic -->|"loads covers"| node_assets_manager
node_assets_manager -.->|"reads asset records"| node_database
node_assets_manager -->|"downloads remote images"| node_oss
node_server -->|"configures logging"| node_logger
node_server -->|"uses configuration"| node_config
node_worker -->|"loads configuration"| node_config

click node_server "https://github.com/evanray-team/xray-image-server/blob/main/core/index.ts"
click node_render_api "https://github.com/evanray-team/xray-image-server/blob/main/apis/render.post.ts"
click node_ping_api "https://github.com/evanray-team/xray-image-server/blob/main/apis/ping.get.ts"
click node_render_service "https://github.com/evanray-team/xray-image-server/blob/main/core/render-service.ts"
click node_worker_pool "https://github.com/evanray-team/xray-image-server/blob/main/core/worker-pool.ts"
click node_worker "https://github.com/evanray-team/xray-image-server/blob/main/core/render-worker.ts"
click node_worker_protocol "https://github.com/evanray-team/xray-image-server/blob/main/core/worker-types.ts"
click node_template_engine "https://github.com/evanray-team/xray-image-server/blob/main/core/render-template.ts"
click node_mai_music "https://github.com/evanray-team/xray-image-server/blob/main/templates/maiMusicInfo.tsx"
click node_mai_best50 "https://github.com/evanray-team/xray-image-server/blob/main/templates/maiPlayerBest50.tsx"
click node_mai_records "https://github.com/evanray-team/xray-image-server/blob/main/templates/maiPlayerMusicRecord.tsx"
click node_mai_collection "https://github.com/evanray-team/xray-image-server/blob/main/templates/maiPlayerCollectionStatus.tsx"
click node_mai_scores "https://github.com/evanray-team/xray-image-server/blob/main/templates/maiPlayerScoreList.tsx"
click node_mai_logic "https://github.com/evanray-team/xray-image-server/blob/main/core/mai-logic.ts"
click node_mai_constants "https://github.com/evanray-team/xray-image-server/blob/main/core/mai-constants.ts"
click node_table_template "https://github.com/evanray-team/xray-image-server/blob/main/templates/maiConstantTable.tsx"
click node_table_background "https://github.com/evanray-team/xray-image-server/blob/main/templates/maiConstantTableBackground.tsx"
click node_theme_registry "https://github.com/evanray-team/xray-image-server/blob/main/templates/maiConstantTableTheme/theme-index.tsx"
click node_theme_modules "https://github.com/evanray-team/xray-image-server/tree/main/templates/maiConstantTableTheme"
click node_credits "https://github.com/evanray-team/xray-image-server/blob/main/templates/maiConstantTableTheme/theme-credits.tsx"
click node_assets_manager "https://github.com/evanray-team/xray-image-server/blob/main/core/asset.ts"
click node_config "https://github.com/evanray-team/xray-image-server/blob/main/core/config.ts"
click node_logger "https://github.com/evanray-team/xray-image-server/blob/main/core/logger.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_server,node_render_api,node_ping_api,node_logger,node_client toneBlue
class node_render_service,node_worker_pool,node_worker,node_worker_protocol,node_template_engine,node_config toneAmber
class node_mai_music,node_mai_best50,node_mai_records,node_mai_collection,node_mai_scores,node_mai_logic,node_mai_constants,node_table_template,node_table_background,node_theme_registry,node_theme_modules,node_credits toneMint
class node_assets_manager,node_database,node_oss toneRose
```

## Components

### HTTP service

- [Server startup](https://github.com/evanray-team/xray-image-server/blob/main/core/index.ts): `core/index.ts`
- [Render endpoint](https://github.com/evanray-team/xray-image-server/blob/main/apis/render.post.ts): `apis/render.post.ts`
- [Ping endpoint](https://github.com/evanray-team/xray-image-server/blob/main/apis/ping.get.ts): `apis/ping.get.ts`
- [Logging](https://github.com/evanray-team/xray-image-server/blob/main/core/logger.ts): `core/logger.ts`

### Render runtime

- [Render service](https://github.com/evanray-team/xray-image-server/blob/main/core/render-service.ts): `core/render-service.ts`
- [Worker pool](https://github.com/evanray-team/xray-image-server/blob/main/core/worker-pool.ts): `core/worker-pool.ts`
- [Render worker](https://github.com/evanray-team/xray-image-server/blob/main/core/render-worker.ts): `core/render-worker.ts`
- [Worker protocol](https://github.com/evanray-team/xray-image-server/blob/main/core/worker-types.ts): `core/worker-types.ts`
- [Template engine](https://github.com/evanray-team/xray-image-server/blob/main/core/render-template.ts): `core/render-template.ts`
- [Configuration](https://github.com/evanray-team/xray-image-server/blob/main/core/config.ts): `core/config.ts`

### Maimai imagery

- [Music info image](https://github.com/evanray-team/xray-image-server/blob/main/templates/maiMusicInfo.tsx): `templates/maiMusicInfo.tsx`
- [Best 50 image](https://github.com/evanray-team/xray-image-server/blob/main/templates/maiPlayerBest50.tsx): `templates/maiPlayerBest50.tsx`
- [Music record image](https://github.com/evanray-team/xray-image-server/blob/main/templates/maiPlayerMusicRecord.tsx): `templates/maiPlayerMusicRecord.tsx`
- [Collection status](https://github.com/evanray-team/xray-image-server/blob/main/templates/maiPlayerCollectionStatus.tsx): `templates/maiPlayerCollectionStatus.tsx`
- [Score list image](https://github.com/evanray-team/xray-image-server/blob/main/templates/maiPlayerScoreList.tsx): `templates/maiPlayerScoreList.tsx`
- [Game logic](https://github.com/evanray-team/xray-image-server/blob/main/core/mai-logic.ts): `core/mai-logic.ts`
- [Game constants](https://github.com/evanray-team/xray-image-server/blob/main/core/mai-constants.ts): `core/mai-constants.ts`
- [Constant table](https://github.com/evanray-team/xray-image-server/blob/main/templates/maiConstantTable.tsx): `templates/maiConstantTable.tsx`
- [Table background](https://github.com/evanray-team/xray-image-server/blob/main/templates/maiConstantTableBackground.tsx): `templates/maiConstantTableBackground.tsx`
- [Theme registry](https://github.com/evanray-team/xray-image-server/blob/main/templates/maiConstantTableTheme/theme-index.tsx): `templates/maiConstantTableTheme/theme-index.tsx`
- [Table themes](https://github.com/evanray-team/xray-image-server/tree/main/templates/maiConstantTableTheme): `templates/maiConstantTableTheme`
- [Theme credits](https://github.com/evanray-team/xray-image-server/blob/main/templates/maiConstantTableTheme/theme-credits.tsx): `templates/maiConstantTableTheme/theme-credits.tsx`

### Assets and data

- [Asset manager](https://github.com/evanray-team/xray-image-server/blob/main/core/asset.ts): `core/asset.ts`
- **SQL database**
- **Tencent COS**

### Other components

- **HTTP client**

## Connections

- HTTP client → Render endpoint: requests render (evidence: `README.md`)
- HTTP client → Ping endpoint: checks health (evidence: `apis/ping.get.ts`)
- Server startup → Render service: initializes (evidence: `core/index.ts`)
- Server startup → Ping endpoint: registers (evidence: `core/index.ts`)
- Server startup → Render endpoint: registers (evidence: `core/index.ts`)
- Render service → Worker pool: initializes pool (evidence: `core/render-service.ts`)
- Worker pool → Render worker: creates worker (evidence: `core/worker-pool.ts`)
- Worker pool → Worker protocol: uses messages (evidence: `core/worker-pool.ts`)
- Render worker → Worker protocol: uses messages (evidence: `core/worker-types.ts`)
- Render worker → Template engine: renders with (evidence: `core/render-worker.ts`)
- Template engine → Asset manager: loads fonts (evidence: `core/render-template.ts`)
- Render endpoint → Render service: dispatches render
- Music info image → Template engine: defines template (evidence: `templates/maiMusicInfo.tsx`)
- Best 50 image → Template engine: defines template (evidence: `templates/maiPlayerBest50.tsx`)
- Music record image → Template engine: defines template (evidence: `templates/maiPlayerMusicRecord.tsx`)
- Collection status → Template engine: defines template (evidence: `templates/maiPlayerCollectionStatus.tsx`)
- Score list image → Template engine: defines template (evidence: `templates/maiPlayerScoreList.tsx`)
- Music info image → Game logic: uses game logic (evidence: `templates/maiMusicInfo.tsx`)
- Music record image → Game logic: uses game logic (evidence: `templates/maiPlayerMusicRecord.tsx`)
- Best 50 image → Game logic: uses game logic (evidence: `templates/maiPlayerBest50.tsx`)
- Score list image → Game logic: uses game logic (evidence: `templates/maiPlayerScoreList.tsx`)
- Music info image → Game constants: uses constants (evidence: `templates/maiMusicInfo.tsx`)
- Music record image → Game constants: uses constants (evidence: `templates/maiPlayerMusicRecord.tsx`)
- Constant table → Template engine: defines template (evidence: `templates/maiConstantTable.tsx`)
- Table background → Theme registry: prepares theme (evidence: `templates/maiConstantTableBackground.tsx`)
- Theme registry → Table themes: dispatches themes (evidence: `templates/maiConstantTableTheme/theme-index.tsx`)
- Table themes → Theme credits: loads credits (evidence: `templates/maiConstantTableTheme/theme-magical.tsx`)
- Table themes → Asset manager: loads imagery (evidence: `templates/maiConstantTableTheme/theme-credits.tsx`)
- Game logic → Asset manager: loads covers (evidence: `core/mai-logic.ts`)
- Asset manager → SQL database: reads asset records
- Asset manager → Tencent COS: downloads remote images (evidence: `core/asset.ts`)
- Server startup → Logging: configures logging (evidence: `core/index.ts`)
- Server startup → Configuration: uses configuration (evidence: `core/index.ts`)
- Render worker → Configuration: loads configuration (evidence: `core/render-worker.ts`)
