The admin panel
A guided tour of every admin area — what each screen is for, what an operator decides there, and the daily and weekly routine that keeps the queues clear.
The admin panel lives at /admin. It is around 79 core screens, plus another
182 that ship with the extensions, so this page does not describe them one by
one. It gives you the map: the six areas, what each one is for, what you
actually decide there, and the routine that keeps the work moving.
Two things are worth knowing before you open it.
There is no sidebar. Navigation is the top bar. Each of the six areas opens
a mega-dropdown; the area pages themselves (/admin/crm, /admin/finance,
/admin/system, /admin/content, /admin/extensions) render nothing but that
area's submenu, so landing on one is not a dead end. Press Ctrl+K (or Cmd+K
on a Mac) anywhere in the admin to open a search over every menu item — it is
admin-only, and it is the fastest way to reach a screen you cannot find.
The nav is the taxonomy, not the work list. Withdrawals are filed under Finance because that is what they are, not because that is when you deal with them. What is waiting on you lives in the Operations inbox in the header, which cuts across the nav and is described below.
First login
The installer seeds one administrator:
superadmin@example.com
12345678These credentials are printed in the installer's summary and they are the same on every install. The account holds the Super Admin role, which bypasses every permission check in the platform — including the ones on money movement.
Delete the default account once you have made your own Super Admin. The seeder
writes a superAdminSeeded marker into the settings table the first time it
runs, so a later pnpm seed (which every update performs) will not recreate the
account you removed.
The seeders create four roles — Super Admin, Admin, Support and
User — but they grant no permissions to any of them. The role_permission
table ships empty. A user you put in the Admin role can log in and will see an
empty admin panel until you assign permissions on Users → Roles &
Permissions → User Roles. Super Admin is the exception because it
short-circuits the check rather than holding grants.
The six areas
/admin — is anything on fire, and how is the business doing. Five KPIs, four
charts, revenue by product, platform health, and an alert band for anything past
its target.
/admin/crm — the people. Accounts, roles and permissions, KYC review, support
tickets, API keys.
/admin/finance — the money. Deposit and withdrawal queues, wallets,
transactions, currencies, gateways, exchange providers, orders, investment plans.
/admin/extensions — the products you sell. Every installed add-on's own admin,
grouped by what it does rather than by vendor.
/admin/content — the public site. Blog, media, sliders, and the design studios
for theme, menus, footer and pages.
/admin/system — the platform itself. Settings, notifications, geo compliance,
audit trail, scheduler, extension manager, updates.
Dashboard
Three questions, in the order the page answers them.
Is anything on fire. An alert band sits above everything else. It fires on three conditions: a queue holding items past their target, a scheduler that is not running, and platform health reported critical. Each row names the thing and links into it. If the band is empty, nothing needs you right now.
How is the business doing. Five KPI cards — total users, active users (signed in within 30 days), fee revenue, transactions all-time, new users this period — then four charts: fee revenue, user growth, trading activity and transaction mix. The timeframe selector offers This week, Last 4 weeks and This year. Below that, revenue split by product and the busiest markets.
Is the platform healthy. The health card polls
/api/admin/system/health/batch every five minutes and checks Database, Cache
(Redis), Scheduler (Cron), Email Service, Exchange Provider, and the transaction,
withdrawal and KYC queues. Analytics do not auto-refresh — they are the expensive
query and they do not change minute to minute. Use the refresh button if you want
them now.
A failed refresh leaves the last good figures on screen rather than blanking the page, so a number that looks frozen may mean the API is unreachable, not that nothing happened.
The Operations inbox
The inbox in the header is the single answer to "what is waiting on me". It is on every admin screen, it polls once a minute, and it covers 25 queues: five that every install has, and up to 20 more contributed by enabled extensions. Which runbook each one opens is Working the Operations inbox.
The five core queues:
| Queue | Where it goes | Target |
|---|---|---|
| Verification | /admin/crm/kyc/application |
7 days |
| Withdrawals | /admin/finance/withdraw/log |
7 days |
| Deposits | /admin/finance/deposit/log |
3 days |
| Transfers | /admin/finance/transfer |
3 days |
| Support | /admin/crm/support |
24 hours |
Add-on queues appear only when their extension is enabled, and they use three budgets by shape rather than one per product: disputes 24 hours (escrow is frozen for both sides while one runs), paid orders awaiting fulfilment 48 hours, and approvals — P2P offers, merchants, copy-trading leaders, bot strategies, ICO offerings, referrals, public questions — 72 hours.
A queue turns amber at half its budget and red once past it. The badge on the inbox and the age column on the queue's own page are computed from the same number, so they cannot disagree.
Queues you cannot open are hidden from your inbox. Clear queues collapse into a single line of pills at the bottom rather than disappearing, so an empty queue reads as "checked and empty" and not "not being counted".
Deciding from a queue
Deposits, withdrawals and transfers share one decision control. All three open
already filtered to PENDING and sorted oldest first — the row that has
waited longest is the one to do next. Approve and Reject sit on the row itself
and on the bulk menu, so you never leave the list.
- A rejection always requires a reason. It is the decision the customer is told about and the one that gets disputed. Approvals take an optional note.
- Whatever you type is emailed to the customer and recorded against your account in the audit trail.
- Rows already settled get no buttons. Offering Approve on a completed withdrawal is an invitation to pay twice.
- Withdrawals can be decided at
PENDINGandPROCESSING— a payout stuck mid-flight is exactly the row that needs a human. Deposits and transfers acceptPENDINGonly.
Users
Users (/admin/crm/user) is the account list. You can create and edit users
but not delete them from the table. The per-row menu carries the operational
actions:
- Block User — pick a reason from Suspicious Activity, Terms of Service Violation, Security Concerns, Fraud Investigation, Compliance Review, Customer Request or Other, and optionally make it temporary with a duration from 1 hour to 1 month. A reason is mandatory.
- Unblock.
- Import Users — CSV upload with a downloadable template, a default password
and an optional welcome email. Needs
import.user. - Export — needs
export.user.
Opening a user shows their profile, activity, block history and their transactions inline.
Roles & Permissions. User Roles (/admin/crm/role) is full CRUD, and it is
where you tick the permissions a role holds. Permissions
(/admin/crm/permission) is deliberately read-only — it is the catalogue of the
715 seeded keys, not somewhere to invent new ones. There is no write endpoint
behind it.
Compliance & Verification. KYC Applications
(/admin/crm/kyc/application) opens on the PENDING tab, oldest first, with tabs
for Additional Info Required, Approved and Rejected and a filter by verification
level. Every status change — from this screen or from an automated verification
service — goes through one code path, which sets the status and your notes,
stamps the review time, clears the applicant's cached profile, emails them, and
writes a row to their activity log. Verification Levels
(/admin/crm/kyc/level) is where the levels and their required fields are
defined.
Customer Support (/admin/crm/support) is the desk console: the queue on the
left, the conversation in the middle, the ticket on the right. It opens on the
conversations waiting for you, oldest wait first — "waiting" means the customer
spoke last, which is not the same as a status, because a ticket stays REPLIED
after they answer. Filter by Waiting, Mine, Free (unassigned), All or Closed,
search the queue, and move through it with J and K. You reply, assign, set
priority and close without leaving the screen. Tickets are not created here.
The queue is capped at the live end of the desk, so the archive has its own
screen: All tickets (/admin/crm/support/tickets), reachable from the
console's top bar. That is where the totals, the analytics tabs, per-column
filters and sorting, and bulk close / reopen / assign / delete live, and it is
the only place that reaches every ticket ever raised.
The inbox badge still counts a ticket as waiting on you while it is PENDING or
OPEN; REPLIED means an agent has already answered.
If the AI Support add-on is installed, the console's queue links through to its Live Inbox, where the same conversations carry the assistant's evidence and a takeover button. Without the add-on, that slot describes what it does instead.
API Management (/admin/api/key) manages the API keys issued for external
integrations.
Finance
The largest area, and the one where mistakes cost money.
Revenue Analytics (/admin/finance/profit) is the platform's own earnings —
fees collected, split by type, by currency and by wallet type, with today, this
week, this month and last month side by side. Totals are kept per currency;
they are never added together, because a figure that sums BTC to USD means
nothing.
Currency Management. Cryptocurrencies (/admin/finance/currency/spot) and
Fiat (/admin/finance/currency/fiat). The crypto screen finds currencies your
exchange provider offers that you have not listed yet and imports them behind a
preview. Neither screen lets you create a currency by hand; you enable, disable
and price what the provider supplies.
Payment Systems. Gateways (/admin/finance/deposit/gateway) is not a table
but a readiness console: for each bundled fiat gateway it tells you whether it
can take a payment right now, which credential is missing if not, whether you are
pointed at test or live keys, and where the webhook URL should go. Credentials
live in the environment, not in the database row — the screen reads the
environment and reports what it finds. Methods
(/admin/finance/deposit/method) is the manual deposit methods you define
yourself. Deposit Records (/admin/finance/deposit/log) is the queue.
Withdrawal Management. Methods and Records. The records screen is the withdrawal queue described above.
Transaction Management. Wallets (/admin/finance/wallet) lists every user
wallet. You cannot create or delete one, but you can adjust a balance —
choose Add or Subtract, enter an amount and a description, and decide whether the
user is notified. Each dialog opens with a fresh idempotency token, so a
double-click cannot double-credit. You can also freeze a wallet with the status
toggle. Transaction Logs (/admin/finance/transaction) is the full ledger,
read and delete only. Internal Transfers (/admin/finance/transfer) is a queue
with a settlement page behind each row.
Trading Infrastructure. Exchange Providers (/admin/finance/exchange) is a
three-tab hub — Overview, Regions, Settings — where you activate a provider,
verify its credentials, test a proxy and flip it live. It deep-links to the
provider's markets, chart data, currencies, balances and fees, none of which
appear in the menu. Trading Settings (/admin/trading/settings) configures the
trading interface: general, features, trading form and display.
Binary Options, Order Management and Investment Management follow the same pattern — markets and settings, then the order books (spot, ecosystem, futures, binary), then plans, durations and analytics.
It is not listed in the route permission map, so it falls back to the
catch-all access.admin. Anyone who can open the admin at all can open it.
Treat access.admin as a meaningful grant, not a formality.
Extensions
The Extensions dropdown is a five-group mega-menu, grouped by what a product does:
- Trading Platforms — a venue where users place orders: Ecosystem, Futures, Forex trading desk, P2P.
- Trading Automation — something that trades for someone, or makes the market: Copy Trading, Trading Bots, Hummingbot, AI Market Maker, Binary AI Engine.
- Investment Products — capital in, yield out, no order placed: AI Investments, managed Forex, Staking, ICO.
- Marketplace — goods and collectibles: Ecommerce, NFT.
- Business Tools — running the business: MLM/Affiliate, MailWizard, Payment Gateway, Knowledge Base.
Each extension has its own admin sub-navigation once you enter it. Note that the admin menu shows extensions you have not enabled, marked as disabled, so you can see what is available; the public user menu hides them.
Content
Blog System (/admin/blog), Media Library (/admin/content/media) and
Homepage Sliders (/admin/content/slider) are the ordinary content screens.
Appearance & Design holds the studios. These render full-bleed with no admin header — they are control-rail-plus-live-preview surfaces that own the whole viewport, and each carries its own way back:
- Site Design (
/admin/design) — palette, corner radius, typeface, elevation, motion, and the navbar and footer layout, previewed against the real site. - Menus (
/admin/menus) — rename, reorder, hide or add items in any menu on the site, including each extension's own. The override is applied last, after permission and extension filtering, so hiding an item removes a link and grants nothing; it can never resurrect a page a role cannot reach. - Footer (
/admin/footer) — footer content. Footer layout is in Site Design. - Page Builder (
/admin/builder) — appears only when thelandingPageTypesetting isCUSTOM. - Default Pages (
/admin/default-editor) — appears only whenlandingPageTypeisDEFAULT.
Those last two are mutually exclusive by design. If you cannot find the page
builder, check landingPageType in Platform Settings.
System
Platform Settings (/admin/system/settings) is seven tabs — general,
security, integrations, features, wallet, social, logos. The save sends only
the keys you changed, which matters more than it sounds:
Withdrawal approval and auto-approval, the five withdrawal two-factor keys, the
wallet transfer fee and spread, the five TransFi ramp and custody keys, demo
mode, FX external routing, the four trading-bot money and kill-switch keys, and
KYC feature enforcement. A non-Super-Admin who changes one gets a 403 for the
whole save. They can still save the rest of the page, because unchanged keys are
dropped before the check runs. Key matching is case-insensitive — renaming a key
to WithdrawApproval does not get around it.
Geo-restriction keys are also refused here; they are only writable from the Geo Policy screen, which has its own permission.
Communication Tools. Notification Service (/admin/system/notification) is
seven tabs — overview, health, test, queue, metrics, PWA and settings — and the
test tab sends a real message on each channel so you can prove delivery before a
customer discovers it is broken. Notification Templates can be edited and
enabled but not created or deleted; the set is fixed by what the platform sends.
SMS Providers compares Twilio and MSG91 and validates credentials before
saving. System Announcements and Market News publish to the site and the
trading terminal.
Compliance. Geo Restrictions restricts access by country with scheduled effective dates, a recorded legal basis, and a rule tester that answers "would this visitor be refused" without waiting for one. Geo Policy is how the rules are enforced — detection sources, VPN handling, wind-down carve-outs, the visitor notice. Geo Access Log is the evidence trail with CSV export.
System Monitoring.
- Audit Trail (
/admin/system/audit) records every administrative mutation: who, which module, method and path, the record touched, success or error, the reason they gave, how long it took, and the request ID and IP. It is append-only — there is no create, edit or delete, and no write endpoint behind it, because a trail whose rows can be edited from the panel is not evidence. Expand a row for the forensics. - Scheduled Tasks (
/admin/system/cron) is where you find out that the scheduler is not running. Since cron became its own process, it can stop while the site keeps serving pages perfectly — and a job that refuses itself every tick returns normally. The page keeps three signals separate rather than folding them into one green tick: the scheduler heartbeat, the job registry with its run state and sticky refusals, and a live log stream. Triggering a job by hand needsmanage.cron; viewing needsview.cron. - Currency Icons finds currencies with no icon and fetches them. Exchange providers list new tokens continuously, so this gap reopens on its own.
Extension Manager (/admin/system/extension) enables and disables installed
extensions and shows what is available. Toggling one clears the platform cache,
so the menus and the operations inbox pick it up immediately.
System Updates (/admin/system/update) checks for new versions, shows the
changelog, and downloads and extracts an update over your installation. See the
warning below about what it does not do.
What the panel cannot do
Some things an operator needs are not in the admin at all, and looking for them there wastes an outage.
The Updates screen fetches the release and extracts it over the project. It does
not run migrations, rebuild the frontend, or restart anything — and it never
deletes files a release removed. Finish the job from a shell in the project root
with pnpm updator (or pnpm update-all, which enumerates core plus every
extension). Back up the database first; the screen says so for a reason.
- Environment configuration. Payment gateway credentials, blockchain RPC
endpoints, the wallet encryption key, Redis and database connection details all
live in
.env. The panel reads them and reports whether they are present; it does not write them. - Starting, stopping and restarting. That is
pnpm start,pnpm stopandpnpm restartfrom the project root. There is no restart button, and thesystemctlcommands the installer prints in its summary do not work — that unit file is deliberately removed during installation. - Web server, ports and TLS. Nothing in the panel touches nginx.
Screens with no menu entry
A handful of real screens are reachable only by typing the URL or from a link inside another page. The most important:
/admin/system/database/backup— runs amysqldumpinto abackup/folder in the project root, lists what is there, and restores from it. It has no inbound link anywhere in the product. It also covers MySQL only: Redis, ScyllaDB (if you run the ecosystem or futures trading engines), your.env, the licence files andfrontend/public/uploads/are not in that dump and must be backed up separately./admin/system/license— linked from exchange and extension detail pages./admin/finance/exchange/balance,/chart,/fee,/market— linked from the Exchange hub./admin/system/logo— superseded by the Logos tab in Platform Settings.
Who can see what
Access is one permission key per route, and a key is derived mechanically from
the admin path: slashes become dots, dashes become underscores, and a verb goes
in front. admin/crm/user becomes access.user, view.user, create.user,
edit.user, delete.user. admin/ai/binary-engine/tiers becomes
view.ai.binary_engine.tier.
The verbs mean what they say: access. opens a screen, view. reads, create.,
edit. and delete. do the obvious, and manage. is reserved for privileged or
destructive lifecycle actions like triggering a cron job by hand.
Four things follow from this that matter in practice.
Group headers list the union of everything reachable below them, and the check is "any", not "all". A role scoped to deposits alone still sees the Finance group, with only the deposit screens inside it.
Hiding a menu item removes a link. The API enforces the same permission on the route behind it regardless, so a hidden page is still refused if someone types the URL. Equally, granting a permission does not un-hide a page you removed in the menu editor.
The route map covers 217 paths explicitly. Anything under /admin that is not
listed requires access.admin — fail-closed, but coarse. Several real screens
sit in that bucket, including Trading Settings, the page builder and the
notification service.
The role name is checked by string, before permissions are consulted. There is no way to scope a Super Admin. Give the role to people, not to service accounts.
One more, if you run a public demo: with demo mode on, every POST, PUT and
DELETE under /api/admin is refused for anyone who is not a Super Admin.
Demo mode is read from the environment, not from the settings table, so a demo
install that appears to accept admin writes is not misconfigured — it is not in
demo mode.
The routine
-
Every day — clear the band, then the queues. Open
/admin. If the alert band is empty and the health card is green, go straight to the Operations inbox in the header and work the red queues first, then amber. Each queue opens oldest-first for you; you do not need to sort anything. -
Every day — support inside 24 hours. Support has the tightest budget of the core five. Assign what you cannot answer rather than leaving it unassigned.
-
Every day — withdrawals with an eye on
PROCESSING. Filter toPROCESSINGonce a day as well asPENDING. Those are payouts that started and did not finish, and nothing else in the product will tell you about them. -
Every week — check the scheduler. Open System → System Monitoring → Scheduled Tasks and confirm the heartbeat banner is green and no job is stuck refusing itself. A dead scheduler does not stop the website, so nothing else makes it obvious.
-
Every week — read the audit trail. System → Audit Trail, filtered to
ERROR. A run of failures from one admin on one endpoint is either a permission problem or an incident, and both are cheaper to find on Monday than in a chargeback. -
Every week — currency icons and new listings. Run the icon sync; providers add tokens continuously and a missing icon is visible to every customer.
-
Every month — take a backup and prove it. Run the database backup, and copy
.env, thelic/directory andfrontend/public/uploads/off the box. The built-in backup covers MySQL and nothing else. -
When an update appears — read the changelog first. Especially the Upgrade Notes section, which is pulled to the top because it is the part that costs money to miss. Back up, download from the panel, then finish the job from a shell with
pnpm updator.