@managemint-solutions/sdk 0.35.0 → 0.37.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.
@@ -0,0 +1,375 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ReviewLeaveRequestDto = exports.UpdateLeaveRequestDto = exports.CreateLeaveRequestDto = exports.GetLeaveRequestsDto = exports.LeaveRequestIdDto = exports.UpdateLeaveEntitlementDto = exports.CreateLeaveEntitlementDto = exports.GetLeaveEntitlementsDto = exports.LeaveEntitlementIdDto = exports.UpdateLeaveTypeDto = exports.CreateLeaveTypeDto = exports.GetLeaveTypesDto = exports.LeaveTypeIdDto = void 0;
13
+ const class_validator_1 = require("class-validator");
14
+ const class_transformer_1 = require("class-transformer");
15
+ const enum_1 = require("@managemint-solutions/entities/leave/enum");
16
+ const validators_1 = require("../validators");
17
+ // class-validator versions of the shared DTO types from @managemint-solutions/entities.
18
+ // Each class `implements` its entities type so the wire contract cannot drift.
19
+ //
20
+ // Body fields are required: a nullable one carries `@IsNullable()` without `@IsOptional()`,
21
+ // so `null` passes and a missing key fails. Only the query-string filters are optional.
22
+ const Trim = () => (0, class_transformer_1.Transform)(({ value }) => (typeof value === 'string' ? value.trim() : value), { toClassOnly: true });
23
+ /** A query-string tri-state: `'true'`/`'false'` become booleans, anything else is left to fail. */
24
+ const QueryBoolean = () => (0, class_transformer_1.Transform)(({ value }) => (value === 'true' ? true : value === 'false' ? false : value), {
25
+ toClassOnly: true,
26
+ });
27
+ // The users columns (`user_id`) are v4: they carry the GoTrue auth uid the signup trigger copies
28
+ // out of `auth.users.id`, so the table's uuidv7 default never fires. Every other id is v7.
29
+ // ---- Leave types ----
30
+ class LeaveTypeIdDto {
31
+ leaveTypeId;
32
+ }
33
+ exports.LeaveTypeIdDto = LeaveTypeIdDto;
34
+ __decorate([
35
+ (0, class_validator_1.IsUUID)('7', { message: 'Invalid leave type ID format' }),
36
+ __metadata("design:type", String)
37
+ ], LeaveTypeIdDto.prototype, "leaveTypeId", void 0);
38
+ class GetLeaveTypesDto {
39
+ active;
40
+ }
41
+ exports.GetLeaveTypesDto = GetLeaveTypesDto;
42
+ __decorate([
43
+ (0, class_validator_1.IsOptional)(),
44
+ (0, validators_1.IsNullable)(),
45
+ QueryBoolean(),
46
+ (0, class_validator_1.IsBoolean)({ message: 'Active must be true or false' }),
47
+ __metadata("design:type", Object)
48
+ ], GetLeaveTypesDto.prototype, "active", void 0);
49
+ class CreateLeaveTypeDto {
50
+ name;
51
+ description;
52
+ default_days;
53
+ is_paid;
54
+ requires_approval;
55
+ }
56
+ exports.CreateLeaveTypeDto = CreateLeaveTypeDto;
57
+ __decorate([
58
+ Trim(),
59
+ (0, class_validator_1.IsString)({ message: 'Invalid name' }),
60
+ (0, class_validator_1.MinLength)(1, { message: 'Name cannot be empty' }),
61
+ (0, class_validator_1.MaxLength)(100, { message: 'Name cannot exceed 100 characters' }),
62
+ __metadata("design:type", String)
63
+ ], CreateLeaveTypeDto.prototype, "name", void 0);
64
+ __decorate([
65
+ (0, validators_1.EmptyToNull)(),
66
+ (0, validators_1.IsNullable)(),
67
+ (0, class_validator_1.IsString)({ message: 'Invalid description' }),
68
+ (0, class_validator_1.MaxLength)(2000, { message: 'Description cannot exceed 2000 characters' }),
69
+ __metadata("design:type", Object)
70
+ ], CreateLeaveTypeDto.prototype, "description", void 0);
71
+ __decorate([
72
+ (0, class_validator_1.IsNumber)({ maxDecimalPlaces: 1 }, { message: 'Default days must be a number with at most one decimal' }),
73
+ (0, class_validator_1.Min)(0, { message: 'Default days cannot be negative' }),
74
+ (0, class_validator_1.Max)(999.9, { message: 'Default days cannot exceed 999.9' }),
75
+ __metadata("design:type", Number)
76
+ ], CreateLeaveTypeDto.prototype, "default_days", void 0);
77
+ __decorate([
78
+ (0, class_validator_1.IsBoolean)({ message: 'Is paid must be true or false' }),
79
+ __metadata("design:type", Boolean)
80
+ ], CreateLeaveTypeDto.prototype, "is_paid", void 0);
81
+ __decorate([
82
+ (0, class_validator_1.IsBoolean)({ message: 'Requires approval must be true or false' }),
83
+ __metadata("design:type", Boolean)
84
+ ], CreateLeaveTypeDto.prototype, "requires_approval", void 0);
85
+ class UpdateLeaveTypeDto {
86
+ name;
87
+ description;
88
+ default_days;
89
+ is_paid;
90
+ requires_approval;
91
+ active;
92
+ }
93
+ exports.UpdateLeaveTypeDto = UpdateLeaveTypeDto;
94
+ __decorate([
95
+ Trim(),
96
+ (0, class_validator_1.IsString)({ message: 'Invalid name' }),
97
+ (0, class_validator_1.MinLength)(1, { message: 'Name cannot be empty' }),
98
+ (0, class_validator_1.MaxLength)(100, { message: 'Name cannot exceed 100 characters' }),
99
+ __metadata("design:type", String)
100
+ ], UpdateLeaveTypeDto.prototype, "name", void 0);
101
+ __decorate([
102
+ (0, validators_1.EmptyToNull)(),
103
+ (0, validators_1.IsNullable)(),
104
+ (0, class_validator_1.IsString)({ message: 'Invalid description' }),
105
+ (0, class_validator_1.MaxLength)(2000, { message: 'Description cannot exceed 2000 characters' }),
106
+ __metadata("design:type", Object)
107
+ ], UpdateLeaveTypeDto.prototype, "description", void 0);
108
+ __decorate([
109
+ (0, class_validator_1.IsNumber)({ maxDecimalPlaces: 1 }, { message: 'Default days must be a number with at most one decimal' }),
110
+ (0, class_validator_1.Min)(0, { message: 'Default days cannot be negative' }),
111
+ (0, class_validator_1.Max)(999.9, { message: 'Default days cannot exceed 999.9' }),
112
+ __metadata("design:type", Number)
113
+ ], UpdateLeaveTypeDto.prototype, "default_days", void 0);
114
+ __decorate([
115
+ (0, class_validator_1.IsBoolean)({ message: 'Is paid must be true or false' }),
116
+ __metadata("design:type", Boolean)
117
+ ], UpdateLeaveTypeDto.prototype, "is_paid", void 0);
118
+ __decorate([
119
+ (0, class_validator_1.IsBoolean)({ message: 'Requires approval must be true or false' }),
120
+ __metadata("design:type", Boolean)
121
+ ], UpdateLeaveTypeDto.prototype, "requires_approval", void 0);
122
+ __decorate([
123
+ (0, class_validator_1.IsBoolean)({ message: 'Active must be true or false' }),
124
+ __metadata("design:type", Boolean)
125
+ ], UpdateLeaveTypeDto.prototype, "active", void 0);
126
+ // ---- Leave entitlements ----
127
+ class LeaveEntitlementIdDto {
128
+ leaveEntitlementId;
129
+ }
130
+ exports.LeaveEntitlementIdDto = LeaveEntitlementIdDto;
131
+ __decorate([
132
+ (0, class_validator_1.IsUUID)('7', { message: 'Invalid leave entitlement ID format' }),
133
+ __metadata("design:type", String)
134
+ ], LeaveEntitlementIdDto.prototype, "leaveEntitlementId", void 0);
135
+ class GetLeaveEntitlementsDto {
136
+ page = 1;
137
+ page_size = 10;
138
+ user_id;
139
+ leave_type_id;
140
+ as_of;
141
+ }
142
+ exports.GetLeaveEntitlementsDto = GetLeaveEntitlementsDto;
143
+ __decorate([
144
+ (0, class_validator_1.IsOptional)(),
145
+ (0, class_transformer_1.Transform)(({ value }) => value ? Number(value) : 1, { toClassOnly: true }),
146
+ (0, class_validator_1.IsNumber)({}, { message: 'Page must be a number' }),
147
+ (0, class_validator_1.Min)(1, { message: 'Page must be at least 1' }),
148
+ __metadata("design:type", Number)
149
+ ], GetLeaveEntitlementsDto.prototype, "page", void 0);
150
+ __decorate([
151
+ (0, class_validator_1.IsOptional)(),
152
+ (0, class_transformer_1.Transform)(({ value }) => value ? Number(value) : 10, { toClassOnly: true }),
153
+ (0, class_validator_1.IsNumber)({}, { message: 'Page size must be a number' }),
154
+ (0, class_validator_1.Min)(1, { message: 'Page size must be at least 1' }),
155
+ (0, class_validator_1.Max)(100, { message: 'Page size cannot exceed 100' }),
156
+ __metadata("design:type", Number)
157
+ ], GetLeaveEntitlementsDto.prototype, "page_size", void 0);
158
+ __decorate([
159
+ (0, class_validator_1.IsOptional)(),
160
+ (0, validators_1.IsNullable)(),
161
+ (0, class_validator_1.IsUUID)('4', { message: 'Invalid user ID format' }),
162
+ __metadata("design:type", Object)
163
+ ], GetLeaveEntitlementsDto.prototype, "user_id", void 0);
164
+ __decorate([
165
+ (0, class_validator_1.IsOptional)(),
166
+ (0, validators_1.IsNullable)(),
167
+ (0, class_validator_1.IsUUID)('7', { message: 'Invalid leave type ID format' }),
168
+ __metadata("design:type", Object)
169
+ ], GetLeaveEntitlementsDto.prototype, "leave_type_id", void 0);
170
+ __decorate([
171
+ (0, class_validator_1.IsOptional)(),
172
+ (0, validators_1.IsNullable)(),
173
+ (0, validators_1.IsCalendarDate)({ message: 'As of must be a calendar date (YYYY-MM-DD)' }),
174
+ __metadata("design:type", Object)
175
+ ], GetLeaveEntitlementsDto.prototype, "as_of", void 0);
176
+ class CreateLeaveEntitlementDto {
177
+ user_id;
178
+ leave_type_id;
179
+ days_entitled;
180
+ period_start;
181
+ period_end;
182
+ notes;
183
+ }
184
+ exports.CreateLeaveEntitlementDto = CreateLeaveEntitlementDto;
185
+ __decorate([
186
+ (0, class_validator_1.IsUUID)('4', { message: 'Invalid user ID format' }),
187
+ __metadata("design:type", String)
188
+ ], CreateLeaveEntitlementDto.prototype, "user_id", void 0);
189
+ __decorate([
190
+ (0, class_validator_1.IsUUID)('7', { message: 'Invalid leave type ID format' }),
191
+ __metadata("design:type", String)
192
+ ], CreateLeaveEntitlementDto.prototype, "leave_type_id", void 0);
193
+ __decorate([
194
+ (0, class_validator_1.IsNumber)({ maxDecimalPlaces: 1 }, { message: 'Days entitled must be a number with at most one decimal' }),
195
+ (0, class_validator_1.Min)(0, { message: 'Days entitled cannot be negative' }),
196
+ (0, class_validator_1.Max)(999.9, { message: 'Days entitled cannot exceed 999.9' }),
197
+ __metadata("design:type", Number)
198
+ ], CreateLeaveEntitlementDto.prototype, "days_entitled", void 0);
199
+ __decorate([
200
+ (0, validators_1.IsNullable)(),
201
+ (0, validators_1.IsCalendarDate)({ message: 'Period start must be a calendar date (YYYY-MM-DD)' }),
202
+ __metadata("design:type", Object)
203
+ ], CreateLeaveEntitlementDto.prototype, "period_start", void 0);
204
+ __decorate([
205
+ (0, validators_1.IsNullable)(),
206
+ (0, validators_1.IsCalendarDate)({ message: 'Period end must be a calendar date (YYYY-MM-DD)' }),
207
+ __metadata("design:type", Object)
208
+ ], CreateLeaveEntitlementDto.prototype, "period_end", void 0);
209
+ __decorate([
210
+ (0, validators_1.EmptyToNull)(),
211
+ (0, validators_1.IsNullable)(),
212
+ (0, class_validator_1.IsString)({ message: 'Invalid notes' }),
213
+ (0, class_validator_1.MaxLength)(2000, { message: 'Notes cannot exceed 2000 characters' }),
214
+ __metadata("design:type", Object)
215
+ ], CreateLeaveEntitlementDto.prototype, "notes", void 0);
216
+ class UpdateLeaveEntitlementDto {
217
+ days_entitled;
218
+ period_end;
219
+ notes;
220
+ }
221
+ exports.UpdateLeaveEntitlementDto = UpdateLeaveEntitlementDto;
222
+ __decorate([
223
+ (0, class_validator_1.IsNumber)({ maxDecimalPlaces: 1 }, { message: 'Days entitled must be a number with at most one decimal' }),
224
+ (0, class_validator_1.Min)(0, { message: 'Days entitled cannot be negative' }),
225
+ (0, class_validator_1.Max)(999.9, { message: 'Days entitled cannot exceed 999.9' }),
226
+ __metadata("design:type", Number)
227
+ ], UpdateLeaveEntitlementDto.prototype, "days_entitled", void 0);
228
+ __decorate([
229
+ (0, validators_1.IsCalendarDate)({ message: 'Period end must be a calendar date (YYYY-MM-DD)' }),
230
+ __metadata("design:type", String)
231
+ ], UpdateLeaveEntitlementDto.prototype, "period_end", void 0);
232
+ __decorate([
233
+ (0, validators_1.EmptyToNull)(),
234
+ (0, validators_1.IsNullable)(),
235
+ (0, class_validator_1.IsString)({ message: 'Invalid notes' }),
236
+ (0, class_validator_1.MaxLength)(2000, { message: 'Notes cannot exceed 2000 characters' }),
237
+ __metadata("design:type", Object)
238
+ ], UpdateLeaveEntitlementDto.prototype, "notes", void 0);
239
+ // ---- Leave requests ----
240
+ class LeaveRequestIdDto {
241
+ leaveRequestId;
242
+ }
243
+ exports.LeaveRequestIdDto = LeaveRequestIdDto;
244
+ __decorate([
245
+ (0, class_validator_1.IsUUID)('7', { message: 'Invalid leave request ID format' }),
246
+ __metadata("design:type", String)
247
+ ], LeaveRequestIdDto.prototype, "leaveRequestId", void 0);
248
+ class GetLeaveRequestsDto {
249
+ page = 1;
250
+ page_size = 10;
251
+ user_id;
252
+ status;
253
+ start_date_after;
254
+ start_date_before;
255
+ }
256
+ exports.GetLeaveRequestsDto = GetLeaveRequestsDto;
257
+ __decorate([
258
+ (0, class_validator_1.IsOptional)(),
259
+ (0, class_transformer_1.Transform)(({ value }) => value ? Number(value) : 1, { toClassOnly: true }),
260
+ (0, class_validator_1.IsNumber)({}, { message: 'Page must be a number' }),
261
+ (0, class_validator_1.Min)(1, { message: 'Page must be at least 1' }),
262
+ __metadata("design:type", Number)
263
+ ], GetLeaveRequestsDto.prototype, "page", void 0);
264
+ __decorate([
265
+ (0, class_validator_1.IsOptional)(),
266
+ (0, class_transformer_1.Transform)(({ value }) => value ? Number(value) : 10, { toClassOnly: true }),
267
+ (0, class_validator_1.IsNumber)({}, { message: 'Page size must be a number' }),
268
+ (0, class_validator_1.Min)(1, { message: 'Page size must be at least 1' }),
269
+ (0, class_validator_1.Max)(100, { message: 'Page size cannot exceed 100' }),
270
+ __metadata("design:type", Number)
271
+ ], GetLeaveRequestsDto.prototype, "page_size", void 0);
272
+ __decorate([
273
+ (0, class_validator_1.IsOptional)(),
274
+ (0, validators_1.IsNullable)(),
275
+ (0, class_validator_1.IsUUID)('4', { message: 'Invalid user ID format' }),
276
+ __metadata("design:type", Object)
277
+ ], GetLeaveRequestsDto.prototype, "user_id", void 0);
278
+ __decorate([
279
+ (0, class_validator_1.IsOptional)(),
280
+ (0, validators_1.IsNullable)(),
281
+ (0, class_validator_1.IsEnum)(enum_1.LeaveRequestStatus, { message: 'Invalid status' }),
282
+ __metadata("design:type", Object)
283
+ ], GetLeaveRequestsDto.prototype, "status", void 0);
284
+ __decorate([
285
+ (0, class_validator_1.IsOptional)(),
286
+ (0, validators_1.IsNullable)(),
287
+ (0, validators_1.IsCalendarDate)({ message: 'Start date after must be a calendar date (YYYY-MM-DD)' }),
288
+ __metadata("design:type", Object)
289
+ ], GetLeaveRequestsDto.prototype, "start_date_after", void 0);
290
+ __decorate([
291
+ (0, class_validator_1.IsOptional)(),
292
+ (0, validators_1.IsNullable)(),
293
+ (0, validators_1.IsCalendarDate)({ message: 'Start date before must be a calendar date (YYYY-MM-DD)' }),
294
+ __metadata("design:type", Object)
295
+ ], GetLeaveRequestsDto.prototype, "start_date_before", void 0);
296
+ // No `user_id`: a request is always the caller's own. Filing on someone's behalf is a later
297
+ // feature, and leaving the field out is what keeps a forged one from validating.
298
+ class CreateLeaveRequestDto {
299
+ leave_type_id;
300
+ start_date;
301
+ end_date;
302
+ is_half_day;
303
+ reason;
304
+ }
305
+ exports.CreateLeaveRequestDto = CreateLeaveRequestDto;
306
+ __decorate([
307
+ (0, class_validator_1.IsUUID)('7', { message: 'Invalid leave type ID format' }),
308
+ __metadata("design:type", String)
309
+ ], CreateLeaveRequestDto.prototype, "leave_type_id", void 0);
310
+ __decorate([
311
+ (0, validators_1.IsCalendarDate)({ message: 'Start date must be a calendar date (YYYY-MM-DD)' }),
312
+ __metadata("design:type", String)
313
+ ], CreateLeaveRequestDto.prototype, "start_date", void 0);
314
+ __decorate([
315
+ (0, validators_1.IsCalendarDate)({ message: 'End date must be a calendar date (YYYY-MM-DD)' }),
316
+ __metadata("design:type", String)
317
+ ], CreateLeaveRequestDto.prototype, "end_date", void 0);
318
+ __decorate([
319
+ (0, class_validator_1.IsBoolean)({ message: 'Is half day must be true or false' }),
320
+ __metadata("design:type", Boolean)
321
+ ], CreateLeaveRequestDto.prototype, "is_half_day", void 0);
322
+ __decorate([
323
+ (0, validators_1.EmptyToNull)(),
324
+ (0, validators_1.IsNullable)(),
325
+ (0, class_validator_1.IsString)({ message: 'Invalid reason' }),
326
+ (0, class_validator_1.MaxLength)(2000, { message: 'Reason cannot exceed 2000 characters' }),
327
+ __metadata("design:type", Object)
328
+ ], CreateLeaveRequestDto.prototype, "reason", void 0);
329
+ class UpdateLeaveRequestDto {
330
+ leave_type_id;
331
+ start_date;
332
+ end_date;
333
+ is_half_day;
334
+ reason;
335
+ }
336
+ exports.UpdateLeaveRequestDto = UpdateLeaveRequestDto;
337
+ __decorate([
338
+ (0, class_validator_1.IsUUID)('7', { message: 'Invalid leave type ID format' }),
339
+ __metadata("design:type", String)
340
+ ], UpdateLeaveRequestDto.prototype, "leave_type_id", void 0);
341
+ __decorate([
342
+ (0, validators_1.IsCalendarDate)({ message: 'Start date must be a calendar date (YYYY-MM-DD)' }),
343
+ __metadata("design:type", String)
344
+ ], UpdateLeaveRequestDto.prototype, "start_date", void 0);
345
+ __decorate([
346
+ (0, validators_1.IsCalendarDate)({ message: 'End date must be a calendar date (YYYY-MM-DD)' }),
347
+ __metadata("design:type", String)
348
+ ], UpdateLeaveRequestDto.prototype, "end_date", void 0);
349
+ __decorate([
350
+ (0, class_validator_1.IsBoolean)({ message: 'Is half day must be true or false' }),
351
+ __metadata("design:type", Boolean)
352
+ ], UpdateLeaveRequestDto.prototype, "is_half_day", void 0);
353
+ __decorate([
354
+ (0, validators_1.EmptyToNull)(),
355
+ (0, validators_1.IsNullable)(),
356
+ (0, class_validator_1.IsString)({ message: 'Invalid reason' }),
357
+ (0, class_validator_1.MaxLength)(2000, { message: 'Reason cannot exceed 2000 characters' }),
358
+ __metadata("design:type", Object)
359
+ ], UpdateLeaveRequestDto.prototype, "reason", void 0);
360
+ class ReviewLeaveRequestDto {
361
+ status;
362
+ review_note;
363
+ }
364
+ exports.ReviewLeaveRequestDto = ReviewLeaveRequestDto;
365
+ __decorate([
366
+ (0, class_validator_1.IsEnum)(enum_1.LeaveReviewDecision, { message: 'Status must be approved or rejected' }),
367
+ __metadata("design:type", String)
368
+ ], ReviewLeaveRequestDto.prototype, "status", void 0);
369
+ __decorate([
370
+ (0, validators_1.EmptyToNull)(),
371
+ (0, validators_1.IsNullable)(),
372
+ (0, class_validator_1.IsString)({ message: 'Invalid review note' }),
373
+ (0, class_validator_1.MaxLength)(2000, { message: 'Review note cannot exceed 2000 characters' }),
374
+ __metadata("design:type", Object)
375
+ ], ReviewLeaveRequestDto.prototype, "review_note", void 0);
@@ -0,0 +1,5 @@
1
+ export * from './dto';
2
+ export * from './working-days';
3
+ export { LeaveTypesResource } from './leave-types';
4
+ export { LeaveEntitlementsResource, type CreateLeaveEntitlementInput, type LeaveEntitlementCover, } from './leave-entitlements';
5
+ export { LeaveRequestsResource, type CreateLeaveRequestRow, type ReviewLeaveRequestRow, type UpdateLeaveRequestRow, } from './leave-requests';
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ // Leave, the first slice of the HR module: one resource per table, the DTOs the api validates
3
+ // with, and the calendar arithmetic the api counts days with. The resources hang off
4
+ // `SupabaseClient` as `leaveTypes`, `leaveEntitlements` and `leaveRequests`; the holiday
5
+ // calendar the day count reads is its own resource, `publicHolidays` (src/public-holidays).
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
18
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.LeaveRequestsResource = exports.LeaveEntitlementsResource = exports.LeaveTypesResource = void 0;
22
+ __exportStar(require("./dto"), exports);
23
+ __exportStar(require("./working-days"), exports);
24
+ var leave_types_1 = require("./leave-types");
25
+ Object.defineProperty(exports, "LeaveTypesResource", { enumerable: true, get: function () { return leave_types_1.LeaveTypesResource; } });
26
+ var leave_entitlements_1 = require("./leave-entitlements");
27
+ Object.defineProperty(exports, "LeaveEntitlementsResource", { enumerable: true, get: function () { return leave_entitlements_1.LeaveEntitlementsResource; } });
28
+ var leave_requests_1 = require("./leave-requests");
29
+ Object.defineProperty(exports, "LeaveRequestsResource", { enumerable: true, get: function () { return leave_requests_1.LeaveRequestsResource; } });
@@ -0,0 +1,42 @@
1
+ import type { MmsList } from '@managemint-solutions/entities/common';
2
+ import type { LeaveEntitlementEntity, LeavePeriod } from '@managemint-solutions/entities/leave';
3
+ import type { AuthContext } from '../auth';
4
+ import { type AuditResource } from '../audit';
5
+ import type { TypedSupabaseClient } from '../client';
6
+ import type { GetLeaveEntitlementsDto, UpdateLeaveEntitlementDto } from './dto';
7
+ /** What the request path needs of the entitlement covering a date: the period and the cap. */
8
+ export type LeaveEntitlementCover = LeavePeriod & {
9
+ mms_id: string;
10
+ days_entitled: number;
11
+ };
12
+ /** The create input after the api has resolved the period defaults. */
13
+ export type CreateLeaveEntitlementInput = LeavePeriod & {
14
+ user_id: string;
15
+ leave_type_id: string;
16
+ days_entitled: number;
17
+ notes?: string | null;
18
+ };
19
+ export declare class LeaveEntitlementsResource {
20
+ private readonly supabase;
21
+ private readonly auth;
22
+ private readonly table;
23
+ constructor(supabase: TypedSupabaseClient, auth: AuthContext, audit: AuditResource);
24
+ list(query: GetLeaveEntitlementsDto): Promise<MmsList<LeaveEntitlementEntity>>;
25
+ getById(leaveEntitlementId: string): Promise<LeaveEntitlementEntity>;
26
+ /**
27
+ * The entitlement of `userId` for `leaveTypeId` whose period contains `date`, or null when the
28
+ * type is not tracked for them then. The periods of one user and type cannot overlap (the
29
+ * table's exclusion constraint), so there is at most one.
30
+ */
31
+ findFor(userId: string, leaveTypeId: string, date: string): Promise<LeaveEntitlementCover | null>;
32
+ create(input: CreateLeaveEntitlementInput): Promise<LeaveEntitlementEntity>;
33
+ update(leaveEntitlementId: string, input: UpdateLeaveEntitlementDto): Promise<LeaveEntitlementEntity>;
34
+ /** Hard delete: the type simply becomes untracked for that user and period. */
35
+ remove(leaveEntitlementId: string): Promise<void>;
36
+ /**
37
+ * Adds the computed balance to each row from one query over the requests that could count
38
+ * against any of them - the approved and pending ones of these users and types, starting in
39
+ * the span the periods cover. Nothing is stored: a balance is always what the requests say.
40
+ */
41
+ private withBalances;
42
+ }
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LeaveEntitlementsResource = void 0;
4
+ const enum_1 = require("@managemint-solutions/entities/audit-trail/enum");
5
+ const enum_2 = require("@managemint-solutions/entities/leave/enum");
6
+ const audit_1 = require("../audit");
7
+ const errors_1 = require("../errors");
8
+ const transforms_1 = require("../transforms");
9
+ const LEAVE_ENTITLEMENT_SELECT = `
10
+ mms_id,
11
+ created_at,
12
+ created_by:user_profiles!created_by (*),
13
+ updated_at,
14
+ last_updated_by:user_profiles!last_updated_by (*),
15
+ user:user_profiles!user_id (*),
16
+ leave_type:leave_types!leave_type_id (
17
+ mms_id,
18
+ name
19
+ ),
20
+ period_start,
21
+ period_end,
22
+ days_entitled,
23
+ notes
24
+ `;
25
+ class LeaveEntitlementsResource {
26
+ supabase;
27
+ auth;
28
+ table;
29
+ constructor(supabase, auth, audit) {
30
+ this.supabase = supabase;
31
+ this.auth = auth;
32
+ this.table = (0, audit_1.auditedTable)(supabase, auth, audit, {
33
+ table: 'leave_entitlements',
34
+ entityType: enum_1.AuditTrailEntityType.LEAVE_ENTITLEMENTS,
35
+ });
36
+ }
37
+ async list(query) {
38
+ const page = query.page;
39
+ const pageSize = query.page_size;
40
+ const offset = (page - 1) * pageSize;
41
+ let entitlementsQuery = this.supabase
42
+ .from('leave_entitlements')
43
+ .select(LEAVE_ENTITLEMENT_SELECT, { count: 'estimated' })
44
+ .eq('organization_id', this.auth.organization_id)
45
+ .order('period_start', { ascending: false })
46
+ .order('created_at', { ascending: false })
47
+ .range(offset, offset + pageSize - 1);
48
+ if (query.user_id) {
49
+ entitlementsQuery = entitlementsQuery.eq('user_id', query.user_id);
50
+ }
51
+ if (query.leave_type_id) {
52
+ entitlementsQuery = entitlementsQuery.eq('leave_type_id', query.leave_type_id);
53
+ }
54
+ if (query.as_of) {
55
+ entitlementsQuery = entitlementsQuery.lte('period_start', query.as_of).gte('period_end', query.as_of);
56
+ }
57
+ const { data, error, count } = await entitlementsQuery;
58
+ if (error)
59
+ throw (0, errors_1.mapPostgrestError)(error);
60
+ const rows = await this.withBalances((data ?? []));
61
+ return (0, transforms_1.toMmsList)(rows, page, pageSize, count);
62
+ }
63
+ async getById(leaveEntitlementId) {
64
+ const { data, error } = await this.supabase
65
+ .from('leave_entitlements')
66
+ .select(LEAVE_ENTITLEMENT_SELECT)
67
+ .eq('mms_id', leaveEntitlementId)
68
+ .eq('organization_id', this.auth.organization_id)
69
+ .single();
70
+ if (error)
71
+ throw (0, errors_1.mapPostgrestError)(error);
72
+ const [row] = await this.withBalances([data]);
73
+ return row;
74
+ }
75
+ /**
76
+ * The entitlement of `userId` for `leaveTypeId` whose period contains `date`, or null when the
77
+ * type is not tracked for them then. The periods of one user and type cannot overlap (the
78
+ * table's exclusion constraint), so there is at most one.
79
+ */
80
+ async findFor(userId, leaveTypeId, date) {
81
+ const { data, error } = await this.supabase
82
+ .from('leave_entitlements')
83
+ .select('mms_id, period_start, period_end, days_entitled')
84
+ .eq('organization_id', this.auth.organization_id)
85
+ .eq('user_id', userId)
86
+ .eq('leave_type_id', leaveTypeId)
87
+ .lte('period_start', date)
88
+ .gte('period_end', date)
89
+ .maybeSingle();
90
+ if (error)
91
+ throw (0, errors_1.mapPostgrestError)(error);
92
+ if (!data)
93
+ return null;
94
+ const cover = data;
95
+ return { ...cover, days_entitled: Number(cover.days_entitled) };
96
+ }
97
+ async create(input) {
98
+ const row = await this.table.insert({
99
+ user_id: input.user_id,
100
+ leave_type_id: input.leave_type_id,
101
+ period_start: input.period_start,
102
+ period_end: input.period_end,
103
+ days_entitled: input.days_entitled,
104
+ notes: input.notes ?? null,
105
+ organization_id: this.auth.organization_id,
106
+ created_by: this.auth.mms_id,
107
+ created_at: new Date().toISOString(),
108
+ });
109
+ return this.getById(row.mms_id);
110
+ }
111
+ async update(leaveEntitlementId, input) {
112
+ await this.table.update(leaveEntitlementId, {
113
+ days_entitled: input.days_entitled,
114
+ period_end: input.period_end,
115
+ notes: input.notes,
116
+ last_updated_by: this.auth.mms_id,
117
+ updated_at: new Date().toISOString(),
118
+ });
119
+ return this.getById(leaveEntitlementId);
120
+ }
121
+ /** Hard delete: the type simply becomes untracked for that user and period. */
122
+ async remove(leaveEntitlementId) {
123
+ await this.table.remove(leaveEntitlementId);
124
+ }
125
+ /**
126
+ * Adds the computed balance to each row from one query over the requests that could count
127
+ * against any of them - the approved and pending ones of these users and types, starting in
128
+ * the span the periods cover. Nothing is stored: a balance is always what the requests say.
129
+ */
130
+ async withBalances(rows) {
131
+ if (rows.length === 0)
132
+ return [];
133
+ const userIds = [...new Set(rows.map((row) => row.user.mms_id))];
134
+ const typeIds = [...new Set(rows.map((row) => row.leave_type.mms_id))];
135
+ const earliest = rows.map((row) => row.period_start).sort()[0];
136
+ const latest = rows.map((row) => row.period_end).sort().reverse()[0];
137
+ const { data, error } = await this.supabase
138
+ .from('leave_requests')
139
+ .select('user_id, leave_type_id, start_date, days, status')
140
+ .eq('organization_id', this.auth.organization_id)
141
+ .in('user_id', userIds)
142
+ .in('leave_type_id', typeIds)
143
+ .in('status', [enum_2.LeaveRequestStatus.APPROVED, enum_2.LeaveRequestStatus.PENDING])
144
+ .gte('start_date', earliest)
145
+ .lte('start_date', latest);
146
+ if (error)
147
+ throw (0, errors_1.mapPostgrestError)(error);
148
+ const requests = (data ?? []);
149
+ return rows.map((row) => {
150
+ const mine = requests.filter((request) => request.user_id === row.user.mms_id &&
151
+ request.leave_type_id === row.leave_type.mms_id &&
152
+ request.start_date >= row.period_start &&
153
+ request.start_date <= row.period_end);
154
+ const sum = (status) => mine
155
+ .filter((request) => request.status === status)
156
+ .reduce((total, request) => total + Number(request.days), 0);
157
+ const daysEntitled = Number(row.days_entitled);
158
+ const daysUsed = sum(enum_2.LeaveRequestStatus.APPROVED);
159
+ const daysPending = sum(enum_2.LeaveRequestStatus.PENDING);
160
+ return {
161
+ ...row,
162
+ days_entitled: daysEntitled,
163
+ days_used: daysUsed,
164
+ days_pending: daysPending,
165
+ days_remaining: daysEntitled - daysUsed - daysPending,
166
+ };
167
+ });
168
+ }
169
+ }
170
+ exports.LeaveEntitlementsResource = LeaveEntitlementsResource;