Skip to content

Task/webhooks validate v7#540

Merged
greatest0fallt1me merged 3 commits into
Predictify-org:mainfrom
Paranoa-dev:task/webhooks-validate-v7
Jul 26, 2026
Merged

Task/webhooks validate v7#540
greatest0fallt1me merged 3 commits into
Predictify-org:mainfrom
Paranoa-dev:task/webhooks-validate-v7

Conversation

@Paranoa-dev

Copy link
Copy Markdown
Contributor

feat: input validation /api/webhooks

Summary

Adds Zod-validated input schemas for all /api/webhooks endpoints, replacing inline ad-hoc validation with centralized, reusable validators. Follows the established pattern from src/validators/markets.ts and src/validators/predictions.ts.

Changes

New file: src/validators/webhooks.ts

  • listWebhooksQuerySchema -- validates GET /api/webhooks query params (cursor, limit). Uses .strict() to reject unknown params. Coerces string limits to integers with range 1-100.
  • dlqQuerySchema -- validates GET /api/admin/webhooks/dlq query params (same shape as above).
  • dlqReplayParamsSchema -- validates POST /api/admin/webhooks/dlq/:id/replay route params using Zod's .uuid() validator.

Modified: src/routes/webhooks.ts

  • Removed inline webhooksQuerySchema (regex-based string limit validation).
  • Imported listWebhooksQuerySchema from centralized validators.
  • Schema now uses z.coerce.number() for type-safe limit parsing with proper integer and range validation.

Modified: src/routes/adminWebhooks.ts

  • Added Zod validation for GET /dlq query params via dlqQuerySchema (previously raw req.query with no validation).
  • Added Zod validation for POST /dlq/:id/replay params via dlqReplayParamsSchema (replaced manual UUID regex).
  • Added structured pino logging with correlation IDs to both handlers.
  • Removed /* eslint-disable @typescript-eslint/no-explicit-any */ and replaced any cast with typed ReplayResult interface.

Bugfixes (pre-existing)

  • src/index.ts -- Fixed broken webhooksRouter import (exported createWebhooksRouter, not webhooksRouter). Router is now conditionally created via factory when options.webhooks is provided.
  • src/routes/predictions.ts -- Added missing accessLog middleware import that blocked all tests using createApp.

Tests

New file: tests/webhooksValidation.test.ts

38 tests, all passing:

Schema unit tests (19):

  • listWebhooksQuerySchema -- valid inputs, empty cursor, zero/negative/non-integer/max limit, unknown params
  • dlqQuerySchema -- empty query, valid params, unknown params, zero/max limit
  • dlqReplayParamsSchema -- valid UUID, invalid format, empty string, wrong length, non-hex chars

Integration tests (19):

  • GET /api/webhooks -- auth (403 without/with non-admin), validation (400 for bad limit/cursor/unknown params), success (200 with valid params, pagination, requestId in errors)
  • GET /api/admin/webhooks/dlq -- auth, validation for limit and unknown params
  • POST /api/admin/webhooks/dlq/:id/replay -- auth, 400 for invalid UUID, 404 for non-existent row

Validation Behavior

All endpoints now return a standardized error envelope on invalid input:

{
  "error": {
    "code": "validation_error",
    "message": "<specific Zod error message>",
    "requestId": "<correlation ID>"
  }
}

Unknown query parameters are rejected (.strict() mode) to keep route boundaries explicit and avoid silently ignoring malformed input.

Files Changed

File Action Lines changed
src/validators/webhooks.ts Added +75
src/routes/webhooks.ts Modified -15, +5
src/routes/adminWebhooks.ts Modified -15, +68
src/routes/predictions.ts Modified +1
src/index.ts Modified -4, +7
tests/webhooksValidation.test.ts Added +379

Checklist

  • Implementation matches the description
  • Tests added and passing (38/38)
  • ESLint clean
  • Follows repo conventions (factory pattern, error response shape, log events)
  • Input validation at the boundary with standardized error envelope
  • Structured logging with correlation IDs
  • Clear documentation and inline comments

Closes #433

- Add Zod schemas in src/validators/webhooks.ts for:
  - listWebhooksQuerySchema (GET /api/webhooks)
  - dlqQuerySchema (GET /api/admin/webhooks/dlq)
  - dlqReplayParamsSchema (POST /api/admin/webhooks/dlq/:id/replay)
- Refactor src/routes/webhooks.ts to use centralized validator
- Add structured logging and Zod validation to adminWebhooks.ts
- Fix broken webhooksRouter import in src/index.ts
- Fix missing accessLog import in src/routes/predictions.ts
- 38 tests covering schema unit tests and integration tests
- Tests for listWebhooksQuerySchema, dlqQuerySchema, dlqReplayParamsSchema
- Integration tests for auth, validation errors, pagination, requestId
@drips-wave

drips-wave Bot commented Jul 26, 2026

Copy link
Copy Markdown

@Paranoa-dev 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

@greatest0fallt1me

Copy link
Copy Markdown
Contributor

Merged via direct push to main (admin)

@greatest0fallt1me
greatest0fallt1me merged commit 7d39a64 into Predictify-org:main Jul 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add input validation for /api/webhooks (v7)

2 participants