# Panel Panel is the Nexuma web interface for operators and users. Operators manage the platform from one place. Users manage their own subscriptions, public links, configs, traffic, finance history, and account settings. This page is public operator documentation. It describes panel capabilities, routes, API behavior, environment variables, and Docker deployment without requiring source-code access. ## Capabilities ### Admin Dashboard - Node status grid. - Recent audit log feed. - Auto-refresh for operational visibility. ### Users - User list with search and status filters. - Approval, rejection, restore, block, edit, and delete actions. - User profile details. - User subscriptions. - User subscription links. - User node/protocol access matrix. - User finance and balance transaction history. ### Tariffs - Create, edit, and delete tariffs. - Configure price, duration, traffic limit, active state, and allowed protocols. - Restrict tariffs to selected nodes. - Attach external subscription sources. - Allow or block selected routing categories through tariff permissions. ### Subscriptions - Create and cancel subscriptions. - Filter subscriptions by status, user, and tariff. - Toggle auto-renew. - Create, rename, disable, reset, and delete public links. - Restrict public links to selected nodes. ### Nodes - List, create, edit, and delete nodes. - Generate registration codes. - Rotate node auth keys. - Force config sync. - Manage protocols. - Manage outbounds for proxy chains; probe outbound connectivity. - Manage routing config, routing balancers, and observatory settings. - Manage masking sites with TLS upload or auto-issuance; view certificate status. - Install and restart Xray and MTProto. - Update GeoIP/geosite files. - Generate X25519, ML-DSA-65, TLS-ECH, and VLESS encryption keys. - View live runtime status and resource usage. ### Routing Rules - Create, edit, and delete reusable rule sets. - Manage custom rules and balancers. - Assign routing configuration to nodes. ### External Subscriptions - Create, edit, and delete external subscription sources. - Test a source URL before attaching it to tariffs. - Attach sources to tariffs so their share links are appended to subscriptions. ### Settings - Configure panel access settings (allowed hosts, root path). - Configure subscription delivery settings (update interval, display name, support URL). - Configure Telegram bot token. - Configure the user IP information provider: IPinfo.io with an API token, or ip-api.com with Russian or English result language. English is the default for ip-api.com. - Configure a DonationAlerts OAuth application with its client ID, client secret, generated callback URL, public donation page URL, and commission percentage. After saving, authorize it through DonationAlerts; access and refresh tokens are stored and refreshed automatically. - Configure DonatePay with an API token, public donation page URL, and an optional commission percentage. ### DonationAlerts Payments - The Finance page shows an add-funds button only while DonationAlerts is configured. - The payment modal shows the configured commission and the current user's UUID. - The user must put exactly one UUID in the donation message; otherwise the donation remains unassigned. - Core checks donations every 5 minutes, scanning donations created during the previous hour. - Only positive whole-RUB donations are processed. The configured commission is deducted and the credited result is rounded down to whole RUB; other currencies and fractional gross amounts are skipped. - Donation IDs are stored as unique external transaction references, preventing duplicate credits. ### DonatePay Payments - Core checks successful DonatePay donations every 5 minutes, scanning the previous hour. - The user UUID is read from the transaction `comment`; donations without exactly one valid UUID remain unassigned. - Only positive whole-RUB donations are credited. The optional configured commission is deducted and rounded down. - DonatePay transaction IDs are stored as provider-specific external references to prevent duplicate credits. ### User IP History - View the number of recorded IP addresses on the admin user overview. - Open IP history grouped by enriched network information. - Expand a group to view each IP with first-seen and last-used timestamps. - Groups and addresses are ordered by most recent use. ### Broadcasts - Create and schedule Telegram broadcast messages. - Filter recipients by node. - View per-broadcast delivery status and error log. ### Logs - View audit events. - Filter logs by action and user. ### Self-Service - Personal dashboard. - Traffic charts and hourly distribution. - Personal subscriptions. - Personal public links. - Personal configs. - Finance history and balance. - Account profile settings. - Telegram account linking and unlinking. - Referral referees list. ### Public Subscription Page - Public `/sub/:uuid` page. - Subscription metadata. - Raw config download/copy. - QR code. - Per-config copy buttons. - MTProto link display. ## Environment Variables | Variable | Required | Default | Description | | --- | --- | --- | --- | | `NUXT_PUBLIC_API_BASE` | No | `/api` | Browser-facing API base. Use `/api` for same-origin panel proxying. | | `NUXT_CORE_URL` | Yes for Docker | `http://localhost:3000` fallback | Core URL used by the panel server proxy. | | `NUXT_PUBLIC_WS_BASE` | No | empty (same origin) | WebSocket origin for the Socket.IO client (`/ws`). Empty = same origin (prod behind a reverse proxy that forwards `/ws` to Core); in dev point at Core, e.g. `http://localhost:3000`. | Recommended production values: ```env NUXT_PUBLIC_API_BASE=/api NUXT_CORE_URL=http://core:3000 ``` ## Docker Compose Panel-only deployment: ```yaml version: '3.9' services: panel: image: nexuma/panel:latest container_name: nexuma-panel restart: unless-stopped environment: NUXT_PUBLIC_API_BASE: /api NUXT_CORE_URL: https://core.example.com ports: - "3010:3000" healthcheck: test: ["CMD-SHELL", "wget -qO- http://localhost:3000/ || exit 1"] interval: 30s timeout: 10s retries: 3 start_period: 30s ``` Run: ```bash docker compose up -d ``` Open: ```text http://your-server:3010 ``` ## Routes Public routes: | Route | Purpose | | --- | --- | | `/auth/login` | Login screen. | | `/auth/pending` | Waiting-for-approval screen. | | `/auth/telegram/redirect` | Telegram login callback. | | `/auth/telegram/link-redirect` | Telegram account-link callback. | | `/sub/:uuid` | Public subscription page. | | `/:uuid` | Root UUID entry point for clients and redirects. | Admin routes: | Route | Purpose | | --- | --- | | `/` | Dashboard. | | `/users` | User list. | | `/users/:id` | User profile. | | `/users/:id/subscriptions` | User subscriptions. | | `/users/:id/links` | User links. | | `/users/:id/access` | User node/protocol access. | | `/users/:id/finance` | User finance. | | `/users/:id/referees` | Users invited by this user. | | `/tariffs` | Tariff management. | | `/nodes` | Node list. | | `/nodes/:id` | Node overview. | | `/nodes/:id/protocols` | Node protocols. | | `/nodes/:id/outbounds` | Node outbounds. | | `/nodes/:id/routing` | Node routing. | | `/nodes/:id/masking` | Node masking site. | | `/subscriptions` | Subscription management. | | `/routing-rules` | Routing rule set management. | | `/external-subscriptions` | External source management. | | `/settings` | Platform settings. | | `/broadcasts` | Telegram broadcast management. | | `/logs` | Audit logs. | | `/config-builder` | Protocol config builder. | User routes: | Route | Purpose | | --- | --- | | `/me` | Personal dashboard. | | `/me/subscriptions` | Personal subscriptions. | | `/me/configs` | Personal configs. | | `/me/links` | Personal links. | | `/me/finance` | Personal finance history. | ## API Behavior - Browser API calls use `NUXT_PUBLIC_API_BASE`. - The recommended browser base is `/api`. - Requests to `/api/*` are proxied by the panel server to `NUXT_CORE_URL`. - The proxy strips the `/api` prefix before forwarding. - UUID root requests from VPN clients are proxied to Core subscription output when the request does not ask for HTML. - Access and refresh tokens are stored in the browser. - API calls include the bearer access token when available. - A `401` response triggers a refresh attempt and one retry. - Failed operations are shown as user-facing notifications unless marked silent. ## Auth Rules - `/auth/*`, `/sub/*`, and UUID-only root paths are public. - Pending users can only see the pending page and logout. - Admin pages require an admin account. - Self-service pages require a logged-in user. ## Typical Operator Flow 1. Log in as admin. 2. Create or approve users. 3. Create tariffs. 4. Add or register nodes. 5. Configure node protocols. 6. Create subscriptions. 7. Share public subscription links. 8. Monitor node status, usage, and logs. ## Public Subscription Flow 1. User or admin opens a public link. 2. The panel loads subscription metadata from Core. 3. The panel displays configs, QR, traffic, expiry, and MTProto links. 4. VPN clients can request the UUID directly and receive raw subscription output.