Admin Console

Manage your platform, users and content in one place.

New topic
All topics
HeaderCat.MsgStatusViews
Topics posted by users - click Edit to review, adjust and activate
HeaderByStatus
Users - toggle login access
UsernameNameEmailRolePRO TierVerifiedNotifyLogin enabled
PRO members

Everyone currently holding PRO. Admins are not listed — their access comes from the role, not from this flag, which is why the count matches the tile on the PRO subscription card. A paid member can be refunded from the payments console; a comped or unknown member has no payment to refund and is withdrawn with the switch in the Users tab.

UsernameEmailVerifiedTierSource Granted byGrantedCountry
Java runtimes - which JDK images this server can actually run

The compiler checks each version's container image once and remembers the answer, so pulling an image on the host does not take effect until this is re-checked (or the backend restarts). Pull with docker pull eclipse-temurin:21-jdk, then press Re-check images.

Press Re-check images to look.
Online-compiler projects - view code, download, enable/disable
NameTypeOwnerFilesCreated Enabled
Premium projects - price, package and access
NameCategoryLevelPrice StatusBuyersPackage
Page access counts - project downloads have their own tab
PageAccessesLast access
Kafka starter projects - Maven and Gradle downloads from the Kafka API Listener and Producer
Project downloads - one row per downloadable file
CourseFileDownloadsShareLast download

Loading audience data…

By country
Country Views Share
Loading…
Page × country
Page Country Views Last view
Loading…
Credit tokens
Username or email — either is looked up.

The grant is immediate and cannot be undone from this console — there is no debit endpoint. Both the user and you get an in-app notification, and the credit is written to the token ledger as ADMIN_CREDIT with your username on it.

Credited in this session 0 Cleared when you reload
UserCredited New balanceAt
Nothing credited yet.
Pending orders
Loading…
A row here means a checkout was started, not that money moved. Fresh rows are usually just an open tab. Anything older than an hour is worth checking against the RazorPay dashboard by its order id — if the payment was captured there but the order is still listed here, that customer paid and received nothing. Rows are removed automatically after 7 days.
AgeOrder idUserKind AmountTokensStarted
Loading…
Payment errors
Loading…
ALERT rows are attack-shaped — a signature that could not have come from RazorPay, a payment they say was never captured for what we billed, or an order verified by the wrong account. WARN rows are usually the gateway being unreachable. Expand a row for RazorPay's own response. Note that declined cards are not here: those are handled entirely by RazorPay and never reach this server.
WhenTypeUserOrder Amount
Loading…
Messages
Loading…
— the message is safe here, but the notification email never left. Worth checking your mail configuration.
Authenticator app
Loading…
Codes are generated on your phone from a shared secret and the clock — nothing is sent, so this keeps working when email does not. Email codes stay available; this adds a second way in, it does not replace the first.
  1. In Google Authenticator, Authy or 1Password choose add account → enter a setup key, and type this key:
    Account: your admin email · Type: time-based
  2. Save your recovery codes — shown once, never again. Print them or put them in a password manager.
    
                            
                          
  3. Enter the current 6-digit code to finish:
If the account is already in your authenticator, just enter its current code. If it isn't, use Start over below for a fresh key — that issues ten new recovery codes and voids the old ten.
Recovery codes
unused codes remaining

Each code works once. If you run low, re-run setup — it issues a fresh ten and voids the old set. If you lose both the phone and the codes, the recovery path is a DELETE against admin_mfa on the database, documented in db/admin-mfa.sql.

Every switch here is global and takes effect immediately — no redeploy, and no restart. Each one is enforced on the server, so hiding a page is never what stops it.

Developer Lab Limits

Effective immediately on the next request that reads them — nothing is cached. Each field shows the range the server accepts; anything outside it is refused, so a mistyped digit cannot take the sandboxes down.

Loading limits…

AI interviewer engine - global, takes effect on the next question
Loading engines…

Which model conducts the mock interviews on ai-interview.html. Switching costs nothing and needs no redeploy - an interview already in progress simply finishes on the new engine, because the transcript is stored here rather than at either vendor. An engine that is not reachable is shown as unavailable; selecting it anyway is allowed, so you can pick it before starting the model server.

PRO subscription
checking
Price, India
Price, international
PRO members
Sold on

The price is not editable here. It is read from PRO_PRICE_INR and PRO_PRICE_USD in the backend environment (and the bundled run tokens from PRO_TOKENS_INR / PRO_TOKENS_USD), so changing it means an env change and a restart. The figures above are fetched live from /api/payment/pro/price, so they are what a customer is actually being charged right now — not what any config file on your laptop says.

To stop new PRO sales use the PRO upgrades switch in Site settings above; to give or withdraw PRO for one person use the switch in the Users table below. Turning sales off never affects anyone who has already paid.

Learn courses
loading

Switching a course off removes it from the Learn hub, from its own URL and from the reading order — on the next page load, with no redeploy. It is a listing control, not access control: free lesson content is static JavaScript that a determined visitor can still fetch directly. Anything that must not be readable belongs behind the PRO or paid-course gate instead.

No courses match.
Project downloads
loading

Everyone — anyone, signed in or not. PRO only — PRO members and admins. Off — admins only, so a bundle can be withdrawn without deleting it. Takes effect on the next page load.

This currently controls the listing, not the file. These bundles are static files the frontend serves directly, so anyone holding a downloads/….zip URL can still fetch it whatever is set here. Making this real access control requires serving them through an authenticated endpoint — see the note in DownloadAccessService.
No downloads match.