Skip to content

fix: validation in client api#7206

Merged
Dhruwang merged 8 commits intomainfrom
fix/response-validation-in-client-api
Feb 6, 2026
Merged

fix: validation in client api#7206
Dhruwang merged 8 commits intomainfrom
fix/response-validation-in-client-api

Conversation

@Dhruwang
Copy link
Copy Markdown
Member

@Dhruwang Dhruwang commented Feb 5, 2026

Problem

Validation rules were not being applied when creating or updating responses through the client APIs (/api/v1/client and /api/v2/client). While the management APIs correctly validated response data against survey validation rules, the client API endpoints were missing this validation logic entirely.

Additionally, client APIs receive partial responses as users progress through surveys (incremental updates), which required special handling to avoid false "required" errors for questions the user hasn't reached yet.

Solution

1. Enhanced validateResponseData function

Updated the shared validateResponseData function to support partial response validation by adding a finished parameter:

  • When finished: false (in-progress): Only validates fields that are present in the current payload, preventing "required" errors for unanswered questions
  • When finished: true (completed): Validates all fields to ensure the entire survey is complete and valid

2. Centralized validation functions

Moved all validation-related functions to a shared location (apps/web/modules/api/lib/validation.ts) since they're used by both v1 and v2 APIs (client and management):

  • validateResponseData - Core validation logic (shared)
  • formatValidationErrorsForV2Api - Formats errors for v2 management APIs (returns ApiErrorDetails[])
  • formatValidationErrorsForV1Api - Formats errors for v1 APIs and v2 client APIs (returns Record<string, string>)

3. Added validation to client API endpoints

Implemented validation in all client API response endpoints:

POST endpoints (create response):

  • apps/web/app/api/v1/client/[environmentId]/responses/route.ts
  • apps/web/app/api/v2/client/[environmentId]/responses/route.ts

PUT endpoints (update response):

  • apps/web/app/api/v1/client/[environmentId]/responses/[responseId]/route.ts
  • apps/web/app/api/v2/client/[environmentId]/responses/[responseId]/route.ts (re-exports v1 handler)

4. Updated management API endpoints

Updated management API endpoints to explicitly pass finished: true to maintain existing behavior:

  • apps/web/modules/api/v2/management/responses/route.ts
  • apps/web/modules/api/v2/management/responses/[responseId]/route.ts
  • apps/web/app/api/v1/management/responses/route.ts
  • apps/web/app/api/v1/management/responses/[responseId]/route.ts

Changes

Files Modified

  1. Created: apps/web/modules/api/lib/validation.ts

    • Moved and enhanced validation functions from management API folder
    • Added finished parameter support to validateResponseData
    • Renamed formatValidationErrorsForApiformatValidationErrorsForV2Api for clarity
  2. Updated: All client API response routes (v1 and v2)

    • Added validation calls before creating/updating responses
    • Properly handle partial responses using finished flag
  3. Updated: All management API response routes (v1 and v2)

    • Updated to use shared validation functions
    • Explicitly pass finished: true for full validation
  4. Updated: Test file

    • Moved to apps/web/modules/api/lib/validation.test.ts
    • Updated to use new function signatures
    • Added tests for partial validation (finished: false)
  5. Deleted: apps/web/modules/api/v2/management/responses/lib/validation.ts

    • Functions moved to shared location

Files Deleted

  • apps/web/modules/api/v2/management/responses/lib/validation.ts (moved to shared location)
  • apps/web/app/api/v2/client/[environmentId]/responses/lib/validation.ts (no longer needed, using shared function)

Testing

All existing tests pass, including:

  • ✅ 14 tests in modules/api/lib/validation.test.ts
  • Tests cover validation logic, error formatting, and partial response handling

Impact

  • Client APIs now validate responses according to survey validation rules
  • Partial responses work correctly - users can progress through surveys without false validation errors
  • Code is DRY - single source of truth for validation logic
  • Better organization - validation functions in shared location accessible to all APIs
  • Backward compatible - management APIs continue to work as before

Example

Before: A client API request with invalid email format would succeed without validation.

After: The same request now returns a proper validation error:

{
  "code": "bad_request",
  "message": "Validation failed",
  "details": {
    "response.data.email": "Please enter a valid email address"
  }
}

Fixes https://github.com/formbricks/internal/issues/1306

@Dhruwang Dhruwang requested a review from pandeymangg February 5, 2026 05:46
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 5, 2026

Walkthrough

This pull request adds server-side validation of response data across multiple API endpoints. Validation checks are introduced in v1 and v2 client and management response handlers, occurring before response creation or updates. The validation utilities are consolidated from v2-specific paths to a unified location at @/modules/api/lib/validation. The validateResponseData function signature is extended with a finished boolean parameter to control validation behavior—when finished is false, only present fields are validated; when true, all fields are validated. Additionally, formatValidationErrorsForApi is renamed to formatValidationErrorsForV2Api to clarify its usage context. Validation failures return formatted error responses that short-circuit further processing.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: validation in client api' directly and clearly summarizes the main objective of the PR, which is to add validation to client API endpoints. It follows Conventional Commits format and is concise.
Description check ✅ Passed The PR description is comprehensive and well-structured. It covers the problem statement, solution details, specific changes, testing, and impact. It includes the issue number and follows the expected structure from the template.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/web/app/api/v1/client/[environmentId]/responses/route.ts (1)

121-144: ⚠️ Potential issue | 🟠 Major

Add "other option length" validation to V1 client POST route.

This endpoint validates file uploads and response data but is missing validateOtherOptionLengthForMultipleChoice, which is present in the V2 client POST route (line 97) and V1 client PUT route (line 98). Without this validation, responses with "other" options exceeding the character limit can be created through this endpoint while being rejected by other endpoints.

🤖 Fix all issues with AI agents
In `@apps/web/app/api/v2/client/`[environmentId]/responses/route.ts:
- Around line 15-18: The import of formatValidationErrorsForV1Api and
validateResponseData in route.ts is using the wrong path; update the import to
point to the centralized validation utilities at "@/modules/api/lib/validation"
so that formatValidationErrorsForV1Api and validateResponseData are imported
from the correct module; keep the imported symbol names unchanged and verify any
other usages in route.ts refer to those same function names.
🧹 Nitpick comments (2)
apps/web/app/api/v1/management/responses/[responseId]/route.ts (1)

144-161: Consider: No data merging unlike V1 client PUT route.

This V1 management PUT validates responseUpdate.data directly, while the V1 client PUT route at apps/web/app/api/v1/client/[environmentId]/responses/[responseId]/route.ts (lines 118-131) merges existing response data with the update before validation:

const mergedData = {
  ...response.data,
  ...inputValidation.data.data,
};

This difference may be intentional if management APIs expect complete data, but it creates inconsistent validation behavior between endpoints. When finished: true is sent with partial data, the management API will report "required" errors for missing fields, while the client API will validate the merged state.

apps/web/modules/api/lib/validation.ts (1)

45-50: Avoid repeated Object.keys work during partial validation.

Object.keys(responseData) is recalculated for every element. Cache once to keep this O(n) and cleaner.

♻️ Suggested refactor
-  if (!finished) {
-    elementsToValidate = allElements.filter((element) => Object.keys(responseData).includes(element.id));
-  }
+  if (!finished) {
+    const responseKeys = new Set(Object.keys(responseData));
+    elementsToValidate = allElements.filter((element) => responseKeys.has(element.id));
+  }

Comment thread apps/web/app/api/v2/client/[environmentId]/responses/route.ts Outdated
Copy link
Copy Markdown
Contributor

@pandeymangg pandeymangg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Just a small comment, pls take a look 🙏

Comment thread apps/web/modules/api/lib/validation.ts Outdated
@Dhruwang Dhruwang requested a review from pandeymangg February 5, 2026 12:11
Copy link
Copy Markdown
Contributor

@pandeymangg pandeymangg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 🚀

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Feb 5, 2026

@TheodorTomas TheodorTomas added this pull request to the merge queue Feb 5, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Feb 5, 2026
@Dhruwang Dhruwang added this pull request to the merge queue Feb 6, 2026
Merged via the queue into main with commit 56ce05f Feb 6, 2026
17 checks passed
@Dhruwang Dhruwang deleted the fix/response-validation-in-client-api branch February 6, 2026 07:11
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.

2 participants