Use the debug console
Control the clock, drive the scheduler by hand, read state, and reset a demo database safely.
Owned by Admin · 11 steps · about 20 minutes
Why this exists
Almost everything interesting on this platform happens on a schedule: holds expire, tiers cascade, payouts mature, tabs settle at a month boundary, tax packages generate at a quarter boundary. Waiting for real time to demonstrate any of that is impossible, so the platform ships two levers instead of sleep-based hacks: a clock override and a manual scheduler tick.
They are separate on purpose. Moving the clock changes what the platform believes "now" is; it does not make anything happen. The scheduler tick is what actually runs the handlers. Nearly every confusing training moment — "I set the date to next month and nothing settled" — is those two being conflated. Set the clock, then tick.
The whole tree is gated three ways: it 404s entirely when debug endpoints are disabled (the routes do not exist, so a probe cannot even learn they are there), it requires an admin group, and every non-GET call is recorded in an append-only debug audit log with its parameters. Debug is not a back door; it is a front door with a camera on it.
The database reset is guarded by environment as well: it refuses outright in prod, and it wants a typed confirmation everywhere else. It drops every table, re-runs the schema and re-seeds the core data — so it is the right tool before a demo and a catastrophe during one.
Before you start
- An admin session and debug endpoints enabled — otherwise every route here is a 404.
- A non-production environment. The reset refuses in prod, and the clock override should never be used against real customers.
Practise with
| Persona | Password | Note | |
|---|---|---|---|
| admin | admin@club.test | admin123 | the only persona for whom /debug exists at all |
Steps 1–11 — Admin
their manual →-
1Open the debug console. The card at the top gives you the environment, the database path, the schema version and the current clock override, plus the two controls you will use most.Expected result A Set Clock form, a Clear button, and a Run Scheduler Tick button that report their JSON result in place.Watch out for The Registered debug routes table below renders empty in this build — the route index only walks top-level routes and this version of the framework nests them. The forms work; the directory does not. Navigate to module debug endpoints by URL or from the admin hub. FILED 2026-08-30 as plan 679. This paragraph was written on 2026-08-07 with the manual itself and had been the only record of the defect since: measured, app.routes holds 68 Mount and _IncludedRouter objects and zero paths beginning /debug, so the filter can never match. Delete this sentence and the two before it when 679 lands.
-
2Set the platform clock to a specific instant using the full UTC format, for example the first day of next month at midnight.Expected result The override is stored and every timestamp the platform writes from now on comes from it.Watch out for A malformed timestamp is 400 bad_timestamp. And setting the clock alone changes nothing else: no handler runs until you tick.
-
3Run a tick. This is what actually executes the handlers: order-hold expiry, idle-cart abandonment, the event lifecycle, marketing, resale, payout release, monthly tab settlement and quarterly tax filings.Expected result A scheduler run row with a per-handler result.Watch out for You can pass an explicit now to a tick instead of moving the clock, which is often cleaner. Handlers run in sorted-name order, so events runs before marketing — that ordering is why a tier cascade and the social post announcing it can land in the same tick.
-
4Read the recent runs and their handler output when a tick did not do what you expected.Expected result Recent runs newest first with their results.Watch out for A handler that reported nothing usually had nothing due. Check your clock before you suspect the handler.
-
5Dump the whole environment: database path, schema version, clock override, row counts for every table, and every setting.Expected result One response that answers most 'is this database the one I think it is' questions.Watch out for Row counts are the fastest way to spot a database you have not seeded. If the counts are near zero, stop debugging and seed.
-
6List the platform settings with their values, then change one with the settings endpoint when you need to steer behaviour rather than data.Expected result Every setting row, and the updated row after a change.Watch out for Settings are real configuration, not scratch space. Changing a ledger threshold or a tax scheduler flag to make a demo work will still be changed tomorrow when someone else is demoing something else.
-
7Set one setting by key, sending the new value.Expected result The stored row with its new value and who updated it.Watch out for Internal markers exist here that you should not touch by hand — the ledger's last-settled-period marker is one. Changing it will make settlement skip or repeat a month.
-
8Read the outbound wire log: every call the platform made to a mock payment processor, Telegram, a wallet, the mail house or a social network, with its request and response.Expected result Recent calls, filterable by service, method and correlation id.Watch out for This is the single place to answer 'did we actually send it'. Filtering by correlation id gets you the whole story of one package, order or post.
-
9Read the debug audit log and see your own non-GET debug calls recorded with their parameters.Expected result Action names prefixed with the module, plus the body you sent.Watch out for Append-only, like every audit table here. Assume anything you do under /debug is on the record, because it is.
-
10When a demo database is beyond saving, reset it: send the typed confirmation and it drops every table, re-applies the schema and re-seeds core data.Expected result Confirmation that the reset ran.Watch out for 403 env_forbidden in prod, and 400 without the exact confirmation word. It does NOT run the module seed hooks — run the seeder afterwards if you want demo events, credit and training content back.
-
11Clear the clock override when you are finished, by sending a null value.Expected result The override is removed and the platform returns to real time.Watch out for This is the step everyone skips. A left-behind clock override is the single most common cause of 'the platform has gone mad' the next morning — expired sessions, reservations that will not hold, invariants that report impossible times.