All files / src/types api.ts

96.96% Statements 160/165
75% Branches 3/4
0% Functions 0/2
96.96% Lines 160/165

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 1662x 2x 2x 2x 2x 2x 2x     2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x     2x   2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x  
// src/types/api.ts
// ============================================================================
// API RESPONSE TYPE DEFINITIONS
// ============================================================================
// Standardized response types for all API endpoints per ADR-028.
// These types ensure consistent response structure across the entire API.
// ============================================================================

/**
 * Standard pagination metadata included in paginated responses.
 */
export interface PaginationMeta {
  /** Current page number (1-indexed) */
  page: number;
  /** Number of items per page */
  limit: number;
  /** Total number of items across all pages */
  total: number;
  /** Total number of pages */
  totalPages: number;
  /** Whether there is a next page */
  hasNextPage: boolean;
  /** Whether there is a previous page */
  hasPrevPage: boolean;
}
 
/**
 * Optional metadata that can be included in any response.
 */
export interface ResponseMeta {
  /** Unique request identifier for tracking/debugging */
  requestId?: string;
  /** ISO timestamp of when the response was generated */
  timestamp?: string;
  /** Pagination info (only for paginated responses) */
  pagination?: PaginationMeta;
}
 
/**
 * Standard success response envelope.
 * All successful API responses should follow this structure.
 *
 * @example
 * // Single item response
 * {
 *   "success": true,
 *   "data": { "id": 1, "name": "Item" }
 * }
 *
 * @example
 * // Paginated list response
 * {
 *   "success": true,
 *   "data": [{ "id": 1 }, { "id": 2 }],
 *   "meta": {
 *     "pagination": { "page": 1, "limit": 20, "total": 100, ... }
 *   }
 * }
 */
export interface ApiSuccessResponse<T> {
  success: true;
  data: T;
  meta?: ResponseMeta;
}
 
/**
 * Standard error response envelope.
 * All error responses should follow this structure.
 *
 * @example
 * // Validation error
 * {
 *   "success": false,
 *   "error": {
 *     "code": "VALIDATION_ERROR",
 *     "message": "The request data is invalid.",
 *     "details": [{ "path": ["email"], "message": "Invalid email format" }]
 *   }
 * }
 *
 * @example
 * // Not found error
 * {
 *   "success": false,
 *   "error": {
 *     "code": "NOT_FOUND",
 *     "message": "User not found"
 *   }
 * }
 */
export interface ApiErrorResponse {
  success: false;
  error: {
    /** Machine-readable error code (e.g., 'VALIDATION_ERROR', 'NOT_FOUND') */
    code: string;
    /** Human-readable error message */
    message: string;
    /** Additional error details (validation errors, etc.) */
    details?: unknown;
  };
  meta?: Pick<ResponseMeta, 'requestId' | 'timestamp'>;
}
 
/**
 * Union type for all API responses.
 * Useful for frontend type narrowing based on `success` field.
 */
export type ApiResponse<T> = ApiSuccessResponse<T> | ApiErrorResponse;
 
// ============================================================================
// ERROR CODES
// ============================================================================
// Standardized error codes for consistent error identification.
// ============================================================================
 
/**
 * Standard error codes used across the API.
 * These should be used with the `sendError` helper function.
 */
export const ErrorCode = {
  // Client errors (4xx)
  VALIDATION_ERROR: 'VALIDATION_ERROR',
  NOT_FOUND: 'NOT_FOUND',
  UNAUTHORIZED: 'UNAUTHORIZED',
  FORBIDDEN: 'FORBIDDEN',
  CONFLICT: 'CONFLICT',
  BAD_REQUEST: 'BAD_REQUEST',
  RATE_LIMITED: 'RATE_LIMITED',
  PAYLOAD_TOO_LARGE: 'PAYLOAD_TOO_LARGE',
 
  // Server errors (5xx)
  INTERNAL_ERROR: 'INTERNAL_ERROR',
  SERVICE_UNAVAILABLE: 'SERVICE_UNAVAILABLE',
  EXTERNAL_SERVICE_ERROR: 'EXTERNAL_SERVICE_ERROR',
  NOT_IMPLEMENTED: 'NOT_IMPLEMENTED',
} as const;
 
export type ErrorCodeType = (typeof ErrorCode)[keyof typeof ErrorCode];
 
// ============================================================================
// HELPER TYPES
// ============================================================================
 
/**
 * Input for creating paginated responses.
 */
export interface PaginationInput {
  page: number;
  limit: number;
  total: number;
}
 
/**
 * Type guard to check if a response is a success response.
 */
export function isApiSuccess<T>(response: ApiResponse<T>): response is ApiSuccessResponse<T> {
  return response.success === true;
}
 
/**
 * Type guard to check if a response is an error response.
 */
export function isApiError<T>(response: ApiResponse<T>): response is ApiErrorResponse {
  return response.success === false;
}