# Admin Panel frontend

Release: **0.19.1**, Phase 19.

## Open and sign in

After installing dependencies with `npm ci`, configuring the environment, applying migrations/seeds, and starting the web process, open `/admin` on the configured application origin. Use the administrator provisioned by the existing secured `npm run admin:create` setup procedure. Sign in with email/password, then an authenticator code or an unused recovery code. No default account or password is included.

Admin session cookies remain HttpOnly; CSRF tokens stay in memory. Tokens, passwords, payout details and records are never stored in browser storage. Signing out revokes the server session and clears the interface. Session expiry returns to sign-in and late responses cannot repopulate a previous session. Browser back/forward cache restoration reauthenticates.

The public HTML shell contains no private account data. It cannot be framed. Admin API requests still enforce IP allowlisting, permissions, CSRF, maintenance policy and server validation.

## Workspaces

The catalog contains 34 resource workspaces plus the Overview page; each account sees only its granted workspaces and actions.

| Area               | Available operations                                                                                                                                                                        |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Overview           | Operational totals, financial report under its separate permission, daily table/chart, task statistics, rollup history; UTC range up to 366 days                                            |
| Users              | Search/filter, profile/metrics/wallet reads, scoped ban/unban and session revocation                                                                                                        |
| Tasks              | Draft creation, edit, publish, pause, archive; categories; attempt review                                                                                                                   |
| Referrals          | Search/filter, detail/history, review and referral rules                                                                                                                                    |
| Withdrawals        | Search/filter, request/history/approval detail, hold/approve/reject, explicit account reveal and manual payment confirmation                                                                |
| Withdrawal methods | Create/edit, activate/deactivate, add/edit structured account fields and global rules                                                                                                       |
| Free reward boxes  | Create/edit, free reward items, inventory and eligibility, publish/pause/end/archive, claim history                                                                                         |
| Banners            | Create/edit, verified media picker, schedule, publish/pause/archive                                                                                                                         |
| Announcements      | Create/edit, target audience, schedule, publish/expire/archive                                                                                                                              |
| Tutorials          | Create/edit plain content, cover picker, video URL, publish/archive                                                                                                                         |
| Bot messages       | Template editor, supported formatting toolbar, variables, buttons, server preview, publish/archive                                                                                          |
| Broadcasts         | Create draft; inspect audience/template/schedule; approve by a different administrator; cancel; delivery counts                                                                             |
| Reminders          | Create/edit schedule, IANA timezone, local time, days, audience and template; activate/pause/archive                                                                                        |
| Configuration      | General settings, managed links, feature flags, themes, currencies and maintenance windows                                                                                                  |
| Media              | Verified image upload, gallery, metadata and image picking                                                                                                                                  |
| Operations         | Immutable ledger/entries, administrator invitations/access, custom roles/grants, audit/security logs, fraud review, wallet adjustments, delivery status, failed-job retry and system health |

## Editing and review

Editors are derived from the backend's input schemas. Cross-field business checks remain server-side. Optional fields have three distinct meanings: keep unchanged/use default, set a value, or clear a nullable value. Nested objects and arrays use structured controls. Backend-owned versions are carried with the submitted snapshot. Monetary minor units remain decimal strings; **1050** represents **10.50** only when that currency has two decimal places.

Create/edit and lifecycle actions show a review screen before sending. Withdrawal confirmation includes the request, amount, fee, payout amount and approval progress. Broadcast approval repeats the template, audience and schedule. A stale version, network uncertainty or server error keeps the review visible and blocks immediate resubmission; close and refresh to inspect the current record. Requests are never retried automatically. Concurrent identical mutations share one request.

Payout account details are fetched only after an explicit reveal confirmation. The reveal is audited and removed on dialog close, tab hiding, route change or logout. Confirm-paid records a payment already performed through the configured manual process; it does not initiate a bank/provider payment.

Tutorials and announcements accept **plain text**. Existing safe HTML is converted back to plain text for editing so repeated saves do not double-encode it. Bot templates use their existing allowed Telegram HTML syntax. The preview displays the server-rendered template text and button configuration without executing markup.

Filters are sent only to endpoints supporting them. Endpoints without pagination retain their existing bounded list contract; their search is labelled as applying to loaded records. Refresh reloads the authoritative response. Arrays, identifiers and long text remain readable in detail dialogs. Layout includes a compact mobile menu, dark/light appearance, keyboard focus indicators, semantic tables, native dialogs, live status announcements and reduced-motion rules.

## Media upload

`POST /api/v1/admin/console/media/upload` accepts strict JSON containing `original_name`, `mime_type` and `content_base64`. The larger body allowance applies **only** to this exact POST path, after CSRF, administrator authentication, IP allowlisting and `media.manage`; other routes keep the normal body limit. The route also applies the existing sensitive rate limit.

The server checks the existing deployment byte/pixel/MIME limits, a PNG/JPEG/WebP signature, actual decoder format and a single frame. Sharp decodes and re-encodes pixels with metadata removed, auto-orients and fits within 2560 × 2560 without enlargement. A process accepts at most two concurrent image jobs, with a decoder timeout. Original upload bytes are not published. Verified bytes are staged under the configured quarantine directory, atomically moved to a generated public path, hashed and inserted as a verified media row. The existing public gateway checks row visibility, size and SHA-256 before serving.

Public and quarantine directories must reside on the same filesystem for atomic rename and be writable by the web process. Serve images through the media gateway; do not expose the storage directory directly. An uncertain database insert can leave an unreferenced generated file: it remains inaccessible through the gateway. Reconcile such orphans against committed media rows during maintenance before removing them. No automatic deletion follows an uncertain insert.

Sharp is an exact-pinned native dependency. Use `npm ci` with optional packages enabled on the target platform so its matching native binary is installed. If the host cannot load it, use a compatible Node host; do not skip image verification.

## API additions and read boundaries

All new routes use `/api/v1/admin/console`:

| Route                                        | Permission                                                          |
| -------------------------------------------- | ------------------------------------------------------------------- |
| `GET /catalog`                               | Authenticated administrator; output filtered by granted permissions |
| `GET /administrators`, `/administrators/:id` | `administrators.view`                                               |
| `GET /roles`, `/roles/:id`                   | `administrators.view`                                               |
| `GET /ledger`, `/ledger/:id`                 | `ledger.view`                                                       |
| `GET /audit-logs`                            | `audit_logs.view`                                                   |
| `GET /security-events`                       | `security_events.view`                                              |
| `GET /fraud-monitor`                         | `fraud.view`                                                        |
| `GET /media`, `POST /media/upload`           | `media.manage`                                                      |
| `GET /deliveries`                            | `notifications.view`                                                |
| `GET /failed-jobs`, `GET /health`            | `system_health.view`                                                |

Operational lists allow `page`, `page_size` (up to 100), and bounded `search`. They use fixed SQL projections, bound values and escaped LIKE wildcards. Password hashes, session secrets, raw message payloads, storage paths, raw security evidence, IP addresses and raw audit before/after state are excluded. Reads are audited. `/health` is a database/outbox snapshot, not a worker or provider availability guarantee.

No new database migration or environment variable is required. Existing financial, task, referral, notification and free-only reward services remain authoritative.

## Known implementation boundaries

Release 0.19.1 implements the original management APIs and the five missing administration workflows: invitations and role management, scoped restrictions/session control, fraud review, controlled wallet corrections and manual failed-job retry. Initial super-admin provisioning remains a secured CLI operation; additional administrators use the invitation flow.

Content uses the existing editor semantics, not an unrestricted HTML CMS. Dashboard reports do not add a separate administrator leaderboard editing service. Branding, secrets and deployment settings remain within the existing configuration model; no bot/database secret is editable through this panel.

## Verification and acceptance

Run `npm run check`. Phase 19 adds HTTP middleware integration tests with injected repositories, DOM interaction tests in jsdom, and real Sharp image-processing tests. jsdom tests do not prove browser layout, native dialog focus trapping, image decoding on devices or keyboard/screen-reader behavior.

Before production acceptance, run the full application against staging MySQL/Redis and real HTTPS cookies; verify role-specific workflows, TOTP/recovery, permission revocation, maintenance access, image upload/serving, dual approvals and worker delivery. Browser/device visual checks, deployment, load tests and real provider/payout tests are separate acceptance work. This task did not send real broadcasts, alter live payouts or deploy the application.

Implementation references: [Zod input JSON schemas](https://zod.dev/json-schema), [native HTML dialog](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/dialog), [Sharp input safety controls](https://sharp.pixelplumbing.com/api-constructor/), [Sharp output encoding](https://sharp.pixelplumbing.com/api-output/).

## Completed management operations

The five 0.19.0 management gaps are implemented in 0.19.1. See [Phase 19 completion report](PHASE-19-COMPLETE-REPORT.md) for invitation enrollment, independent wallet review, scoped restrictions, fraud evidence, manual retries, permissions and the required migration 023 upgrade.
