diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index 1786680c..00000000 --- a/AGENTS.md +++ /dev/null @@ -1,74 +0,0 @@ -# AGENTS.md - -This file provides guidance to agents when working with code in this repository. - -## Critical Architecture Patterns - -**Telegram Bot Restart Pattern**: MUST call `service.StopBot()` before any server restart (SIGHUP or shutdown) to prevent Telegram bot 409 conflicts. This is critical in `main.go` signal handlers (lines 82-84, 120-122). - -**Embedded Assets**: All web resources (HTML, CSS, JS, translations in `web/translation/`) are embedded at compile time using `//go:embed`. Changes to these files require full recompilation - no hot-reload available. - -**Dual Server Design**: Main web panel and subscription server run concurrently, both managed by `web/global` package. Subscription server uses separate port. - -**Database Seeder System**: Uses `HistoryOfSeeders` model to track one-time migrations (e.g., password bcrypt migration). Check this table before running migrations to prevent re-execution. - -**Xray Integration**: Panel dynamically generates `config.json` from inbound/outbound settings and communicates via gRPC API (`xray/api.go`) for real-time traffic stats. Xray binary is platform-specific (`xray-{os}-{arch}`) and managed by installer scripts. - -**Signal-Based Restart**: SIGHUP triggers graceful restart. Always stop Telegram bot first via `service.StopBot()`, then restart both web and sub servers. - -## Build & Development Commands - -```bash -# Build (creates bin/3x-ui.exe) -go build -o bin/3x-ui.exe ./main.go - -# Run with debug logging -XUI_DEBUG=true go run ./main.go - -# Test all packages -go test ./... - -# Vet code -go vet ./... -``` - -**Production Build**: Uses CGO_ENABLED=1 with static linking via Bootlin musl toolchains for cross-platform builds (see `.github/workflows/release.yml`). - -## Configuration & Environment - -**Environment Variables**: -- `XUI_DEBUG=true` - Enable detailed debug logging -- `XUI_LOG_LEVEL` - Set log level (debug/info/notice/warning/error) -- `XUI_MAIN_FOLDER` - Override default installation folder -- `XUI_BIN_FOLDER` - Override binary folder (default: "bin") -- `XUI_DB_FOLDER` - Override database folder (default: `/etc/x-ui` on Linux) -- `XUI_LOG_FOLDER` - Override log folder (default: `/var/log/x-ui` on Linux) - -**Database Path**: `config.GetDBPath()` returns `/etc/x-ui/x-ui.db` on Linux, current directory on Windows. GORM models auto-migrate on startup. - -**Listen Address**: If inbound listen field is empty, defaults to `0.0.0.0` for proper dual-stack IPv4/IPv6 binding (see `database/model/model.go` lines 85-87). - -## Project-Specific Patterns - -**IP Limitation**: Implements "last IP wins" strategy. When client exceeds LimitIP, oldest connections are automatically disconnected via Xray API to allow newest IPs. - -**Session Management**: Uses `gin-contrib/sessions` with cookie-based store for authentication. - -**Internationalization**: Translation files in `web/translation/translate.*.toml`. Access via `I18nWeb(c, "key")` in controllers using `locale.I18nType` enum. - -**Job Scheduling**: Uses `robfig/cron/v3` for periodic tasks (traffic monitoring, CPU checks, LDAP sync, IP tracking). Jobs registered in `web/web.go` during server initialization. - -**Service Layer Pattern**: Services inject dependencies (like `xray.XrayAPI`) and operate on GORM models. Example: `InboundService` in `web/service/inbound.go`. - -**Controller Pattern**: Controllers use Gin context (`*gin.Context`) and inherit from `BaseController`. Check auth via `checkLogin` middleware. - -**Xray Binary Management**: Download platform-specific Xray binary to bin folder during installation. GeoIP/GeoSite rules downloaded from external repositories (Loyalsoldier, chocolate4u, runetfreedom). - -## Gotchas - -1. **Bot Restart**: Always stop Telegram bot before server restart to avoid 409 conflict -2. **Embedded Assets**: Changes to HTML/CSS/JS require recompilation -3. **Password Migration**: Seeder system tracks bcrypt migration - check `HistoryOfSeeders` table -4. **Port Binding**: Subscription server uses different port from main panel -5. **Xray Binary**: Must match OS/arch exactly - managed by installer scripts -6. **No Test Files**: Project currently has no `_test.go` files, though `go test ./...` is available diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 3050e09b..00000000 --- a/CLAUDE.md +++ /dev/null @@ -1,110 +0,0 @@ -# CLAUDE.md - -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Development commands - -- Build the app: `go build -o bin/3x-ui.exe ./main.go` -- Run locally with debug logging: `XUI_DEBUG=true go run ./main.go` -- Run tests: `go test ./...` -- Run vet: `go vet ./...` -- Run a single package test suite: `go test ./path/to/package` -- Run a single test: `go test ./path/to/package -run TestName` -- Show CLI help / subcommands: `go run ./main.go --help` -- Show version: `go run ./main.go -v` - -VS Code tasks mirror the common Go workflows: -- `go: build` -- `go: run` -- `go: test` -- `go: vet` - -## Runtime shape - -This is a Go monolith for managing Xray-core, with two Gin-based HTTP servers started from `main.go`: -- the main panel server in `web/` -- the subscription server in `sub/` - -`main.go` initializes the SQLite database, starts both servers, and handles process signals: -- `SIGHUP` restarts the panel + subscription servers -- `SIGUSR1` restarts xray-core only - -Important: before full shutdown or SIGHUP restart, the Telegram bot is stopped explicitly via `service.StopBot()` to avoid Telegram 409 conflicts. - -## High-level architecture - -### Database and settings - -- `database/db.go` initializes GORM with SQLite, runs auto-migrations, seeds the default admin user, and runs one-time seeders. -- Models live in `database/model/model.go`. -- App configuration is heavily database-backed through the `settings` table rather than static config files. -- `HistoryOfSeeders` is used to track one-time migrations such as password hashing changes. - -### Web panel - -- `web/web.go` builds the main Gin engine, session middleware, gzip, i18n, static asset serving, template loading, websocket hub setup, and background cron jobs. -- Controllers are in `web/controller/`. -- Business logic lives in `web/service/`. -- Background tasks live in `web/job/`. -- The websocket hub is in `web/websocket/` and is wired from `web/web.go`. - -### Subscription server - -- `sub/sub.go` starts a separate Gin server for subscription links and JSON subscriptions. -- It has its own listen/port/cert settings and can run independently of the main panel routes. -- It reuses embedded templates/assets from `web/` and applies subscription-specific path/domain settings from the database. - -### Xray integration - -- `xray/` is the bridge to xray-core. -- `xray/process.go` writes `config.json`, launches the platform-specific xray binary, tracks process state, and handles stop/restart behavior. -- `xray/api.go`, `xray/traffic.go`, and related files handle API access and traffic/stat collection. -- The panel treats xray-core as a managed subprocess and periodically monitors/restarts it from cron jobs in `web/web.go`. - -### Frontend delivery model - -- The UI is server-rendered HTML templates plus embedded static assets under `web/html/` and `web/assets/`. -- In production, templates/assets are embedded with `go:embed` in `web/web.go`. -- In debug mode (`XUI_DEBUG=true`), templates and assets are loaded from disk, so edits under `web/html/` and `web/assets/` are reflected without rebuilding embedded resources. -- Internationalization files live in `web/translation/*.toml` and are initialized by `web/locale`. - -## Background jobs and long-running behavior - -`web/web.go` registers the operational jobs that keep the panel in sync with xray-core. These include: -- xray process health checks -- deferred/statistical traffic collection -- client IP checks / log maintenance -- periodic traffic reset jobs -- optional LDAP sync -- optional Telegram notification and CPU alert jobs - -When changing settings or services that affect runtime behavior, check whether a cron job, websocket update, or xray restart path also needs to change. - -## Repo-specific conventions and gotchas - -- Default credentials are seeded as `admin` / `admin`, but stored hashed in the DB. -- The app uses DB settings extensively; many behavior changes require updating `SettingService`, not just editing route/controller code. -- The `Inbound` model stores much of the Xray config as JSON strings (`Settings`, `StreamSettings`, `Sniffing`), then converts those into xray config structs. -- The main panel and subscription server have separate listen/port/cert/base-path concepts. Keep them distinct when changing routing or TLS behavior. -- Session handling uses `gin-contrib/sessions` with a cookie store and secret loaded from settings. -- The subscription server intentionally runs Gin in release mode and discards Gin default writers. -- There are currently no `*_test.go` files in the repo, so `go test ./...` mainly validates buildability of packages. - -## Important files to orient quickly - -- `main.go` — process entrypoint, CLI subcommands, signal handling -- `web/web.go` — main server wiring, embedded assets/templates, cron jobs -- `sub/sub.go` — subscription server wiring -- `database/db.go` — DB init, migrations, seeders -- `database/model/model.go` — core persistent models -- `web/service/setting.go` — central behavior/settings access point -- `web/service/inbound.go` and `web/service/xray.go` — panel logic tied to xray config/runtime -- `xray/process.go` — xray subprocess management - -## Existing repo guidance carried forward - -From `.github/copilot-instructions.md` and current code structure: -- Treat the project as a Go + Gin + SQLite application with embedded web assets. -- Remember the dual-server design: main panel plus subscription server. -- Preserve the Telegram bot shutdown-before-restart behavior. -- If working on deployment or container behavior, note that Docker support exists via `Dockerfile`, `DockerInit.sh`, `DockerEntrypoint.sh`, and `docker-compose.yml`. diff --git a/go.mod b/go.mod index a30157c3..6858d5b6 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/gin-gonic/gin v1.12.0 github.com/go-ldap/ldap/v3 v3.4.13 github.com/goccy/go-json v0.10.6 + github.com/goccy/go-yaml v1.19.2 github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 github.com/joho/godotenv v1.5.1 @@ -48,7 +49,6 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.30.2 // indirect - github.com/goccy/go-yaml v1.19.2 // indirect github.com/google/btree v1.1.3 // indirect github.com/gorilla/context v1.1.2 // indirect github.com/gorilla/securecookie v1.1.2 // indirect diff --git a/web/html/settings/panel/subscription/general.html b/web/html/settings/panel/subscription/general.html index 4f10a716..725a9359 100644 --- a/web/html/settings/panel/subscription/general.html +++ b/web/html/settings/panel/subscription/general.html @@ -3,50 +3,58 @@ - + - + - + - + - + - + - +