docs/PROJECT_ARCHITECTURE.md
This document is written for AI coding agents and maintainers who need to understand and modify this project safely. It focuses on where behavior lives, how the application starts, and which files are usually involved for common changes.
Qinglong is a timed task management platform. It provides a web admin panel for managing cron jobs, scripts, environment variables, subscriptions, dependencies, logs, configuration files, and system settings.
The repository is organized as a full-stack TypeScript application:
src/: frontend admin panel, built with Umi Max, React, Ant Design, and Ant Design Pro Layout.back/: backend application, built with Express, TypeScript, typedi, Sequelize, SQLite, gRPC, and worker processes.shell/: runtime shell scripts used to execute tasks and preload task environments.data/: local runtime data, including scripts, logs, configs, SQLite database, uploaded files, and cloned repositories.static/: built frontend and backend artifacts.docker/: Docker images, compose file, and entrypoint.sample/: sample scripts and default config templates.Browser
-> src/pages/*
-> src/utils/http.tsx
-> /api/*
-> back/api/*
-> back/services/*
-> back/data/* Sequelize models
-> data/db/database.sqlite
Cron/task execution
-> back/services/cron.ts
-> shell/task.sh or shell/otask.sh
-> data/scripts/*
-> data/log/*
Frontend assets in production
-> static/dist/*
-> served by back/loaders/express.ts
Development starts from package.json:
pnpm start
This runs:
start:back: nodemon ./back/app.tsstart:front: max devBackend startup begins in back/app.ts.
Important details:
cluster.Production-style backend output is generated by:
pnpm run build:back
The compiled backend is placed under static/build.
Frontend output is generated by:
pnpm run build:front
The compiled frontend is placed under static/dist.
back/app.tsResponsibilities:
back/loaders/app.tsback/loaders/express.tsback/loaders/db.tsback/loaders/depInjector.tsback/loaders/initData.tsback/loaders/initFile.tsback/loaders/initTask.tsback/loaders/server.tsback/loaders/sock.tsLoader responsibilities:
back/loaders/express.ts is the main HTTP middleware and routing setup. It handles:
/open/* rewrite to /api/*.back/api/index.ts.static/dist/index.html.back/api/index.tsThis file registers all API modules:
user.ts: login, initialization, authentication-related user endpoints.env.ts: environment variable endpoints.config.ts: config file endpoints.log.ts: log endpoints.cron.ts: cron/task endpoints.script.ts: script file endpoints.open.ts: open API/app token endpoints.dependence.ts: dependency management endpoints.system.ts: system information/settings endpoints.subscription.ts: subscription endpoints.update.ts: update/check endpoints.health.ts: health check endpoints.Route files should stay thin. They should validate input, get a service from typedi's Container, call the service, and return { code, data, message } style responses.
back/services/*Services contain most business logic. Common examples:
cron.ts: create/update/delete/run cron jobs, generate crontab data, manage logs, call scheduler client.env.ts: manage environment variables.config.ts: read/write config files.script.ts: manage script files.subscription.ts: manage script subscriptions and repository pulls.dependence.ts: install/manage runtime dependencies.system.ts: system info and settings.notify.ts: notification behavior.sock.ts: socket/log stream behavior.grpc.ts: gRPC server lifecycle.http.ts: HTTP server lifecycle.When changing backend behavior, first find the API route, then follow it into the matching service. In most cases, the service is the right place for behavioral changes.
back/data/index.tsback/data/*.tsThe backend uses Sequelize with SQLite. Database storage is configured in back/data/index.ts:
data/db/database.sqlite
Common model files:
cron.ts: cron job model.cronView.ts: saved cron table views.env.ts: environment variable model.dependence.ts: dependency model.open.ts: open API app/token model.subscription.ts: subscription model.system.ts: system settings model.notify.ts: notification-related data.Model sync and simple column migrations are currently handled in back/loaders/db.ts.
back/config/index.tsThis is the central runtime config file. It reads .env, establishes QL_DIR, and defines important paths:
dataPath: runtime data root.configPath: config files.scriptPath: user scripts.repoPath: subscription repositories.logPath: task logs.dbPath: SQLite database location.uploadPath: uploaded files.shellPath: shell runtime scripts.preloadPath: JS/Python/Shell preload files.Before hardcoding paths, check back/config/index.ts.
back/schedule/*back/protos/*back/services/grpc.tsThe project has two scheduling paths:
back/services/cron.ts decides whether a task needs the Node scheduler using schedule shape and extra_schedules.
back/shared/*back/config/util.tsback/config/share.tsback/config/http.tsUse these before adding new global helpers. Existing shared code includes:
.umirc.tsImportant behavior:
http://127.0.0.1:5700/.static/dist../api/env.js.QlBaseUrl affects frontend public path and routing base.src/app.tsResponsibilities:
QlBaseUrl as public path and router basename.src/layouts/defaultProps.tsxsrc/layouts/index.tsxdefaultProps.tsx defines the main route/menu list. If adding a new page visible in the sidebar, update this file.
Current major pages:
src/pages/crontab: timed task management.src/pages/subscription: subscription management.src/pages/env: environment variables.src/pages/config: config files.src/pages/script: script management.src/pages/dependence: dependency management.src/pages/log: log management.src/pages/diff: diff tool.src/pages/setting: system settings.src/pages/login: login.src/pages/initialization: first-run initialization.src/pages/error: error page.src/utils/http.tsx: API request helper.src/utils/websocket.ts: socket connection behavior.src/utils/config.ts: frontend config helpers.src/utils/const.ts: constants.src/utils/date.ts: date formatting helpers.src/utils/init.ts: initialization helpers.src/utils/codemirror/*: CodeMirror integration.src/utils/monaco/*: Monaco integration.When changing a page's API behavior, inspect both the page file and src/utils/http.tsx.
src/components/*: reusable UI components.src/pages/**/index.less: page-level styles.src/pages/script/index.module.less and src/pages/log/index.module.less: CSS module styles.src/assets/fonts/*: bundled fonts.src/locales/*.json: i18n text.Follow the existing Ant Design and Ant Design Pro patterns when modifying UI.
shell/task.sh: task execution path.shell/otask.sh: alternate/manual task execution path.shell/api.sh: shell-side API helpers.shell/env.sh: environment setup.shell/check.sh: runtime check helpers.shell/update.sh: update helpers.shell/rmlog.sh: log cleanup.shell/share.sh: shared shell helpers.shell/preload/*: preload files injected into JS/Python/Shell task environments.The backend often coordinates task execution, but the actual user script process environment is shaped by files in shell/.
data/This directory is runtime state, not just source code. Be careful when modifying or deleting files here.
Important subdirectories:
data/db: SQLite database.data/config: generated and user-edited config files.data/scripts: user scripts.data/repo: cloned subscription repositories.data/log: task logs.data/upload: uploaded files.data/syslog: system logs.data/ssh.d: SSH-related runtime data.data/dep_cache: dependency cache, when present.Many bugs that appear as "backend logic" may involve state stored under data/.
docker/Dockerfiledocker/310.Dockerfiledocker/docker-compose.ymldocker/docker-entrypoint.shecosystem.config.jsversion.yamlUse these when changing deployment, container startup, PM2 behavior, or release metadata.
Typical files:
back/api/<module>.ts.back/services/<module>.ts.back/data/<module>.ts if persistence changes.celebrate/Joi near the route.src/pages/** or src/utils/**.Typical files:
src/pages/<page>/index.tsx.src/pages/<page>/index.less if needed.src/layouts/defaultProps.tsx.src/locales/zh-CN.json and src/locales/en-US.json.Start with:
back/api/cron.tsback/services/cron.tsback/schedule/*shell/task.shshell/otask.shshell/preload/*Also inspect:
back/data/cron.tsback/validation/schedule.tsdata/config/crontab.listdata/log/*Start with:
back/api/env.tsback/services/env.tsback/data/env.tssrc/pages/env/index.tsxAlso inspect:
shell/preload/env.shshell/preload/env.jsshell/preload/env.pyStart with:
back/api/script.tsback/services/script.tssrc/pages/script/index.tsxdata/scripts/*Start with:
back/api/user.tsback/services/user.tsback/shared/auth.tsback/shared/store.tsback/loaders/express.tsback/token.tssrc/pages/login/index.tsxsrc/pages/initialization/index.tsxBe careful with:
Start with:
back/api/subscription.tsback/services/subscription.tsback/data/subscription.tssrc/pages/subscription/index.tsxdata/repo/*Start with:
back/api/dependence.tsback/services/dependence.tsback/data/dependence.tssrc/pages/dependence/index.tsxdata/depsdata/dep_cacheStart with:
back/api/log.tsback/services/log.tsback/services/sock.tsback/shared/logStreamManager.tssrc/pages/log/index.tsxsrc/components/terminal.tsxdata/log/*Backend:
typedi services consistently.back/config/index.ts.{ code, data, message } shape.Frontend:
src/layouts/defaultProps.tsx.Shell/runtime:
shell/ as part of production behavior.Data:
data/ as mutable runtime state.When asked to modify behavior:
src/pages, back/api, and back/services.back/data model and back/loaders/db.ts.shell/ and back/services/cron.ts.pnpm run build:back for backend TypeScript changes.pnpm run build:front for frontend build changes..
├── back/ Backend TypeScript application
│ ├── api/ Express route modules
│ ├── config/ Runtime config, paths, constants, helpers
│ ├── data/ Sequelize models and SQLite connection
│ ├── loaders/ Startup initialization and Express setup
│ ├── middlewares/ Express middlewares
│ ├── protos/ gRPC proto files and generated TS
│ ├── schedule/ Scheduler/gRPC client helpers
│ ├── services/ Business logic services
│ ├── shared/ Shared backend utilities
│ └── validation/ Joi validation schemas
├── src/ Frontend Umi/React application
│ ├── assets/ Fonts and static frontend assets
│ ├── components/ Shared UI components
│ ├── hooks/ Frontend hooks
│ ├── layouts/ Main layout and menu route config
│ ├── locales/ i18n JSON
│ ├── pages/ Feature pages
│ └── utils/ HTTP, WebSocket, editor, date, and config utilities
├── shell/ Task runtime shell scripts and preload files
├── data/ Runtime state: db, logs, scripts, repos, configs
├── docker/ Docker build and compose files
├── sample/ Sample scripts and default config templates
├── static/ Built frontend/backend artifacts
└── docs/ Project documentation