@classytic/payroll 2.7.5 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,110 @@
1
- import { L as LeaveType, a as LeaveBalance, W as WorkingDaysOptions, b as LeaveSummaryResult, c as LeaveInitConfig, O as ObjectIdLike, E as EmployeeDocument, d as OperationContext } from './types-BVDjiVGS.js';
2
- import { Model, Types } from 'mongoose';
1
+ import { aj as HttpError, ak as ErrorCode, a7 as LeaveType, al as LeaveBalance, am as WorkingDaysOptions, an as LeaveSummaryResult, ao as LeaveInitConfig, a2 as ObjectIdLike, E as EmployeeDocument, ap as OperationContext } from './types-bZdAJueH.js';
2
+ import { ClientSession, Model, Types } from 'mongoose';
3
+
4
+ /**
5
+ * @classytic/payroll - Error Handling
6
+ *
7
+ * Custom error classes with error codes and HTTP status
8
+ */
9
+
10
+ declare class PayrollError extends Error implements HttpError {
11
+ readonly code: ErrorCode;
12
+ readonly status: number;
13
+ readonly context: Record<string, unknown>;
14
+ readonly timestamp: Date;
15
+ /**
16
+ * Create a PayrollError.
17
+ *
18
+ * Supports BOTH constructor styles for backwards compatibility:
19
+ * - new PayrollError(message, code?, status?, context?)
20
+ * - new PayrollError(code, status, message, context?)
21
+ */
22
+ constructor(messageOrCode: string | ErrorCode, codeOrStatus?: ErrorCode | number, statusOrMessage?: number | string, context?: Record<string, unknown>);
23
+ /**
24
+ * Convert error to JSON for API responses (ClockIn-compatible shape)
25
+ */
26
+ toJSON(): Record<string, unknown>;
27
+ /**
28
+ * Check if error is operational (expected) vs programmer error
29
+ */
30
+ isOperational(): boolean;
31
+ }
32
+ /**
33
+ * Not initialized error
34
+ */
35
+ declare class NotInitializedError extends PayrollError {
36
+ constructor(message?: string);
37
+ }
38
+ /**
39
+ * Employee not found error
40
+ */
41
+ declare class EmployeeNotFoundError extends PayrollError {
42
+ constructor(employeeId?: string, context?: Record<string, unknown>);
43
+ }
44
+ /**
45
+ * Invalid employee error
46
+ */
47
+ declare class InvalidEmployeeError extends PayrollError {
48
+ constructor(message: string, context?: Record<string, unknown>);
49
+ }
50
+ /**
51
+ * Duplicate payroll error
52
+ */
53
+ declare class DuplicatePayrollError extends PayrollError {
54
+ constructor(employeeId: string, month: number, year: number, payrollRunType?: string, context?: Record<string, unknown>);
55
+ }
56
+ /**
57
+ * Validation error
58
+ */
59
+ declare class ValidationError extends PayrollError {
60
+ readonly errors: string[];
61
+ constructor(errors: string | string[], context?: Record<string, unknown>);
62
+ }
63
+ /**
64
+ * Employee terminated error
65
+ */
66
+ declare class EmployeeTerminatedError extends PayrollError {
67
+ constructor(employeeId?: string, context?: Record<string, unknown>);
68
+ }
69
+ /**
70
+ * Already processed error
71
+ */
72
+ declare class AlreadyProcessedError extends PayrollError {
73
+ constructor(message: string, context?: Record<string, unknown>);
74
+ }
75
+ /**
76
+ * Not eligible error
77
+ */
78
+ declare class NotEligibleError extends PayrollError {
79
+ constructor(message: string, context?: Record<string, unknown>);
80
+ }
81
+ /**
82
+ * Security error (unauthorized access, cross-organization access, etc.)
83
+ */
84
+ declare class SecurityError extends PayrollError {
85
+ constructor(message: string, context?: Record<string, unknown>);
86
+ }
87
+ /**
88
+ * Create error from code
89
+ */
90
+ declare function createError(code: ErrorCode, message: string, context?: Record<string, unknown>): PayrollError;
91
+ /**
92
+ * Check if error is PayrollError
93
+ */
94
+ declare function isPayrollError(error: unknown): error is PayrollError;
95
+ /**
96
+ * Extract error info for logging
97
+ */
98
+ declare function extractErrorInfo(error: unknown): {
99
+ code: string;
100
+ status: number;
101
+ message: string;
102
+ context?: Record<string, unknown>;
103
+ };
104
+ /**
105
+ * Convert unknown error to PayrollError
106
+ */
107
+ declare function toPayrollError(error: unknown): PayrollError;
3
108
 
4
109
  /**
5
110
  * @classytic/payroll - Leave Utilities
@@ -232,7 +337,7 @@ interface SecureEmployeeLookupOptions {
232
337
  /**
233
338
  * Mongoose session for transactions
234
339
  */
235
- session?: any;
340
+ session?: ClientSession;
236
341
  /**
237
342
  * Fields to populate
238
343
  */
@@ -296,8 +401,8 @@ declare function employeeExistsSecure<T extends EmployeeDocument>(model: Model<T
296
401
  */
297
402
  declare function findEmployeesSecure<T extends EmployeeDocument>(model: Model<T>, options: {
298
403
  organizationId: ObjectIdLike;
299
- filter?: Record<string, any>;
300
- session?: any;
404
+ filter?: Record<string, unknown>;
405
+ session?: ClientSession;
301
406
  limit?: number;
302
407
  skip?: number;
303
408
  sort?: Record<string, 1 | -1>;
@@ -328,7 +433,7 @@ declare function requireOrganizationId(organizationId: ObjectIdLike | undefined,
328
433
  interface ContainerLike {
329
434
  isSingleTenant(): boolean;
330
435
  getSingleTenantConfig(): {
331
- organizationId?: any;
436
+ organizationId?: ObjectIdLike;
332
437
  autoInject?: boolean;
333
438
  } | null;
334
439
  getOrganizationId(): string | null;
@@ -487,4 +592,149 @@ declare function isObjectIdEmployeeId(value: unknown): value is ObjectIdLike;
487
592
  */
488
593
  declare function formatEmployeeId(employeeId: ObjectIdLike | string): string;
489
594
 
490
- export { validateOrganizationId as A, type ContainerLike as C, DEFAULT_CARRY_OVER as D, type EmployeeIdMode as E, type ResolveOrganizationIdParams as R, type SecureEmployeeLookupOptions as S, _default as _, DEFAULT_LEAVE_ALLOCATIONS as a, type EmployeeIdType as b, type EmployeeQueryFilter as c, accrueLeaveToBalance as d, calculateCarryOver as e, calculateLeaveDays as f, calculateUnpaidLeaveDeduction as g, detectEmployeeIdType as h, employeeExistsSecure as i, findEmployeeSecure as j, findEmployeesSecure as k, formatEmployeeId as l, getAvailableDays as m, getLeaveBalance as n, getLeaveBalances as o, getLeaveSummary as p, getUnpaidLeaveDays as q, hasLeaveBalance as r, initializeLeaveBalances as s, isObjectIdEmployeeId as t, isStringEmployeeId as u, normalizeEmployeeId as v, proRateAllocation as w, requireOrganizationId as x, resolveOrganizationId as y, tryResolveOrganizationId as z };
595
+ /**
596
+ * @classytic/payroll - Error Helpers
597
+ *
598
+ * Higher-level error handling utilities that combine type guards
599
+ * and error classes for common payroll error scenarios.
600
+ *
601
+ * Uses:
602
+ * - `../errors/index.js` for PayrollError classes
603
+ * - `./type-guards.js` for MongoDB error type checking
604
+ *
605
+ * @module @classytic/payroll/utils/error-helpers
606
+ */
607
+
608
+ interface TransactionErrorResult {
609
+ /** Whether the error is transaction-related */
610
+ isTransactionError: boolean;
611
+ /** Whether transactions are unsupported (standalone MongoDB) */
612
+ isUnsupported: boolean;
613
+ /** Whether the operation can be safely retried */
614
+ retryable: boolean;
615
+ /** Wrapped PayrollError with context */
616
+ error: PayrollError;
617
+ /** Original error for logging */
618
+ originalError: unknown;
619
+ }
620
+ /**
621
+ * Handle transaction-specific errors with categorization and retry guidance.
622
+ *
623
+ * Categorizes transaction errors into:
624
+ * - **Unsupported**: Standalone MongoDB without replica set (non-retryable, graceful fallback)
625
+ * - **Transient**: Network issues, coordinator changes (retryable)
626
+ * - **Connection**: Server unreachable, shutdown (retryable after delay)
627
+ * - **Other**: Unknown transaction errors (non-retryable)
628
+ *
629
+ * @param error - Unknown error from a transaction operation
630
+ * @param operationName - Name of the operation for context (e.g., 'processSalary')
631
+ * @returns Structured error result with retry guidance
632
+ *
633
+ * @example
634
+ * ```typescript
635
+ * try {
636
+ * await processWithTransaction(session);
637
+ * } catch (error) {
638
+ * const result = handleTransactionError(error, 'processSalary');
639
+ * if (result.isUnsupported) {
640
+ * // Fall back to non-transactional processing
641
+ * await processWithoutTransaction();
642
+ * } else if (result.retryable) {
643
+ * // Retry the operation
644
+ * await retry(() => processWithTransaction(session));
645
+ * } else {
646
+ * throw result.error;
647
+ * }
648
+ * }
649
+ * ```
650
+ */
651
+ declare function handleTransactionError(error: unknown, operationName: string): TransactionErrorResult;
652
+ interface DuplicateKeyErrorResult {
653
+ /** Whether the error is a duplicate key error */
654
+ isDuplicate: boolean;
655
+ /** The field name that caused the duplicate */
656
+ field: string;
657
+ /** Wrapped DuplicatePayrollError or PayrollError */
658
+ error: PayrollError;
659
+ }
660
+ /**
661
+ * Handle MongoDB duplicate key errors with field extraction.
662
+ *
663
+ * Converts raw MongoDB E11000 errors into structured DuplicatePayrollError
664
+ * or PayrollError with the duplicate field identified.
665
+ *
666
+ * @param error - Unknown error from a create/update operation
667
+ * @param context - Additional context for the error
668
+ * @returns Structured duplicate key error result
669
+ *
670
+ * @example
671
+ * ```typescript
672
+ * try {
673
+ * await PayrollRecord.create(data);
674
+ * } catch (error) {
675
+ * const result = handleDuplicateKeyError(error, {
676
+ * employeeId: 'EMP-001',
677
+ * month: 1,
678
+ * year: 2024,
679
+ * });
680
+ * if (result.isDuplicate) {
681
+ * throw result.error; // DuplicatePayrollError with field info
682
+ * }
683
+ * throw error; // Re-throw non-duplicate errors
684
+ * }
685
+ * ```
686
+ */
687
+ declare function handleDuplicateKeyError(error: unknown, context?: {
688
+ employeeId?: string;
689
+ month?: number;
690
+ year?: number;
691
+ }): DuplicateKeyErrorResult;
692
+ interface PayrollErrorResult {
693
+ /** Error code for programmatic handling */
694
+ code: string;
695
+ /** HTTP status code */
696
+ status: number;
697
+ /** Human-readable error message */
698
+ message: string;
699
+ /** Additional context */
700
+ context: Record<string, unknown>;
701
+ /** Whether the error is operational (expected) vs programmer error */
702
+ operational: boolean;
703
+ /** Whether the operation can be retried */
704
+ retryable: boolean;
705
+ }
706
+ /**
707
+ * Handle any payroll operation error and produce a structured result.
708
+ *
709
+ * Combines error classification from type-guards with PayrollError
710
+ * extraction to produce a unified error result suitable for API responses,
711
+ * logging, or retry decisions.
712
+ *
713
+ * @param error - Unknown error from any payroll operation
714
+ * @param operationName - Name of the operation for context
715
+ * @returns Structured error result
716
+ *
717
+ * @example
718
+ * ```typescript
719
+ * try {
720
+ * await payroll.processSalary(params);
721
+ * } catch (error) {
722
+ * const result = handlePayrollError(error, 'processSalary');
723
+ * logger.error(result.message, { code: result.code, context: result.context });
724
+ * res.status(result.status).json({ error: result });
725
+ * }
726
+ * ```
727
+ */
728
+ declare function handlePayrollError(error: unknown, operationName: string): PayrollErrorResult;
729
+ /**
730
+ * Format error for user-facing display.
731
+ *
732
+ * Strips internal details and produces a clean message suitable
733
+ * for API responses or UI display.
734
+ *
735
+ * @param error - Unknown error
736
+ * @returns User-safe error message
737
+ */
738
+ declare function formatUserError(error: unknown): string;
739
+
740
+ export { toPayrollError as $, normalizeEmployeeId as A, proRateAllocation as B, type ContainerLike as C, DEFAULT_CARRY_OVER as D, type EmployeeIdMode as E, requireOrganizationId as F, resolveOrganizationId as G, tryResolveOrganizationId as H, validateOrganizationId as I, AlreadyProcessedError as J, DuplicatePayrollError as K, EmployeeNotFoundError as L, EmployeeTerminatedError as M, InvalidEmployeeError as N, NotEligibleError as O, type PayrollErrorResult as P, NotInitializedError as Q, type ResolveOrganizationIdParams as R, type SecureEmployeeLookupOptions as S, type TransactionErrorResult as T, PayrollError as U, SecurityError as V, ValidationError as W, createError as X, extractErrorInfo as Y, isPayrollError as Z, _default as _, DEFAULT_LEAVE_ALLOCATIONS as a, type DuplicateKeyErrorResult as b, type EmployeeIdType as c, type EmployeeQueryFilter as d, accrueLeaveToBalance as e, calculateCarryOver as f, calculateLeaveDays as g, calculateUnpaidLeaveDeduction as h, detectEmployeeIdType as i, employeeExistsSecure as j, findEmployeeSecure as k, findEmployeesSecure as l, formatEmployeeId as m, formatUserError as n, getAvailableDays as o, getLeaveBalance as p, getLeaveBalances as q, getLeaveSummary as r, getUnpaidLeaveDays as s, handleDuplicateKeyError as t, handlePayrollError as u, handleTransactionError as v, hasLeaveBalance as w, initializeLeaveBalances as x, isObjectIdEmployeeId as y, isStringEmployeeId as z };