UNPKG

@ritas-inc/hanaqueryapi-client

Version:

TypeScript client for HANA Query API with full type safety and error handling

786 lines (693 loc) 21.6 kB
/** * HANA Query API Client - Type Definitions * * Complete TypeScript interfaces matching the current API response structures. * These types are based on the actual API implementation and ensure type safety. */ // ============================================================================ // Base Response Types // ============================================================================ /** * Base API response structure */ export interface BaseAPIResponse { success: boolean; } /** * Successful API response */ export interface SuccessResponse<TData = any, TMetadata = any> extends BaseAPIResponse { success: true; data: TData; metadata?: TMetadata; } /** * Error API response */ export interface ErrorResponse extends BaseAPIResponse { success: false; problem: ProblemDetails; } /** * Generic API response (success or error) */ export type APIResponse<TData = any, TMetadata = any> = | SuccessResponse<TData, TMetadata> | ErrorResponse; /** * Problem details for error responses (RFC 7807) */ export interface ProblemDetails { status: number; type: string; title: string; detail: string; instance: string; context: { request: string; responseText: string; }; issues: string[]; } // ============================================================================ // Request Parameter Types // ============================================================================ /** * Date range parameters for sales endpoint */ export interface SalesParams { from: string; // YYYY-MM-DD format (required) to: string; // YYYY-MM-DD format (required) } /** * Generic request options */ export interface RequestOptions { timeout?: number; retries?: number; signal?: AbortSignal; } // ============================================================================ // HTTP Headers // ============================================================================ /** * API response headers */ export interface APIResponseHeaders { 'x-response-time'?: string; 'x-authorization-response'?: 'ok' | 'unauthorized'; 'content-type'?: string; } // ============================================================================ // Health Endpoint Types // ============================================================================ /** * Health check response data */ export interface HealthData { status: 'ok'; timestamp: string; // ISO 8601 format uptime: number; // Server uptime in seconds } /** * Health endpoint metadata containing system information * * @example * ```typescript * { * systemInfo: true, * serverTime: "2025-06-30T12:00:00.000Z", * nodeVersion: "v24.0.2", * platform: "linux", * arch: "x64" * } * ``` */ export interface HealthMetadata { /** Indicates that system information is included in the metadata */ systemInfo: boolean; /** Server current time in ISO 8601 format */ serverTime: string; /** Node.js version (e.g., "v24.0.2") */ nodeVersion: string; /** Operating system platform (e.g., "linux", "darwin", "win32") */ platform: string; /** System architecture (e.g., "x64", "arm64") */ arch: string; } /** * Health endpoint response */ export type HealthResponse = SuccessResponse<HealthData, HealthMetadata>; // ============================================================================ // Documentation Endpoint Types // ============================================================================ /** * API documentation response data */ export interface DocsData { name: string; version: string; endpoints: Record<string, string>; } /** * Documentation endpoint metadata containing API information * * @example * ```typescript * { * endpointCount: 9, * apiVersion: "v1", * generatedAt: "2025-06-30T12:00:00.000Z", * documentation: true * } * ``` */ export interface DocsMetadata { /** Total number of available API endpoints */ endpointCount: number; /** API version identifier (e.g., "v1") */ apiVersion: string; /** Documentation generation timestamp in ISO 8601 format */ generatedAt: string; /** Indicates this is a documentation endpoint response */ documentation: boolean; } /** * Documentation endpoint response */ export type DocsResponse = SuccessResponse<DocsData, DocsMetadata>; // ============================================================================ // Items Endpoint Types // ============================================================================ /** * Individual item status */ export interface ItemStatus { itemgroup: string; // Item group code itemcode: string; // Unique item identifier description: string; // Item name/description onhand: number; // Current stock quantity onorder: number; // Quantity on purchase orders onassembly: number; // Quantity in assembly/production min: number; // Minimum stock level max: number; // Maximum stock level } /** * Individual sales order item */ export interface SalesItem { orderEntry: number; // Sales order entry number orderNum: number; // Sales order number cardName: string; // Customer name dueDate: string; // Due date in ISO format itemcode: string; // Item code openqty: number; // Open quantity } /** * Items response data */ export interface ItemsStatusData { items: ItemStatus[]; } /** * Sales response data */ export interface SalesData { sales: SalesItem[]; } /** * Individual item group */ export interface ItemGroup { code: string; // Item group code name: string; // Item group name/description } /** * Item groups response data */ export interface ItemGroupsData { groups: ItemGroup[]; } /** * Items metadata */ export interface ItemsStatusMetadata { count: number; } /** * Sales metadata */ export interface SalesMetadata { count: number; from: string; // ISO 8601 format to: string; // ISO 8601 format } /** * Item groups metadata */ export interface ItemGroupsMetadata { count: number; } /** * Items endpoint response */ export type ItemsStatusResponse = SuccessResponse<ItemsStatusData, ItemsStatusMetadata>; /** * Sales endpoint response */ export type SalesResponse = SuccessResponse<SalesData, SalesMetadata>; /** * Item groups endpoint response */ export type ItemGroupsResponse = SuccessResponse<ItemGroupsData, ItemGroupsMetadata>; /** * Individual item hierarchy */ export interface Hierarchy { rank: string; // Hierarchy level/rank (string) root: string; // Root node identifier (string) parent: string | null; // Parent item code or null for root items node: string; // Child item code quantity: number; // Required quantity of child per parent injections: number; // Number of injection processes required } /** * Item hierarchies response data */ export interface HierarchiesData { hierarchies: Hierarchy[]; } /** * Item hierarchies metadata */ export interface HierarchiesMetadata { count: number; } /** * Item hierarchies endpoint response */ export type HierarchiesResponse = SuccessResponse<HierarchiesData, HierarchiesMetadata>; /** * Individual tree relationship */ export interface Tree { parent: string; // Parent item code itemcode: string; // Child item code quantity: number; // Quantity relationship injPerUn?: number; // Injection per unit (optional) parentSector?: string; // Parent item's production sector (optional) itemSector?: string; // Child item's production sector (optional) parentMaxPerOrder?: number; // Parent item's maximum per order (optional) itemMaxPerOrder?: number; // Child item's maximum per order (optional) } /** * Trees response data */ export interface TreesData { trees: Tree[]; } /** * Trees metadata */ export interface TreesMetadata { count: number; } /** * Trees endpoint response */ export type TreesResponse = SuccessResponse<TreesData, TreesMetadata>; // ============================================================================ // Production Sectors Endpoint Types // ============================================================================ /** * Individual production sector */ export interface ProductionSector { code: string; // Unique sector identifier name: string; // Human-readable sector name order: number; // Display order for consistent presentation } /** * Production sectors response data */ export interface ProductionSectorsData { sectors: ProductionSector[]; } /** * Production sectors metadata */ export interface ProductionSectorsMetadata { count: number; lastUpdated: string; // ISO 8601 timestamp } /** * Production sectors endpoint response */ export type ProductionSectorsResponse = SuccessResponse<ProductionSectorsData, ProductionSectorsMetadata>; // ============================================================================ // Plans Endpoint Types // ============================================================================ /** * Production plan */ export interface Plan { plan_id: number; // Unique plan identifier plan_createdate: string; // Plan creation date (ISO 8601) plan_username: string; // User who created the plan plan_sapstatus: string; // SAP system status plan_status: string; // Human-readable plan status plan_releasedate: string | null; // Plan release date or null products_total: number; // Total products in plan products_generated: number; // Products generated products_canceled: number; // Products canceled products_released: number; // Products released to production products_closed: number; // Products completed/closed injections_generated: number; // Total injection processes generated injections_canceled: number; // Injection processes canceled injections_released: number; // Injection processes released injections_closed: number; // Injection processes completed } /** * Plans list response data */ export interface PlansData { plans: Plan[]; } /** * Plans list metadata */ export interface PlansMetadata { count: number; } /** * Plans list endpoint response */ export type PlansResponse = SuccessResponse<PlansData, PlansMetadata>; /** * Single plan response data */ export interface SinglePlanData { plan: Plan; } /** * Single plan metadata */ export interface SinglePlanMetadata { planId: number; } /** * Single plan endpoint response */ export type SinglePlanResponse = SuccessResponse<SinglePlanData, SinglePlanMetadata>; // ============================================================================ // Plan Products Endpoint Types // ============================================================================ /** * Plan product */ export interface PlanProduct { itemcode: string; // Product item code quantity: number; // Planned production quantity group: string; // Product group name for categorization } /** * Plan products response data * * @remarks * The products array can be empty when a plan exists but has no products. * This is a normal, successful response (HTTP 200), not an error condition. */ export interface PlanProductsData { products: PlanProduct[]; } /** * Plan products metadata */ export interface PlanProductsMetadata { count: number; planId: number; } /** * Plan products endpoint response * * @remarks * API Behavior: * - HTTP 200: Plan exists (products array may be empty or populated) * - HTTP 404: Plan with the specified ID does not exist * - Empty products array indicates the plan exists but has no products */ export type PlanProductsResponse = SuccessResponse<PlanProductsData, PlanProductsMetadata>; // ============================================================================ // Plan Work Orders Endpoint Types // ============================================================================ /** * Work order */ export interface WorkOrder { order_id: number; // Work order unique identifier order_num: number; // Work order number order_itemcode: string; // Item being produced order_plannedqty: number; // Planned production quantity order_status: string; // Current work order status order_completedqty: number; // Quantity completed order_rejectqty: number; // Quantity rejected/scrapped order_createdate: string; // Creation timestamp (ISO 8601) order_originabs: number | null; // Origin document reference order_originnum: number | null; // Origin line number order_releasedate: string | null; // Release timestamp or null } /** * Plan work orders response data * * @remarks * The workOrders array can be empty when a plan exists but has no work orders. * This is a normal, successful response (HTTP 200), not an error condition. */ export interface PlanWorkOrdersData { workOrders: WorkOrder[]; } /** * Plan work orders metadata */ export interface PlanWorkOrdersMetadata { count: number; planId: number; } /** * Plan work orders endpoint response * * @remarks * API Behavior: * - HTTP 200: Plan exists (workOrders array may be empty or populated) * - HTTP 404: Plan with the specified ID does not exist * - Empty workOrders array indicates the plan exists but has no work orders */ export type PlanWorkOrdersResponse = SuccessResponse<PlanWorkOrdersData, PlanWorkOrdersMetadata>; // ============================================================================ // Plan Sectors Summary Endpoint Types // ============================================================================ /** * Plan sector summary */ export interface PlanSectorSummary { plan_entry: number; // Plan document entry ID sector_name: string; // Name of the production sector sector_planned_qtty: number; // Total planned quantity for the sector sector_open_qtty: number; // Quantity still to be completed sector_completed_qtty: number; // Total completed quantity sector_abandoned_qtty: number; // Quantity abandoned (closed/cancelled) } /** * Single plan sectors summary response data */ export interface PlanSectorsSummaryData { sectors: PlanSectorSummary[]; } /** * Single plan sectors summary metadata */ export interface PlanSectorsSummaryMetadata { plan_id: number; sector_count: number; total_planned: number; total_completed: number; completion_rate: number; } /** * Single plan sectors summary endpoint response * * @remarks * API Behavior: * - HTTP 200: Plan exists (sectors array may be empty or populated) * - HTTP 404: Plan with the specified ID does not exist * - Empty sectors array indicates the plan exists but has no sectors */ export type PlanSectorsSummaryResponse = SuccessResponse<PlanSectorsSummaryData, PlanSectorsSummaryMetadata>; /** * All plans sectors summary response data */ export interface AllPlansSectorsSummaryData { sectors: PlanSectorSummary[]; } /** * All plans sectors summary metadata */ export interface AllPlansSectorsSummaryMetadata { total_sectors: number; unique_plans: number; unique_sector_names: string[]; total_planned: number; total_completed: number; overall_completion_rate: number; } /** * All plans sectors summary endpoint response */ export type AllPlansSectorsSummaryResponse = SuccessResponse<AllPlansSectorsSummaryData, AllPlansSectorsSummaryMetadata>; // ============================================================================ // User Endpoint Types // ============================================================================ /** * User lookup response data */ export interface UserData { userId: number; } /** * User lookup metadata */ export interface UserMetadata { username: string; } /** * User lookup endpoint response */ export type UserResponse = SuccessResponse<UserData, UserMetadata>; // ============================================================================ // Client Configuration Types // ============================================================================ /** * Client configuration options */ export interface ClientConfig { baseUrl: string; // Required field timeout?: number; retries?: number; retryDelay?: number; enableLogging?: boolean; logLevel?: 'debug' | 'info' | 'warn' | 'error'; headers?: Record<string, string>; } /** * Request context for logging/debugging */ export interface RequestContext { method: string; url: string; startTime: number; endTime?: number; duration?: number; attempt?: number; maxAttempts?: number; } // ============================================================================ // Error Types // ============================================================================ /** * Client error types */ export type ClientErrorType = | 'network_error' | 'timeout_error' | 'validation_error' | 'authorization_error' | 'not_found_error' | 'server_error' | 'unknown_error'; /** * Client error details */ export interface ClientErrorDetails { type: ClientErrorType; message: string; statusCode?: number; originalError?: Error; context?: RequestContext; problemDetails?: ProblemDetails; } // ============================================================================ // Utility Types // ============================================================================ /** * Extract data type from API response */ export type ExtractData<T> = T extends SuccessResponse<infer TData, any> ? TData : never; /** * Extract metadata type from API response */ export type ExtractMetadata<T> = T extends SuccessResponse<any, infer TMetadata> ? TMetadata : never; /** * Type guard for success responses */ export function isSuccessResponse<T, M>(response: APIResponse<T, M>): response is SuccessResponse<T, M> { return response.success === true; } /** * Type guard for error responses */ export function isErrorResponse(response: APIResponse): response is ErrorResponse { return response.success === false; } // ============================================================================ // Client Return Types (Data + Metadata) // ============================================================================ /** * Client method return types - all methods return consistent { data, metadata } format * * @example * ```typescript * // All client methods return the same structure: * const healthResult: ClientHealthResult = await client.getHealth(); * const { data, metadata } = healthResult; * * // Consistent destructuring pattern for all methods: * const { data: healthData, metadata: healthMeta } = await client.getHealth(); * const { data: docsData, metadata: docsMeta } = await client.getDocs(); * const { data: itemsData, metadata: itemsMeta } = await client.getItemsStatus(); * ``` */ export type ClientHealthResult = { data: HealthData; metadata: HealthMetadata }; export type ClientDocsResult = { data: DocsData; metadata: DocsMetadata }; export type ClientItemsStatusResult = { data: ItemsStatusData; metadata: ItemsStatusMetadata }; export type ClientHierarchiesResult = { data: HierarchiesData; metadata: HierarchiesMetadata }; export type ClientTreesResult = { data: TreesData; metadata: TreesMetadata }; export type ClientProductionSectorsResult = { data: ProductionSectorsData; metadata: ProductionSectorsMetadata }; export type ClientPlansResult = { data: PlansData; metadata: PlansMetadata }; export type ClientSinglePlanResult = { data: SinglePlanData; metadata: SinglePlanMetadata }; export type ClientPlanProductsResult = { data: PlanProductsData; metadata: PlanProductsMetadata }; export type ClientPlanWorkOrdersResult = { data: PlanWorkOrdersData; metadata: PlanWorkOrdersMetadata }; export type ClientUserResult = { data: UserData; metadata: UserMetadata }; // ============================================================================ // Endpoint Map Types // ============================================================================ /** * Map of all available endpoints and their response types */ export interface EndpointMap { 'GET /health': HealthResponse; 'GET /docs': DocsResponse; 'GET /items/status': ItemsStatusResponse; 'GET /items/hierarchies': HierarchiesResponse; 'GET /items/trees': TreesResponse; 'GET /production-sectors': ProductionSectorsResponse; 'GET /plans': PlansResponse; 'GET /plans/{planId}': SinglePlanResponse; 'GET /plans/{planId}/products': PlanProductsResponse; 'GET /plans/{planId}/work-orders': PlanWorkOrdersResponse; 'GET /users/{username}': UserResponse; } /** * Map of client method return types */ export interface ClientEndpointMap { 'getHealth': ClientHealthResult; 'getDocs': ClientDocsResult; 'getItemsStatus': ClientItemsStatusResult; 'getItemHierarchies': ClientHierarchiesResult; 'getItemTrees': ClientTreesResult; 'getProductionSectors': ClientProductionSectorsResult; 'getPlans': ClientPlansResult; 'getPlan': ClientSinglePlanResult; 'getPlanProducts': ClientPlanProductsResult; 'getPlanWorkOrders': ClientPlanWorkOrdersResult; 'getUser': ClientUserResult; } /** * Union of all possible API responses */ export type AnyAPIResponse = EndpointMap[keyof EndpointMap]; /** * Union of all possible client method results */ export type AnyClientResult = ClientEndpointMap[keyof ClientEndpointMap];