UNPKG

@ritas-inc/hanaqueryapi-client

Version:

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

1,299 lines (1,145 loc) 35.7 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 sector: string | null; // Production sector code (null if not assigned) } /** * 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 parameters for filtering */ export interface ItemsParams { groups?: number[]; } /** * 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; groupCodes?: 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) injPerEtiq?: number; // Injections per etiquette (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>; // ============================================================================ // Quantity Per Tag Endpoint Types // ============================================================================ /** * Individual quantity per tag item */ export interface QtyPerTag { itemcode: string; // Item code injPerTag: number; // Injections per tag qtyPerTag: number; // Quantity per tag (calculated) } /** * Quantity per tag response data */ export interface QtyPerTagData { qtyPerTag: QtyPerTag[]; } /** * Quantity per tag metadata */ export interface QtyPerTagMetadata { count: number; } /** * Quantity per tag endpoint response */ export type QtyPerTagResponse = SuccessResponse<QtyPerTagData, QtyPerTagMetadata>; // ============================================================================ // 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>; // ============================================================================ // Database Companies Endpoint Types // ============================================================================ /** * Individual database company */ export interface DatabaseCompany { dbName: string; // Database name cmpName: string; // Company name } /** * Database companies response data */ export interface DatabaseCompaniesData { companies: DatabaseCompany[]; } /** * Database companies metadata */ export interface DatabaseCompaniesMetadata { count: number; lastUpdated: string; } /** * Database companies endpoint response */ export type DatabaseCompaniesResponse = SuccessResponse<DatabaseCompaniesData, DatabaseCompaniesMetadata>; // ============================================================================ // Tags Endpoint Types // ============================================================================ /** * Tag status enum * * @remarks * Status values: * - idle: Tag created but not yet activated * - activated: Tag activated for production * - quantified: Production quantity recorded * - partUtilized: Some quantity has been used * - utilized: Fully utilized * - discarded: Tag discarded * - used: Has usage records (calculated by service layer) */ export type TagStatus = 'idle' | 'activated' | 'quantified' | 'partUtilized' | 'utilized' | 'discarded' | 'used'; /** * Tag usage record */ export interface TagUsage { tagCode: number; workOrder: number; useDateTime: string; // ISO 8601 DateTime string (combined date + time) quantity: number; employee: string | null; } /** * Individual production tag */ export interface Tag { tagEntry: number; workOrderEntry: number | null; workOrderNum: number | null; itemCode: string | null; status: TagStatus; activationDateTime: string | null; // ISO 8601 DateTime string (combined date + time) activationEmployee: string | null; injectionMachine: string | null; mold: string | null; quantificationDateTime: string | null; // ISO 8601 DateTime string (combined date + time) quantificationEmployee: string | null; quantity: number | null; quantityUoM: string; discardDateTime: string | null; // ISO 8601 DateTime string (combined date + time) discardEmployee: string | null; usage: TagUsage[]; } /** * Tag response data */ export interface TagData { tag: Tag; } /** * Tag metadata */ export interface TagMetadata { tagEntry: number; } /** * Tag endpoint response */ export type TagResponse = SuccessResponse<TagData, TagMetadata>; // ============================================================================ // Work Order Tags Endpoint Types // ============================================================================ /** * Work order tags response data */ export interface WorkOrderTagsData { tags: Tag[]; } /** * Work order tags metadata */ export interface WorkOrderTagsMetadata { workOrderEntry: number; count: number; } /** * Work order tags endpoint response * * @remarks * API Behavior: * - Returns all tags associated with the specified work order * - Returns empty array if work order has no tags * - No 404 if work order doesn't exist - just returns empty array */ export type WorkOrderTagsResponse = SuccessResponse<WorkOrderTagsData, WorkOrderTagsMetadata>; // ============================================================================ // Injection Machines Endpoint Types // ============================================================================ /** * Individual injection machine */ export interface InjectionMachine { resCode: string; resName: string; active: string; } /** * Injection machines response data */ export interface InjectionMachinesData { machines: InjectionMachine[]; } /** * Single injection machine response data */ export interface SingleInjectionMachineData { machine: InjectionMachine; } /** * Injection machines metadata */ export interface InjectionMachinesMetadata { count: number; } /** * Single injection machine metadata */ export interface SingleInjectionMachineMetadata { machineCode: string; } /** * Injection machines endpoint response */ export type InjectionMachinesResponse = SuccessResponse<InjectionMachinesData, InjectionMachinesMetadata>; /** * Single injection machine endpoint response */ export type SingleInjectionMachineResponse = SuccessResponse<SingleInjectionMachineData, SingleInjectionMachineMetadata>; // ============================================================================ // Molds Endpoint Types // ============================================================================ /** * Individual mold */ export interface Mold { resCode: string; resName: string; active: string; pieceModel: string | null; cavities: number | null; injectionsPerTag: number | null; standardCycle: number | null; } /** * Molds response data */ export interface MoldsData { molds: Mold[]; } /** * Single mold response data */ export interface SingleMoldData { mold: Mold; } /** * Molds metadata */ export interface MoldsMetadata { count: number; } /** * Single mold metadata */ export interface SingleMoldMetadata { moldCode: string; } /** * Molds endpoint response */ export type MoldsResponse = SuccessResponse<MoldsData, MoldsMetadata>; /** * Single mold endpoint response */ export type SingleMoldResponse = SuccessResponse<SingleMoldData, SingleMoldMetadata>; // ============================================================================ // Business Partners Endpoint Types // ============================================================================ /** * Business partner record. Most fields are nullable since the source SAP HANA data * is sparsely populated. */ export interface BusinessPartner { cardcode: string; // Always present (primary key) cardname: string | null; localarea_number: string | null; // Phone2 — typically the area code (e.g. "11") phone_number: string | null; // Phone1 — main number cellular_number: string | null; email: string | null; indcode: string | null; indname: string | null; // Industry name (joined from oond) ind_description: string | null; tercode: string | null; territory_description: string | null; parent_territory: string | null; zipcode: string | null; street_type: string | null; street_name: string | null; street_number: string | null; neighborhood: string | null; city: string | null; state: string | null; country: string | null; } /** * List response data for /business-partners and /business-partners/search. */ export interface BusinessPartnersData { partners: BusinessPartner[]; } /** * Metadata for /business-partners (plain list). */ export interface BusinessPartnersMetadata { count: number; } /** * Metadata for /business-partners/search — echoes the criteria back. */ export interface BusinessPartnersSearchMetadata { count: number; criteria: SearchCriteria; } /** * List response. */ export type BusinessPartnersResponse = SuccessResponse<BusinessPartnersData, BusinessPartnersMetadata>; /** * Search response. */ export type BusinessPartnersSearchResponse = SuccessResponse<BusinessPartnersData, BusinessPartnersSearchMetadata>; // ============================================================================ // Contacts Endpoint Types // ============================================================================ /** * Contact record (sbo_ritas.ocpr). `cardname` is populated by the search endpoint * (it joins ocrd) but is null/absent on the plain /contacts and * /business-partners/:cardCode/contacts endpoints. */ export interface Contact { contactcode: string; contactname: string | null; first_name: string | null; middle_name: string | null; last_name: string | null; title: string | null; position: string | null; email: string | null; phone_number_1: string | null; // Tel1 phone_number_2: string | null; // Tel2 cell_phone_number: string | null; // Cellolar (sic, real SAP column name) notes: string | null; notes_2: string | null; cardcode: string; // Associated BP CardCode cardname?: string | null; // Only populated by /contacts/search } /** * List response data for /contacts, /contacts/search, * and /business-partners/:cardCode/contacts. */ export interface ContactsData { contacts: Contact[]; } /** * Metadata for /contacts (plain list). */ export interface ContactsMetadata { count: number; } /** * Metadata for /contacts/search — echoes the criteria back. */ export interface ContactsSearchMetadata { count: number; criteria: SearchCriteria; } /** * Metadata for /business-partners/:cardCode/contacts. */ export interface BusinessPartnerContactsMetadata { count: number; cardCode: string; } /** * List response. */ export type ContactsResponse = SuccessResponse<ContactsData, ContactsMetadata>; /** * Search response. */ export type ContactsSearchResponse = SuccessResponse<ContactsData, ContactsSearchMetadata>; /** * Nested contacts-of-partner response. */ export type BusinessPartnerContactsResponse = SuccessResponse<ContactsData, BusinessPartnerContactsMetadata>; // ============================================================================ // Search Criteria // ============================================================================ /** * Search criteria shared by /business-partners/search and /contacts/search. * * The server requires at least one of `phone`, `email`, `q`, or `cardCode` — * a request with only `fuzziness` (or no criteria at all) returns HTTP 400. * The client does not pre-validate this; the server's error is propagated as * a `ValidationError`. */ export interface SearchCriteria { /** * Digits-only substring match. Non-digits in the input are stripped server-side. * For BP search this also matches the Phone2||Phone1 / Phone2||Cellular concatenations, * so it handles "with area code" and "without area code" transparently. */ phone?: string; /** * Exact match after canonical email extraction (first `[A-Za-z0-9._%+-]+@…` substring, * lowercased on both sides). */ email?: string; /** * Free-text fuzzy search via HANA `CONTAINS(..., FUZZY(fuzziness))`. Words are split on * whitespace and OR-ed; each word may match any of the searched fields. */ q?: string; /** * Exact match on CardCode. Useful to scope contact search to a known partner. */ cardCode?: string; /** * Fuzziness threshold for `q` (range 0.1–1.0, default 0.7). Higher values are stricter; * lower values catch more typos and accent variants but return more false positives. * Ignored when `q` is omitted. */ fuzziness?: number; } // ============================================================================ // 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 plan_salesfromdate: string | null; // Sales period start date or null plan_salestodate: string | null; // Sales period end 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 breakQty: number; // Maximum quantity that can be produced in a single work order 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 order_productionsector: string | null; // Production sector code } /** * 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 Tags Endpoint Types // ============================================================================ /** * Plan tag */ export interface PlanTag { tag_entry: number; // Tag document entry ID tag_workorder_num: number; // Work order number tag_item_name: string; // Item name } /** * Plan tags response data */ export interface PlanTagsData { tags: PlanTag[]; } /** * Plan tags metadata */ export interface PlanTagsMetadata { planId: number; count: number; } /** * Plan tags endpoint response * * @remarks * API Behavior: * - HTTP 200: Plan exists (tags array may be empty or populated) * - HTTP 404: Plan with the specified ID does not exist * - Empty tags array indicates the plan exists but has no tags */ export type PlanTagsResponse = SuccessResponse<PlanTagsData, PlanTagsMetadata>; // ============================================================================ // 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 ClientDatabaseCompaniesResult = { data: DatabaseCompaniesData; metadata: DatabaseCompaniesMetadata }; 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 }; export type ClientBusinessPartnersResult = { data: BusinessPartnersData; metadata: BusinessPartnersMetadata }; export type ClientBusinessPartnersSearchResult = { data: BusinessPartnersData; metadata: BusinessPartnersSearchMetadata }; export type ClientContactsResult = { data: ContactsData; metadata: ContactsMetadata }; export type ClientContactsSearchResult = { data: ContactsData; metadata: ContactsSearchMetadata }; export type ClientBusinessPartnerContactsResult = { data: ContactsData; metadata: BusinessPartnerContactsMetadata }; // ============================================================================ // 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; 'getDatabaseCompanies': ClientDatabaseCompaniesResult; 'getPlans': ClientPlansResult; 'getPlan': ClientSinglePlanResult; 'getPlanProducts': ClientPlanProductsResult; 'getPlanWorkOrders': ClientPlanWorkOrdersResult; 'getUser': ClientUserResult; 'getBusinessPartners': ClientBusinessPartnersResult; 'searchBusinessPartners': ClientBusinessPartnersSearchResult; 'getBusinessPartnerContacts': ClientBusinessPartnerContactsResult; 'getContacts': ClientContactsResult; 'searchContacts': ClientContactsSearchResult; } /** * 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];