Skip to content

fix(backend): auth gate strategy switch, read real audit and export data, secure metrics, and unify error responses - #1650

Merged
Junirezz merged 2 commits into
Junirezz:mainfrom
serverlessdomain-hash:feat/batch-1605-1606-1607-1611
Oct 19, 2026
Merged

Junirezz merged 2 commits into
Junirezz:mainfrom
serverlessdomain-hash:feat/batch-1605-1606-1607-1611

Conversation

@serverlessdomain-hash

Copy link
Copy Markdown
Contributor

Description

This pull request resolves issues #1605, #1606, #1607, and #1611 in Junirezz/YieldVault-RWA:

  1. Gate Strategy Switch Behind Auth & Store Cooldown in DB/Redis (Closes [backend] Gate POST /vault/strategy behind auth and move cooldown state out of process.env #1605):

    • Gated POST /vault/strategy behind authentication: requires either an admin ApiKey or a signed wallet action (action: 'strategy'), returning 401 for unauthenticated calls.
    • Replaced process.env.LAST_STRATEGY_SWITCH_TIME with persistent cooldown tracking stored in Prisma (AdminConfigChange) and Redis (vault:strategy:last_switch).
    • Returns HTTP 429 with Retry-After header when the switch interval has not elapsed.
  2. Read Real Data for Audit Logs and Transaction Exports (Closes [backend] Remove or gate public routes serving fabricated audit and transaction export data #1606):

    • /api/v1/audit-logs now gates on validateApiKey and reads real prisma.adminAuditLog records (with action/actor filtering and pagination) instead of generating synthetic logs.
    • Transaction export now queries prisma.transaction directly with the exact same filters (type, status, date range, wallet address) as /transactions, fully removing MOCK_TRANSACTIONS.
    • Eliminated shadowed duplicate export route registration in listEndpoints.ts.
  3. Secure /metrics Behind Scrape Token & Clean Up Metrics Catch Block (Closes [backend] Require auth on /metrics, remove per-vault labels, and fix its error path #1607):

    • Secured GET /metrics behind scrape credential check (METRICS_AUTH_TOKEN, METRICS_SCRAPE_TOKEN, or PROMETHEUS_BEARER_TOKEN) accepting Bearer or ApiKey headers. Returns 401 text/plain when configured and unauthenticated.
    • Handles exceptions in metrics collection by returning HTTP 500 text/plain with the error message.
    • Documented scrape credential settings in .env.example and docs/OPERATIONAL_METRICS.md.
  4. Unify Error Handling via sendApiError & Type Boundary Cleanups (Closes [backend] Unify the error response contract and remove any-typed error handling #1611):

    • Replaced raw error responses and inline error literals in routers (listEndpoints.ts, referralEndpoints.ts, walletAliasEndpoints.ts, transactionEndpoints.ts, vaultEndpoints.ts, etc.) with sendApiError.
    • Admin email replay (POST /admin/emails/replay/:id) now only returns 404 for actual missing emails (NotFoundError or P2025), and returns 500 for general database failures.
    • Replaced any casts in errorBoundary.ts and payloadLimit.ts with unknown and strict type guards.

Closes #1605
Closes #1606
Closes #1607
Closes #1611

…ata, secure metrics, and unify error responses
@drips-wave

drips-wave Bot commented Oct 17, 2026

Copy link
Copy Markdown

@serverlessdomain-hash Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Junirezz
Junirezz merged commit 40624cd into Junirezz:main Oct 19, 2026
13 of 24 checks passed
const authHeader = req.get('Authorization') || req.get('authorization') || '';
const apiKeyHeader = req.get('x-api-key');
let providedKey = apiKeyHeader;
const match = authHeader.match(/^ApiKey\s+(.+)$/i) || authHeader.match(/^Bearer\s+(.+)$/i);
const authHeader = req.get('Authorization') || req.get('authorization') || '';
const apiKeyHeader = req.get('x-api-key');
let providedKey = apiKeyHeader;
const match = authHeader.match(/^ApiKey\s+(.+)$/i) || authHeader.match(/^Bearer\s+(.+)$/i);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants