docs: complete code-reality alignment for remaining docs + reconcile issue set
Remaining docs updated to match code (the docs that the first pass had not covered):
- Flows: Chat, Referral, Rating, Registration, Google OAuth, Negotiation, Payout,
Trezor Safekeeping — corrected endpoints, socket events, status enums, auth gaps
- API Reference: User API, Trezor API — admin route prefix/verb/status corrections,
added undocumented endpoints (ton-proof challenge, profile email verify,
GET /trezor/account, POST /trezor/verify-operation)
- Data Models: Chat, Notification, Payment, PointTransaction, User — corrected
enums (PaymentProvider, escrowState, PointTransaction.type, User.status),
90-day notification TTL, soft-delete semantics, wallet fields
Trezor "zero frontend" finding (audit C31/C32) corrected as STALE:
- Verified current code HAS a full frontend Trezor implementation (admin/trezor
page, TrezorSettingsView, trezorConnector via @trezor/connect-web,
TrezorSignDialog, actions/trezor.ts building the {message,signature} object)
- Fixed Trezor Safekeeping Flow doc (removed false "no frontend" warnings)
- Reclassified ISSUE-012 as invalid/superseded with explanation
Issue set reconciled to a single canonical numbering (ISSUE-001..054):
- Adopted the comprehensive 51-issue set (long-slug, fully indexed)
- Removed 35 superseded short-slug duplicates from the first pass
- Removed a duplicate ISSUE-046 file
- Added 3 issues the 51-set lacked: ISSUE-052 (completed-not-counted-in-stats),
ISSUE-053 (axios 401-only interceptor), ISSUE-054 (rate limiter counts all attempts)
- Regenerated Issues Index: 53 open (14 critical, 39 major) + 1 invalid
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -5,9 +5,9 @@ tags: [api, admin, reference]
|
||||
|
||||
# Admin API
|
||||
|
||||
> **Last updated:** 2026-05-29 — aligned with code (see [Doc vs Code Audit Report](../09%20-%20Audits/Doc%20vs%20Code%20Audit%20Report%20-%202026-05-29.md))
|
||||
> **Last updated:** 2026-05-29 — aligned with code (see Doc vs Code Audit Report)
|
||||
|
||||
There is no single `/api/admin` namespace — admin-only endpoints are scattered across the service routers. This page catalogs them in one place. All require `Bearer JWT` with `req.user.role === 'admin'`. The two enforcement patterns are:
|
||||
There is no single `/api/admin` namespace — admin-only endpoints are scattered across the service routers. This page catalogs them in one place. All require `Bearer JWT` with `req.user.role === 'admin'` unless explicitly noted otherwise. The two enforcement patterns are:
|
||||
|
||||
- Middleware: `authorizeRoles('admin')` after `authenticateToken` (used by the dispute, data-cleanup, blog routers).
|
||||
- Inline check inside the handler: `if (req.user.role !== 'admin') return 403` (used by user, points, payment routes).
|
||||
@@ -16,27 +16,31 @@ There is no single `/api/admin` namespace — admin-only endpoints are scattered
|
||||
|
||||
See full descriptions in [[User API]].
|
||||
|
||||
> **Path note:** The frontend and backend both use `/api/users/admin/*` (plural). The singular `/api/user/admin/*` paths for create/delete/status/role/list are **unreachable** — they are not mounted in the backend. Use `/api/users/admin/*` for all user-management calls.
|
||||
|
||||
| Endpoint | Action |
|
||||
| --- | --- |
|
||||
| `POST /api/user/admin/create` | Create user with role/status |
|
||||
| `DELETE /api/user/admin/:userId` | Soft delete user — sets `status='deleted'` (admins cannot delete each other) |
|
||||
| `PATCH /api/user/admin/:userId/status` | Activate / suspend |
|
||||
| `PATCH /api/user/admin/:userId/toggle-status` | Flip active flag |
|
||||
| `PATCH /api/user/admin/:userId/role` | Change role |
|
||||
| `GET /api/user/admin/list` | Paginated directory + stats |
|
||||
| `GET /api/user/admin/:userId/dependencies` | Pre-delete dependency check |
|
||||
| `POST /api/users/admin/create` | Create user with role/status |
|
||||
| `DELETE /api/users/admin/:userId` | Soft delete user — sets `status='deleted'` (admins cannot delete each other) |
|
||||
| `PATCH /api/users/admin/:userId/status` | Activate / suspend |
|
||||
| `PATCH /api/users/admin/:userId/toggle-status` | Flip active flag |
|
||||
| `PATCH /api/users/admin/:userId/role` | Change role |
|
||||
| `GET /api/users/admin/list` | Paginated directory + stats |
|
||||
| `GET /api/users/admin/:userId/dependencies` | Pre-delete dependency check |
|
||||
| `GET /api/users/admin/stats` | Aggregate user analytics |
|
||||
| `GET /api/users/admin/:userId` | Full user detail (admin view) |
|
||||
| `PUT /api/users/admin/:userId` | Mass update user |
|
||||
| `PUT /api/users/admin/update/:email` | Mass update by email |
|
||||
| `PATCH /api/users/admin/:userId/password` | Force password reset (wipes refresh tokens) |
|
||||
| `POST /api/users/admin/:userId/resend-verification` | Resend verification email |
|
||||
| `POST /api/users/admin/:userId/resend-verification` | Resend verification email (legacy route — uses 8-digit codes) |
|
||||
|
||||
> **Verification code length:** The endpoint `POST /api/users/admin/:userId/resend-verification` is served by the legacy userRoutes and generates **8-digit** codes. The new userController generates 6-digit codes and is reached via a different path. Both coexist; the legacy route takes precedence for this path.
|
||||
|
||||
**⚠️ KNOWN BUG — HTTP verb mismatch (status/role updates):** The frontend Redux actions for `updateUserStatus` and `updateUserRole` send `PUT` requests, but the backend registers these handlers under `PATCH`. These calls will receive `404 Method Not Found` responses until the frontend is corrected to use `PATCH`.
|
||||
|
||||
**⚠️ KNOWN BUG — Status value mismatch:** The frontend sends `'inactive'` and `'pending'` as status values when updating user status. The backend only accepts `'active'`, `'suspended'`, or `'deleted'`. Sending `'inactive'` or `'pending'` will be rejected or silently ignored.
|
||||
|
||||
**Hard vs. soft delete note:** The legacy route `DELETE /users/admin/:id` performs a **hard delete** (`findByIdAndDelete`). The current route `DELETE /api/user/admin/:userId` performs a **soft delete** (sets `status='deleted'`). Always use the current `/api/user/admin/:userId` route to preserve data integrity.
|
||||
**Hard vs. soft delete note:** The legacy route `DELETE /users/admin/:id` performs a **hard delete** (`findByIdAndDelete`). The current route `DELETE /api/users/admin/:userId` performs a **soft delete** (sets `status='deleted'`). Always use the current `/api/users/admin/:userId` route to preserve data integrity.
|
||||
|
||||
## Listing / marketplace moderation
|
||||
|
||||
@@ -80,6 +84,22 @@ See [[Payment API]].
|
||||
|
||||
**⚠️ Path correction:** Release/refund routes do **not** include a `/shkeeper/` segment. The correct paths are `/api/payment/:id/release`, `/api/payment/:id/release/confirm`, etc. (Previously documented incorrectly as `/api/payment/shkeeper/:id/…`.)
|
||||
|
||||
## Derived destinations & sweep
|
||||
|
||||
Frontend page: `/dashboard/admin/derived-destinations`. Backend registers 7 endpoints under `/api/payment/derived-destinations/*` with admin auth.
|
||||
|
||||
| Endpoint | Action |
|
||||
| --- | --- |
|
||||
| `GET /api/payment/derived-destinations` | List all derived destination addresses |
|
||||
| `POST /api/payment/derived-destinations/sweep/trigger` | Trigger a sweep across all destinations |
|
||||
| `POST /api/payment/derived-destinations/sweep/trigger/:id` | Trigger sweep for a single destination |
|
||||
| `GET /api/payment/derived-destinations/sweep/cron/status` | Get sweep cron job status |
|
||||
| `POST /api/payment/derived-destinations/sweep/cron/start` | Start the sweep cron job |
|
||||
| `POST /api/payment/derived-destinations/sweep/cron/stop` | Stop the sweep cron job |
|
||||
| `GET /api/payment/derived-destinations/sweep/history` | Sweep history log |
|
||||
|
||||
> Frontend action functions: `getDerivedDestinations`, `triggerSweep`, `triggerSingleSweep`, `getSweepCronStatus`, `startSweepCron`, `stopSweepCron`.
|
||||
|
||||
## Points (admin)
|
||||
|
||||
See [[Points API]].
|
||||
@@ -140,12 +160,58 @@ Router: [`backend/src/services/admin/dataCleanupRoutes.ts`](../../backend/src/se
|
||||
### GET /api/admin/scanner/status
|
||||
|
||||
**Description:** Returns the current state of the blockchain scanner / wallet monitor.
|
||||
**⚠️ SECURITY BUG — NO AUTHENTICATION:** Despite being mounted under `/api/admin/` and documented as admin-only, this endpoint has **no** `authenticateToken` or `authorizeRoles` guard. Any unauthenticated request can read scanner state.
|
||||
|
||||
> ⚠️ **NOT IMPLEMENTED:** The following endpoints do not exist in the codebase:
|
||||
> - `GET /api/admin/settings/confirmation-thresholds/history` — only the current-values `GET /api/admin/settings/confirmation-thresholds` and per-chain `PATCH /api/admin/settings/confirmation-thresholds/:chainId` exist.
|
||||
> - `POST /api/admin/rn/networks/reload` — the network registry cannot be reloaded at runtime via HTTP.
|
||||
> - `POST /api/admin/rn/networks/probe/:chainId` — no per-chain probe endpoint exists.
|
||||
> **⚠️ SECURITY BUG — NO AUTHENTICATION:** Despite being mounted under `/api/admin/`, this endpoint has **no** `authenticateToken` or `authorizeRoles` guard. Any unauthenticated request can read scanner state.
|
||||
|
||||
## Settings
|
||||
|
||||
### AML settings
|
||||
|
||||
> **⚠️ RUNTIME-ONLY PERSISTENCE:** `PATCH /api/admin/settings/aml` updates `process.env` at runtime only. Changes are **lost on server restart**. There is no frontend page for these endpoints.
|
||||
|
||||
| Endpoint | Auth | Action |
|
||||
| --- | --- | --- |
|
||||
| `GET /api/admin/settings/aml` | admin | Read current AML settings |
|
||||
| `PATCH /api/admin/settings/aml` | admin | Update AML settings (runtime only — not persisted to disk or DB) |
|
||||
|
||||
### Confirmation thresholds
|
||||
|
||||
Frontend page exists. Endpoints require admin auth.
|
||||
|
||||
| Endpoint | Action |
|
||||
| --- | --- |
|
||||
| `GET /api/admin/settings/confirmation-thresholds` | Get current confirmation thresholds for all chains |
|
||||
| `PATCH /api/admin/settings/confirmation-thresholds/:chainId` | Update threshold for a specific chain |
|
||||
|
||||
> **Not implemented:** `GET /api/admin/settings/confirmation-thresholds/history` — history endpoint does not exist. `POST /api/admin/rn/networks/reload` and `POST /api/admin/rn/networks/probe/:chainId` do not exist.
|
||||
|
||||
## Payments awaiting confirmation
|
||||
|
||||
Frontend page exists.
|
||||
|
||||
| Endpoint | Auth | Action |
|
||||
| --- | --- | --- |
|
||||
| `GET /api/admin/payments/awaiting-confirmation` | admin | List payments pending blockchain confirmation |
|
||||
|
||||
## RN network registry
|
||||
|
||||
Frontend page exists.
|
||||
|
||||
| Endpoint | Auth | Action |
|
||||
| --- | --- | --- |
|
||||
| `GET /api/admin/rn/networks` | admin | List all registered RN networks |
|
||||
|
||||
## Blog admin
|
||||
|
||||
Backend registers 5 blog admin endpoints, all guarded by `authorizeRoles('admin')`. Frontend has action functions calling each.
|
||||
|
||||
| Endpoint | Action |
|
||||
| --- | --- |
|
||||
| `GET /api/blog/admin/posts` | List all blog posts (admin view, includes drafts) |
|
||||
| `POST /api/blog/posts` | Create a new blog post |
|
||||
| `GET /api/blog/admin/posts/:id` | Get a single blog post (admin view) |
|
||||
| `PUT /api/blog/posts/:id` | Update a blog post |
|
||||
| `DELETE /api/blog/posts/:id` | Delete a blog post |
|
||||
|
||||
## Analytics
|
||||
|
||||
|
||||
Reference in New Issue
Block a user