What the addon tells bot owners, and what it does not
The notifications this addon actually sends, the fifteen templates it declares and never uses, the dead notify helpers, the deep links that land on a 404, and what to promise customers instead.
This page exists because the addon's source contains a notification catalogue
that is far larger than its notification behaviour. utils/constants.ts declares
fifteen template names and utils/integrations.ts exports ten ready-made
notify* helpers covering starts, stops, every trade, stop losses, take profits,
daily summaries and marketplace sales — and not one of those helpers is called
by anything.
An operator who writes their customer comms from that list will promise a stream of alerts the product does not produce. Read this page before you tell anyone what their bot will tell them.
Every notification the addon sends goes out on the IN_APP channel only.
createNotification in backend/src/utils/notifications.ts hard-codes
channels: ["IN_APP"], so there is no email, no SMS and no push for any bot
event, and nothing on Admin → System → Notification Templates changes that.
The bell in the customer's header and /user/notification are the only places
these ever appear.
What is actually sent
Seven createNotification calls exist across the whole addon, producing six
distinct titles. This is the complete list.
About a bot
| Title | Fires when | Type |
|---|---|---|
| Trading Bot Stopped Due to Critical Error | The engine hits an unrecoverable error on a tick and writes the bot to ERROR |
alert |
| Trading Bot Risk Limit Reached | A daily-loss or drawdown limit fires and the bot is written to LIMIT_REACHED |
alert |
| Trading Bot Became Unresponsive | The stale-bot job finds a RUNNING bot that has not reported a tick for five minutes and marks it ERROR |
alert |
Each carries the reason in its message body — the error text, the limit that fired, or "stale tick detection" — plus a single View Bot action.
About a marketplace listing
| Title | Fires when | Type |
|---|---|---|
| Strategy Approved | An admin approves a pending listing, or Auto Approve Strategies waves one through | system |
| Strategy Rejected | An admin rejects a pending listing. The reason is included | alert |
| Strategy Suspended | An admin suspends an approved listing. The reason is included | alert |
Reinstating a suspended listing notifies nobody. The seller's listing comes back and the only sign is the status on their creator dashboard, so tell the seller yourself when you reinstate.
If you audit backend/src/api/(ext)/trading-bot/ alone you will find four calls
— the three bot notifications and the auto-approval one. The other three
(approve, reject, suspend) sit in
backend/src/api/(ext)/admin/trading-bot/marketplace/utils.ts. Same product,
two directories.
That is the entire notification surface. A bot starting, stopping normally, opening a trade, closing a trade, hitting a stop loss, hitting a take profit, being force-stopped by you, being caught by the fleet kill switch, or having its allocation changed produces no notification at all. Neither does a strategy sale — the seller is credited silently.
The stale-bot job errors up to 200 bots per run and sends one notification per bot, and it runs every minute. A transient stall across a large fleet therefore lands as hundreds of "Became Unresponsive" alerts within a couple of minutes. That is the expected shape of an engine incident, not a bug — see Troubleshooting.
Every notification link is broken
All six titles set both their link and their View Bot / View Strategy
action to a path under /user/trading-bot/…:
/user/trading-bot/{botId}— the three bot notifications/user/trading-bot/marketplace/{strategyId}— the three listing notifications
/user/trading-bot is not a route in this build. The /user segment exists
and holds exactly three things — kyc, notification and profile — and there
is no rewrite or redirect in frontend/next.config.js that would map the rest.
A customer who clicks through lands on the 404 page.
The working paths are:
| What | Real path |
|---|---|
| One bot | /trading-bot/bot/{botId} |
| One listing | /trading-bot/marketplace/{strategyId} |
| The bot list | /trading-bot/bot |
| The seller's own listings and sales | /trading-bot/creator |
Note that the bot link is wrong twice over: it is missing the /bot/ segment as
well as carrying the phantom /user prefix. Until this is fixed, a support reply
should give the customer the real path rather than telling them to click the
notification.
The fifteen templates that are never used
NOTIFICATION_TEMPLATES in
backend/src/api/(ext)/trading-bot/utils/constants.ts maps fifteen keys onto
thirteen distinct template names — STOP_LOSS_TRIGGERED and STOP_LOSS_HIT
both resolve to trading-bot-stop-loss, and the take-profit pair does the same.
| Key | Template name |
|---|---|
BOT_STARTED |
trading-bot-started |
BOT_STOPPED |
trading-bot-stopped |
TRADE_EXECUTED |
trading-bot-trade |
STOP_LOSS_TRIGGERED · STOP_LOSS_HIT |
trading-bot-stop-loss |
TAKE_PROFIT_TRIGGERED · TAKE_PROFIT_HIT |
trading-bot-take-profit |
BOT_ERROR |
trading-bot-error |
DAILY_LIMIT_REACHED |
trading-bot-daily-limit |
DRAWDOWN_LIMIT_REACHED |
trading-bot-drawdown-limit |
STRATEGY_PURCHASED |
trading-bot-strategy-purchased |
STRATEGY_REVIEW |
trading-bot-strategy-review |
DAILY_SUMMARY |
trading-bot-daily-summary |
STRATEGY_APPROVED |
trading-bot-strategy-approved |
STRATEGY_REJECTED |
trading-bot-strategy-rejected |
None of these names appears anywhere else in the product. No seeder, no
migration, no template row, no .md or .json file mentions one — the only
other file in the repository containing them is the compiled copy of that same
constants file. They are not editable on Admin → System → Notification
Templates, because there is nothing there to edit.
So this list is not a set of messages awaiting customisation. It is a plan that was never wired up, and reading it as a feature list is the specific mistake this page exists to prevent.
The dead helper module
backend/src/api/(ext)/trading-bot/utils/integrations.ts exports seventeen
functions. Two of them are imported by anything: getPaperAccount and
resetPaperAccount, both by the two paper-account routes.
The other fifteen have no callers anywhere in the codebase:
- Ten
notify*helpers —notifyBotStarted,notifyBotStopped,notifyTradeExecuted,notifyTakeProfitHit,notifyStopLossHit,notifyBotError,notifyDailySummary,notifyStrategyApproved,notifyStrategyRejected,notifyStrategyPurchased. These are the functions that would use the templates above, and they are the only readers ofNOTIFICATION_TEMPLATES. allocateBotFunds,releaseBotFunds,processBotTrade,getUserBalanceand the module's ownupdatePaperAccount. The live money paths are elsewhere — allocation is a cap written by the allocation routes, and paper accounting runs throughOrderExecutor's ownupdatePaperAccount.
Two consequences for you. First, the wallet model described in that file's
comments is not the model that runs, so do not reason about customer money from
it. Second, if you or a developer "switch the notifications on" by calling those
helpers, they will request the EMAIL channel against templates that do not
exist — which is a change to test, not a switch to flip.
The audit trail is the history, not the inbox
The customer's notification bell is not a log of what their bot did, and it was
never going to be. The log is trading_bot_audit_log, and you read it at
Admin → Trading Bot → Audit Logs (/admin/trading-bot/logs, permission
view.trading_bot.log).
These are the action values something in the product actually writes:
| Action | Written by |
|---|---|
BOT_STARTED · BOT_STOPPED · BOT_PAUSED · BOT_RESUMED |
The engine, on each lifecycle transition |
BOT_ERROR |
The engine, on a tick error |
TRADE_OPENED |
The engine, when a position is opened |
STOP_LOSS_TRIGGERED · TAKE_PROFIT_TRIGGERED |
The engine, when an exit level fires |
DAILY_LIMIT_REACHED · DRAWDOWN_LIMIT_REACHED |
The risk path, alongside LIMIT_REACHED |
FUNDS_ALLOCATED · FUNDS_DEALLOCATED |
The allocation add/remove routes |
KILL_SWITCH_ACTIVATED |
The user's own kill-all, and the admin emergency stop — one row per bot |
The filter dropdown on the logs screen lists all 27 values of the database
column's ENUM, and fourteen of them are written by no code path in this build:
BOT_CREATED, BOT_UPDATED, BOT_DELETED, TRADE_CLOSED, TRADE_FAILED,
ORDER_PLACED, ORDER_CANCELLED, ORDER_FILLED, STRATEGY_PURCHASED,
STRATEGY_SUBMITTED, STRATEGY_APPROVED, STRATEGY_REJECTED,
ADMIN_FORCE_STOP and ADMIN_CONFIG_CHANGE.
An empty result for one of those means nothing is recorded, not that nothing
happened. In particular: a single-bot force stop
(POST /api/admin/trading-bot/bot/{id}/stop) files no admin-attributed row of
its own, so a bot stopped that way shows a BOT_STOPPED row attributed to its
owner if the bot happened to be resident in the engine, and nothing at all if it
did not. The fleet-wide emergency stop is the one admin action that does record
itself, as KILL_SWITCH_ACTIVATED with the admin in userId.
Audit rows are pruned after 90 days by the weekly cleanup job, so the trail is a 90-day window, not a permanent archive.
Orders and fills are not in the trail, and there is nowhere in the admin console
to go and read them instead. /admin/trading-bot/bot/{id} makes exactly one
call — GET /api/admin/trading-bot/bot/{id}, which returns the bot's own row plus
its owner and nothing else — so that page shows aggregate counters
(totalTrades, winning and losing, dailyTrades, profit, volume, fees), the risk
settings, the lifecycle timestamps and the strategy config. There is no trade
list and no order list on it, and no admin trades or orders endpoint exists to
call by hand. The per-trade and per-order rows are reachable only through
GET /api/trading-bot/bot/{id}/trades and …/orders, both of which check that
the caller owns the bot — an admin calling them for a customer's bot gets
"Bot not found". For a specific fill you need the customer's own screen
(/trading-bot/bot/{id}, Trades tab) or the database.
What to tell customers to rely on
Given all of the above, the honest promise is: the bot's own page is the source of truth, and the notifications are a courtesy on three failure states.
Point customers at these, in this order:
-
The bot's page —
/trading-bot/bot/{id}. Its status pill and its Trades, Settings and Allocation tabs are read from the bot's own row and its trade history, so they show what the bot did whether or not any message was ever delivered. -
The six statuses —
DRAFT,RUNNING,PAUSED,STOPPED,ERROR,LIMIT_REACHED. These are the product's actual event vocabulary, and the status is written on every transition whether or not a notification goes out. Bot status is the customer-facing explanation of all six and can be linked straight into a support reply. -
You, from the audit trail. When a customer asks "why did my bot stop on Tuesday", the answer is on
/admin/trading-bot/logsfiltered to their user — it is not in their inbox, and there is no user-facing activity feed. The user dashboard endpoint returns bots and totals only; it carries no audit entries.
Do not promise trade-by-trade alerts, daily summaries, sale notifications for sellers, or emails of any kind. None of those exists.
Related
- The admin console — the audit trail, the moderation queues and the actor column
- Bot status — the customer-facing page for the six statuses
- Running and monitoring bots — what you watch instead
- Troubleshooting — stalled bots and the five-minute watchdog