Files
thrilltrack-explorer/docs/VALIDATION_CENTRALIZATION.md
gpt-engineer-app[bot] 1a8395f0a0 Update documentation references
Update remaining documentation files to remove references to the old approval flow and feature flags.
2025-11-06 21:23:29 +00:00

8.5 KiB

Validation Centralization - Critical Issue #3 Fixed

Overview

This document describes the changes made to centralize all business logic validation in the edge function, removing duplicate validation from the React frontend.

Problem Statement

Previously, validation was duplicated in two places:

  1. React Frontend (useModerationActions.ts): Performed full business logic validation using Zod schemas before calling the edge function
  2. Edge Function (process-selective-approval): Also performed full business logic validation

This created several issues:

  • Duplicate Code: Same validation logic maintained in two places
  • Inconsistency Risk: Frontend and backend could have different validation rules
  • Performance: Unnecessary network round-trips for validation data fetching
  • Single Source of Truth Violation: No clear authority on what's valid

Solution: Edge Function as Single Source of Truth

Architecture Changes

┌─────────────────────────────────────────────────────────────────┐
│                         BEFORE (Duplicate)                       │
├─────────────────────────────────────────────────────────────────┤
│                                                                   │
│  React Frontend                  Edge Function                   │
│  ┌──────────────┐               ┌──────────────┐                │
│  │ UX Validation│               │ Business     │                │
│  │      +       │──────────────▶│ Validation   │                │
│  │ Business     │  If valid     │              │                │
│  │ Validation   │  call edge    │ (Duplicate)  │                │
│  └──────────────┘               └──────────────┘                │
│        ❌ Duplicate validation logic                             │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│                     AFTER (Centralized) ✅                       │
├─────────────────────────────────────────────────────────────────┤
│                                                                   │
│  React Frontend                  Edge Function                   │
│  ┌──────────────┐               ┌──────────────┐                │
│  │ UX Validation│               │ Business     │                │
│  │ Only         │──────────────▶│ Validation   │                │
│  │ (non-empty,  │  Always       │ (Authority)  │                │
│  │  format)     │  call edge    │              │                │
│  └──────────────┘               └──────────────┘                │
│        ✅ Single source of truth                                 │
└─────────────────────────────────────────────────────────────────┘

Changes Made

1. React Frontend (src/hooks/moderation/useModerationActions.ts)

Removed:

  • Import of validateMultipleItems from entityValidationSchemas
  • 200+ lines of validation code that:
    • Fetched full item data with relational joins
    • Ran Zod validation on all items
    • Blocked approval if validation failed
    • Logged validation errors

Added:

  • Clear comment explaining validation happens server-side only
  • Enhanced error handling to detect validation errors from edge function

What Remains:

  • Basic error handling for edge function responses
  • Toast notifications for validation failures
  • Proper error logging with validation flag

2. Validation Schemas (src/lib/entityValidationSchemas.ts)

Updated:

  • Added comprehensive documentation header
  • Marked schemas as "documentation only" for React app
  • Clarified that edge function is the authority
  • Noted these schemas should mirror edge function validation

Status:

  • File retained for documentation and future reference
  • Not imported anywhere in production React code
  • Can be used for basic client-side UX validation if needed

3. Edge Function (supabase/functions/process-selective-approval/index.ts)

No Changes Required:

  • Atomic transaction RPC approach already has comprehensive validation via validateEntityDataStrict()
  • Already returns proper 400 errors for validation failures
  • Already includes detailed error messages
  • Validates within PostgreSQL transaction for data integrity

Validation Responsibilities

Client-Side (React Forms)

Allowed:

  • Non-empty field validation (required fields)
  • Basic format validation (email, URL format)
  • Character length limits
  • Input masking and formatting
  • Immediate user feedback for UX

Not Allowed:

  • Business rule validation (e.g., closing date after opening date)
  • Cross-field validation
  • Database constraint validation
  • Entity relationship validation
  • Status/state validation

Server-Side (Edge Function)

Authoritative For:

  • All business logic validation
  • Cross-field validation
  • Database constraint validation
  • Entity relationship validation
  • Status/state validation
  • Security validation
  • Data integrity checks

Error Handling Flow

// 1. User clicks "Approve" in UI
// 2. React calls edge function immediately (no validation)
const { data, error } = await invokeWithTracking('process-selective-approval', {
  itemIds: [...],
  submissionId: '...'
});

// 3. Edge function validates and returns error if invalid
if (error) {
  // Error contains validation details from edge function
  // React displays the error message
  toast({
    title: 'Validation Failed',
    description: error.message // e.g., "Park name is required"
  });
}

Benefits

  1. Single Source of Truth: Edge function is the authority
  2. Consistency: No risk of frontend/backend validation diverging
  3. Performance: No pre-validation data fetching in frontend
  4. Maintainability: Update validation in one place
  5. Security: Can't bypass validation by manipulating frontend
  6. Simplicity: Frontend code is simpler and cleaner

Testing Validation

To test that validation works:

  1. Submit a park without required fields
  2. Submit a park with invalid dates (closing before opening)
  3. Submit a ride without a park_id
  4. Submit a company with invalid email format

Expected: Edge function should return 400 error with detailed message, React should display error toast.

Migration Guide

If you need to add new validation rules:

  1. Add to edge function (process-selective-approval/index.ts)

    • Update validateEntityDataStrict() function within the atomic transaction RPC
    • Add to appropriate entity type case
    • Ensure validation happens before any database writes
  2. Update documentation schemas (entityValidationSchemas.ts)

    • Keep schemas in sync for reference
    • Update comments if rules change
  3. DO NOT add to React validation

    • React should only do basic UX validation
    • Business logic belongs in edge function (atomic transaction)

This fix addresses:

  • Critical Issue #3: Validation centralization
  • Removes ~200 lines of duplicate code
  • Eliminates validation timing gap
  • Simplifies frontend logic
  • Improves maintainability

Files Changed

  • src/hooks/moderation/useModerationActions.ts - Removed validation logic
  • src/lib/entityValidationSchemas.ts - Updated documentation
  • docs/VALIDATION_CENTRALIZATION.md - This document