mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-04 03:44:22 +00:00
28f7690224
The architecture/code map previously lived in .claude/CLAUDE.md, which was gitignored (local-only) and auto-loaded into every agent session alongside the root CLAUDE.md. Track it in docs/architecture.md instead and reference it from CLAUDE.md so it is read on demand. While moving it, fact-check the whole map against the current tree: - add the missing internal/eventbus and internal/tunnelmonitor packages, the service/email subpackage, and util/wirecodec - document node mTLS (tls_client.go, node_mtls.go, setting_mtls.go) and the fourth TLS verify mode - add the Host, ClientExternalLink, NodeClientIp and ClientGlobalTraffic models plus their symptom-index rows - correct the cron table (check_cpu_usage is 1m not 10s; add check_memory_usage and free_os_memory), the middleware chain (MaxBodyBytes, ConfigEnvelope, CSRF) and the controller route prefixes - refresh the sub/ and service/ file listings, frontend pages (hosts/, index/), CI workflow list, and replace stale exact line counts with rounded sizes
6.1 KiB
6.1 KiB
CLAUDE.md
Operational guide for AI agents working in this repo. Long-form human docs:
CONTRIBUTING.md (setup, testing philosophy) and frontend/README.md.
Read those before large changes. This file is the short, must-follow version.
For a deep navigation map (request lifecycle, cron-job table, symptom → file
index, layering rules), read docs/architecture.md on demand — do not guess
file locations when it can answer in one hop.
Stack
- Backend: Go 1.26 (
module github.com/mhsanaei/3x-ui/v3), Gin, GORM. Runs Xray-core as a managed child process (internal/xray/process.go) and importsgithub.com/xtls/xray-corefor config types + gRPC stats/handler/router API. MTProto inbounds run a second managed child — themtgbinary (internal/mtproto/) — outside Xray. - Storage: SQLite by default (
/etc/x-ui/x-ui.dbon Linux; the executable dir on Windows), PostgreSQL optional (XUI_DB_TYPE/XUI_DB_DSN). The CGo SQLite driver (mattn/go-sqlite3) needs a C compiler —CGO_ENABLED=0builds fail. - Frontend: React 19 + Ant Design 6 + Vite 8 + TypeScript in
frontend/, built intointernal/web/dist/(gitignored) and embedded viaembed.FS.
Repo map
main.go— entry point +x-uiCLI (run, migrate, migrate-db, setting, cert).internal/config/— env parsing (XUI_DEBUG, XUI_LOG_LEVEL, XUI_LOG_FOLDER, XUI_BIN_FOLDER, XUI_SKIP_HSTS, XUI_PORT, XUI_DB_*).internal/database/+internal/database/model/— GORM schema (Inbound, Client, Setting, User), inbound Protocol enum, AutoMigrate + hand-written migrations indb.go.internal/xray/— Xray child-process lifecycle, config generation, gRPC API.internal/mtproto/— MTProto inbounds via the bundledmtgbinary.internal/sub/— subscription server (raw / JSON / Clash).internal/eventbus/— in-process pub/sub (outbound/node health, xray.crash, cpu.high, memory.high, login.attempt).internal/logger/,internal/util/(link, crypto, sys, ldap, …),internal/tunnelmonitor/— shared infrastructure.internal/web/— Gin server (embedsdist/+translation/).controller/— panel + REST API handlers; OpenAPI at /panel/api/openapi.json.service/— business logic (InboundService, SettingService, XrayService, node sync); subpackages tgbot/, email/, outbound/, panel/, integration/.job/— cron jobs (traffic, fail2ban IP-limit, node heartbeat/sync, LDAP).middleware/,entity/,global/,session/(CSRF),network/,runtime/(master/sub-node over mTLS),websocket/.locale/+translation/— i18n, 13 embedded locale JSON files.
frontend/— React + TS source (seefrontend/CLAUDE.md).tools/openapigen/— Go generator that emits frontend types + Zod/JSON schemas intofrontend/src/generated/from Go structs. The OpenAPI doc itself (frontend/public/openapi.json) is assembled from those +endpoints.tsbyfrontend/scripts/build-openapi.mjs.
Hard rules (non-negotiable)
- NO
//line comments in committed Go/TS. Names carry meaning; rename instead of annotating. Exempt://go:build,//go:generate, and other directives. HTML<!-- -->is fine. (A linter cannot enforce this — you must.) - New
g.POST/g.GETininternal/web/controller/REQUIRES a matching entry infrontend/src/pages/api-docs/endpoints.ts, thenmake gen(orcd frontend && npm run gen). It is a hand-maintained registry — nothing checks it against the Go routes, so an omitted route silently vanishes from the docs. - Response examples come from Go struct
example:tags viatools/openapigen— never hand-write them. A new struct must be added to openapigen'sStructAllowallowlist (tools/openapigen/main.go) or it is silently omitted from schemas/examples (andbuild-openapi.mjsthen fails on the missing schema). - A new English i18n key must be added to EVERY locale JSON in
internal/web/translation/(13 files). Missing keys fall back to en-US (or render the raw key if absent there too); nothing fails the build, so they are easy to miss. - DB / model changes require a migration in
internal/database/db.go. - Conventional-commit prefixes (
feat,fix,refactor,chore,docs,style):<area>: short imperative summary, then a body explaining the why.
Go conventions
- Stdlib
testingonly (no testify). Table-driven,t.Runsubtests,t.Helper()on helpers. Assert the exact value / typed error / emitted string, never justerr != nil. Prefer real deps over mocks: throwaway DB viadatabase.InitDB(filepath.Join(t.TempDir(), "x-ui.db"))+t.Cleanup(func() { _ = database.CloseDB() });httptestfor HTTP.internal/sub'sinitSubDB(t)is the template. - Code must pass
golangci-lint run(gofumpt + goimports formatting):make lint.
Frontend conventions (summary; full version in frontend/CLAUDE.md)
- Ant Design 6 only — no Tailwind/shadcn. Targeted tweaks, not rewrites.
- TS strict;
@typescript-eslint/no-explicit-anyis an error. Zod schemas insrc/schemas/are the source of truth; infer types withz.infer, never hand-write. Do not editsrc/generated/. - Editing
frontend/srcdoes NOT change what users see until the Vite build is regenerated intointernal/web/dist/. InXUI_DEBUG=true, HTML is served from the frozen embedded FS but JS/CSS off disk — afternpm run buildyou MUST restartgo run .or you get a blank page with 404s. - After touching share-link logic (
src/lib/xray/), runnpm run test(golden fixtures); regenerate snapshots (npx vitest run -u) only for intentional output changes, never to make a red test green.
Build, test, verify
Run make help for all targets. The full local gate that mirrors CI:
make verify
Common targets: make gen (regenerate Zod/OpenAPI), make lint (Go + frontend),
make test (Go -shuffle=on + frontend), make race, make build. See Makefile.
Definition of done (before opening a PR)
make genand confirmgit diffonfrontend/src/generated+frontend/public/openapi.jsonis clean.make verifypasses.- Diff is focused; refactors are separate from feature work.