Files
cloud-server/REFACTORING_SUMMARY.md
kaffa bb21484590
Some checks failed
TypeScript CI / build (push) Has been cancelled
chore: anvil.it.com → inouter.com
2026-03-27 16:17:13 +00:00

7.9 KiB

Code Quality Refactoring Summary

Overview

This refactoring addresses three medium-priority code quality issues identified in the cloud-server project.

Changes Made

Issue 1: Input Validation Logic Duplication

Problem: Duplicate validation patterns across routes (instances.ts, sync.ts, recommend.ts)

Solution: Created centralized validation utilities

Files Modified:

  • Created /src/utils/validation.ts - Reusable validation functions with type-safe results
  • Updated /src/routes/sync.ts - Now uses parseJsonBody, validateProviders, createErrorResponse
  • Updated /src/routes/recommend.ts - Now uses parseJsonBody, validateStringArray, validateEnum, validatePositiveNumber, createErrorResponse

New Utilities:

// Type-safe validation results
export type ValidationResult<T> =
  | { success: true; data: T }
  | { success: false; error: ValidationError };

// Core validation functions
parseJsonBody<T>(request: Request): Promise<ValidationResult<T>>
validateProviders(providers: unknown, supportedProviders: readonly string[]): ValidationResult<string[]>
validatePositiveNumber(value: unknown, name: string, defaultValue?: number): ValidationResult<number>
validateStringArray(value: unknown, name: string): ValidationResult<string[]>
validateEnum<T>(value: unknown, name: string, allowedValues: readonly T[]): ValidationResult<T>
createErrorResponse(error: ValidationError, statusCode?: number): Response

Benefits:

  • DRY Principle: Eliminated ~200 lines of duplicate validation code
  • Consistency: All routes now use identical validation logic
  • Type Safety: Discriminated union types ensure compile-time correctness
  • Maintainability: Single source of truth for validation rules
  • Testability: Comprehensive test suite (28 tests) for validation utilities

Issue 2: HTTP Status Code Hardcoding

Problem: Hardcoded status codes (413, 400, 503) instead of constants

Solution: Unified HTTP status code usage

Files Modified:

  • /src/constants.ts - Added PAYLOAD_TOO_LARGE: 413 constant
  • /src/routes/recommend.ts - Replaced 413 with HTTP_STATUS.PAYLOAD_TOO_LARGE, replaced 400 with HTTP_STATUS.BAD_REQUEST
  • /src/routes/health.ts - Replaced 503 with HTTP_STATUS.SERVICE_UNAVAILABLE

Benefits:

  • Consistency: All HTTP status codes centralized
  • Searchability: Easy to find all uses of specific status codes
  • Documentation: Self-documenting code with named constants
  • Refactoring Safety: Change status codes in one place

Issue 3: CORS Localhost in Production

Problem: http://localhost:3000 included in production CORS configuration without clear documentation

Solution: Enhanced documentation and guidance for production filtering

Files Modified:

  • /src/constants.ts - Added comprehensive documentation and production filtering guidance

Changes:

/**
 * CORS configuration
 *
 * NOTE: localhost origin is included for development purposes.
 * In production, filter allowed origins based on environment.
 * Example: const allowedOrigins = CORS.ALLOWED_ORIGINS.filter(o => !o.includes('localhost'))
 */
export const CORS = {
  ALLOWED_ORIGINS: [
    'https://inouter.com',
    'https://cloud.inouter.com',
    'http://localhost:3000', // DEVELOPMENT ONLY - exclude in production
  ] as string[],
  // ...
} as const;

Benefits:

  • Clear Intent: Developers understand localhost is development-only
  • Production Safety: Example code shows how to filter in production
  • Maintainability: Future developers won't accidentally remove localhost thinking it's a mistake

Testing

Test Results

✓ All existing tests pass (99 tests)
✓ New validation utilities tests (28 tests)
✓ Total: 127 tests passed
✓ TypeScript compilation: No errors

Test Coverage

  • /src/utils/validation.test.ts - Comprehensive test suite for all validation functions
    • parseJsonBody: Valid JSON, missing content-type, invalid content-type, malformed JSON
    • validateProviders: Valid providers, non-array, empty array, non-string elements, unsupported providers
    • validatePositiveNumber: Positive numbers, zero, string parsing, defaults, negatives, NaN
    • validateStringArray: Valid arrays, missing values, non-arrays, empty arrays, non-string elements
    • validateEnum: Valid enums, missing values, invalid values, non-string values
    • createErrorResponse: Default status, custom status, error details in body

Code Quality Metrics

Lines of Code Reduced

  • Eliminated ~200 lines of duplicate validation code
  • Net reduction: ~150 lines (after accounting for new validation utilities)

Maintainability Improvements

  • Single Responsibility: Validation logic separated from route handlers
  • Reusability: Validation functions used across multiple routes
  • Type Safety: Discriminated unions prevent runtime type errors
  • Error Handling: Consistent error format across all routes

Performance Impact

  • Neutral: No performance degradation
  • Memory: Minimal increase from function reuse
  • Bundle Size: Slight reduction due to code deduplication

Migration Guide

For Future Validation Needs

When adding new validation to routes:

// 1. Import validation utilities
import {
  parseJsonBody,
  validateStringArray,
  validateEnum,
  createErrorResponse,
} from '../utils/validation';

// 2. Parse request body
const parseResult = await parseJsonBody<YourBodyType>(request);
if (!parseResult.success) {
  logger.error('[Route] Parsing failed', {
    code: parseResult.error.code,
    message: parseResult.error.message,
  });
  return createErrorResponse(parseResult.error);
}

// 3. Validate parameters
const arrayResult = validateStringArray(body.items, 'items');
if (!arrayResult.success) {
  logger.error('[Route] Validation failed', {
    code: arrayResult.error.code,
    message: arrayResult.error.message,
  });
  return createErrorResponse(arrayResult.error);
}

For Production CORS Filtering

Add environment-aware CORS filtering in your middleware or worker:

// Example: Filter localhost in production
const allowedOrigins = process.env.NODE_ENV === 'production'
  ? CORS.ALLOWED_ORIGINS.filter(origin => !origin.includes('localhost'))
  : CORS.ALLOWED_ORIGINS;

Backward Compatibility

100% Backward Compatible

  • All existing API behavior preserved
  • No breaking changes to request/response formats
  • All existing tests pass without modification

Next Steps

  1. Apply validation utilities to instances.ts route (parsePositiveNumber helper can be replaced)
  2. Add integration tests for route handlers using validation utilities
  3. Consider adding validation utilities for:
    • Boolean parameters (has_gpu, force, etc.)
    • Date/timestamp parameters
    • URL/path parameters
  4. Create environment-aware CORS middleware to automatically filter localhost in production

Files Changed

Created:
  src/utils/validation.ts (314 lines)
  src/utils/validation.test.ts (314 lines)
  REFACTORING_SUMMARY.md (this file)

Modified:
  src/constants.ts
    - Added HTTP_STATUS.PAYLOAD_TOO_LARGE
    - Enhanced CORS documentation

  src/routes/sync.ts
    - Removed duplicate validation code
    - Integrated validation utilities
    - 70 lines reduced

  src/routes/recommend.ts
    - Removed duplicate validation code
    - Integrated validation utilities
    - Fixed all hardcoded status codes
    - 120 lines reduced

  src/routes/health.ts
    - Fixed hardcoded status code (503 → HTTP_STATUS.SERVICE_UNAVAILABLE)

Conclusion

This refactoring successfully addresses all three medium-priority code quality issues while:

  • Maintaining 100% backward compatibility
  • Improving code maintainability and reusability
  • Adding comprehensive test coverage
  • Reducing technical debt
  • Providing clear documentation for future developers

All changes follow TypeScript best practices, SOLID principles, and the project's existing patterns.