@kernhq/module-hr 0.18.1 → 0.19.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.
- package/dist/contract/capabilities.d.ts.map +1 -1
- package/dist/contract/capabilities.js +16 -0
- package/dist/contract/capabilities.js.map +1 -1
- package/dist/contract/exports.d.ts +459 -0
- package/dist/contract/exports.d.ts.map +1 -0
- package/dist/contract/exports.js +331 -0
- package/dist/contract/exports.js.map +1 -0
- package/dist/contract/index.d.ts +1 -0
- package/dist/contract/index.d.ts.map +1 -1
- package/dist/contract/index.js +1 -0
- package/dist/contract/index.js.map +1 -1
- package/dist/contract/permissions.d.ts +8 -0
- package/dist/contract/permissions.d.ts.map +1 -1
- package/dist/contract/permissions.js +32 -3
- package/dist/contract/permissions.js.map +1 -1
- package/dist/contract/router.d.ts +272 -0
- package/dist/contract/router.d.ts.map +1 -1
- package/dist/contract/router.js +67 -0
- package/dist/contract/router.js.map +1 -1
- package/dist/server/router.d.ts +283 -0
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/router.js +116 -0
- package/dist/server/router.js.map +1 -1
- package/dist/server/services/exports.d.ts +321 -0
- package/dist/server/services/exports.d.ts.map +1 -0
- package/dist/server/services/exports.js +765 -0
- package/dist/server/services/exports.js.map +1 -0
- package/package.json +1 -1
- package/src/client/messages.ts +13 -0
- package/src/contract/capabilities.ts +16 -0
- package/src/contract/exports.ts +354 -0
- package/src/contract/index.ts +1 -0
- package/src/contract/permissions.ts +34 -3
- package/src/contract/router.ts +73 -0
|
@@ -6332,6 +6332,278 @@ export declare const hrContract: {
|
|
|
6332
6332
|
};
|
|
6333
6333
|
}>, Record<never, never>>;
|
|
6334
6334
|
};
|
|
6335
|
+
/**
|
|
6336
|
+
* The monthly handover to whoever runs payroll, per legal entity, frozen at v1.
|
|
6337
|
+
*
|
|
6338
|
+
* `exports.ts` carries the reasoning; three things about the *shape of the surface* belong here:
|
|
6339
|
+
*
|
|
6340
|
+
* **`legalEntityId` is required, and `periodId` is the range.** `reportInput` makes its slice
|
|
6341
|
+
* optional with a `workspace` default and takes free `from`/`to` dates; neither is available here.
|
|
6342
|
+
* A workspace is not an employer, and a half-month export is a question about a boundary this
|
|
6343
|
+
* module already has an answer for — letting a caller draw their own reintroduces the mixed-finality
|
|
6344
|
+
* problem `ReportFinality` exists to name.
|
|
6345
|
+
*
|
|
6346
|
+
* **`v1` is a procedure, not a parameter.** A later column set ships as `payroll.export.v2` beside
|
|
6347
|
+
* this one, with this one unchanged, and both live through at least one deprecation window. A
|
|
6348
|
+
* `?version=` on one mutable procedure would make the frozen path a branch inside a function three
|
|
6349
|
+
* people will edit, and freezing by intention has never worked.
|
|
6350
|
+
*
|
|
6351
|
+
* **Both cost three keys.** `hr.payroll.export`, which ships granted to nobody, plus
|
|
6352
|
+
* `hr.attendance.view_team` for the hours file and `hr.leave.view_team` for the leave file — the
|
|
6353
|
+
* same second-check rule the reports follow, because an export must not answer what the row-level
|
|
6354
|
+
* procedure would refuse.
|
|
6355
|
+
*/
|
|
6356
|
+
payroll: {
|
|
6357
|
+
export: {
|
|
6358
|
+
/**
|
|
6359
|
+
* One entity, one period, two CSVs and a manifest.
|
|
6360
|
+
*
|
|
6361
|
+
* Refuses an open period unless `draft` is set, refuses an entity with nobody in it, and
|
|
6362
|
+
* refuses a person with no employment row covering their days here — because a row of zeros is
|
|
6363
|
+
* something a payroll clerk will pay from, and an error is not.
|
|
6364
|
+
*/
|
|
6365
|
+
v1: import("@orpc/contract").ContractProcedureBuilderWithInputOutput<z.ZodObject<{
|
|
6366
|
+
workspaceId: z.core.$ZodBranded<z.ZodUUID, "WorkspaceId", "out">;
|
|
6367
|
+
legalEntityId: z.ZodUUID;
|
|
6368
|
+
periodId: z.ZodUUID;
|
|
6369
|
+
draft: z.ZodDefault<z.ZodBoolean>;
|
|
6370
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
6371
|
+
manifest: z.ZodObject<{
|
|
6372
|
+
contract: z.ZodLiteral<"kern-payroll-v1">;
|
|
6373
|
+
generatedAt: z.ZodISODateTime;
|
|
6374
|
+
kernVersion: z.ZodString;
|
|
6375
|
+
finality: z.ZodEnum<{
|
|
6376
|
+
draft: "draft";
|
|
6377
|
+
final: "final";
|
|
6378
|
+
}>;
|
|
6379
|
+
draft: z.ZodBoolean;
|
|
6380
|
+
legalEntityId: z.ZodUUID;
|
|
6381
|
+
legalEntityName: z.ZodString;
|
|
6382
|
+
country: z.ZodString;
|
|
6383
|
+
currency: z.ZodNullable<z.ZodString>;
|
|
6384
|
+
periodId: z.ZodUUID;
|
|
6385
|
+
periodStart: z.ZodISODate;
|
|
6386
|
+
periodEnd: z.ZodISODate;
|
|
6387
|
+
periodStatus: z.ZodEnum<{
|
|
6388
|
+
locked: "locked";
|
|
6389
|
+
open: "open";
|
|
6390
|
+
}>;
|
|
6391
|
+
population: z.ZodNumber;
|
|
6392
|
+
counted: z.ZodNumber;
|
|
6393
|
+
scope: z.ZodObject<{
|
|
6394
|
+
permissions: z.ZodArray<z.ZodString>;
|
|
6395
|
+
askedAt: z.ZodLiteral<"workspace">;
|
|
6396
|
+
}, z.core.$strip>;
|
|
6397
|
+
attendance: z.ZodObject<{
|
|
6398
|
+
lockedDays: z.ZodNumber;
|
|
6399
|
+
openDays: z.ZodNumber;
|
|
6400
|
+
final: z.ZodBoolean;
|
|
6401
|
+
firstOpenDay: z.ZodNullable<z.ZodISODate>;
|
|
6402
|
+
lastLockedDay: z.ZodNullable<z.ZodISODate>;
|
|
6403
|
+
}, z.core.$strip>;
|
|
6404
|
+
dayLengthMinutes: z.ZodNumber;
|
|
6405
|
+
format: z.ZodObject<{
|
|
6406
|
+
encoding: z.ZodLiteral<"utf-8">;
|
|
6407
|
+
byteOrderMark: z.ZodLiteral<true>;
|
|
6408
|
+
delimiter: z.ZodLiteral<",">;
|
|
6409
|
+
lineEnding: z.ZodLiteral<"crlf">;
|
|
6410
|
+
quoting: z.ZodLiteral<"rfc4180">;
|
|
6411
|
+
decimalSeparator: z.ZodLiteral<".">;
|
|
6412
|
+
decimalPlaces: z.ZodLiteral<2>;
|
|
6413
|
+
dateFormat: z.ZodLiteral<"iso-8601">;
|
|
6414
|
+
}, z.core.$strip>;
|
|
6415
|
+
files: z.ZodArray<z.ZodObject<{
|
|
6416
|
+
name: z.ZodString;
|
|
6417
|
+
columns: z.ZodArray<z.ZodString>;
|
|
6418
|
+
rows: z.ZodNumber;
|
|
6419
|
+
}, z.core.$strip>>;
|
|
6420
|
+
}, z.core.$strip>;
|
|
6421
|
+
files: z.ZodArray<z.ZodObject<{
|
|
6422
|
+
name: z.ZodString;
|
|
6423
|
+
contentType: z.ZodString;
|
|
6424
|
+
content: z.ZodString;
|
|
6425
|
+
}, z.core.$strip>>;
|
|
6426
|
+
}, z.core.$strip>, import("@orpc/contract").MergedErrorMap<Record<never, never>, {
|
|
6427
|
+
BAD_REQUEST: {
|
|
6428
|
+
data: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
6429
|
+
};
|
|
6430
|
+
UNAUTHORIZED: {};
|
|
6431
|
+
FORBIDDEN: {
|
|
6432
|
+
data: z.ZodOptional<z.ZodObject<{
|
|
6433
|
+
permission: z.ZodOptional<z.ZodString>;
|
|
6434
|
+
}, z.core.$strip>>;
|
|
6435
|
+
};
|
|
6436
|
+
NOT_FOUND: {};
|
|
6437
|
+
CONFLICT: {
|
|
6438
|
+
data: z.ZodOptional<z.ZodObject<{
|
|
6439
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
6440
|
+
}, z.core.$strip>>;
|
|
6441
|
+
};
|
|
6442
|
+
RATE_LIMITED: {};
|
|
6443
|
+
MODULE_DISABLED: {
|
|
6444
|
+
data: z.ZodObject<{
|
|
6445
|
+
module: z.ZodString;
|
|
6446
|
+
}, z.core.$strip>;
|
|
6447
|
+
};
|
|
6448
|
+
}>, Record<never, never>>;
|
|
6449
|
+
/**
|
|
6450
|
+
* The same rows as JSON, with no file written and no refusal thrown.
|
|
6451
|
+
*
|
|
6452
|
+
* So the screen shows the totals and the reasons the export would be refused before anybody
|
|
6453
|
+
* downloads anything. Deliberately not versioned: a preview is this module talking to its own
|
|
6454
|
+
* screen, and nothing outside Kern parses it.
|
|
6455
|
+
*/
|
|
6456
|
+
preview: import("@orpc/contract").ContractProcedureBuilderWithInputOutput<z.ZodObject<{
|
|
6457
|
+
workspaceId: z.core.$ZodBranded<z.ZodUUID, "WorkspaceId", "out">;
|
|
6458
|
+
legalEntityId: z.ZodUUID;
|
|
6459
|
+
periodId: z.ZodUUID;
|
|
6460
|
+
draft: z.ZodDefault<z.ZodBoolean>;
|
|
6461
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
6462
|
+
manifest: z.ZodObject<{
|
|
6463
|
+
contract: z.ZodLiteral<"kern-payroll-v1">;
|
|
6464
|
+
generatedAt: z.ZodISODateTime;
|
|
6465
|
+
kernVersion: z.ZodString;
|
|
6466
|
+
finality: z.ZodEnum<{
|
|
6467
|
+
draft: "draft";
|
|
6468
|
+
final: "final";
|
|
6469
|
+
}>;
|
|
6470
|
+
draft: z.ZodBoolean;
|
|
6471
|
+
legalEntityId: z.ZodUUID;
|
|
6472
|
+
legalEntityName: z.ZodString;
|
|
6473
|
+
country: z.ZodString;
|
|
6474
|
+
currency: z.ZodNullable<z.ZodString>;
|
|
6475
|
+
periodId: z.ZodUUID;
|
|
6476
|
+
periodStart: z.ZodISODate;
|
|
6477
|
+
periodEnd: z.ZodISODate;
|
|
6478
|
+
periodStatus: z.ZodEnum<{
|
|
6479
|
+
locked: "locked";
|
|
6480
|
+
open: "open";
|
|
6481
|
+
}>;
|
|
6482
|
+
population: z.ZodNumber;
|
|
6483
|
+
counted: z.ZodNumber;
|
|
6484
|
+
scope: z.ZodObject<{
|
|
6485
|
+
permissions: z.ZodArray<z.ZodString>;
|
|
6486
|
+
askedAt: z.ZodLiteral<"workspace">;
|
|
6487
|
+
}, z.core.$strip>;
|
|
6488
|
+
attendance: z.ZodObject<{
|
|
6489
|
+
lockedDays: z.ZodNumber;
|
|
6490
|
+
openDays: z.ZodNumber;
|
|
6491
|
+
final: z.ZodBoolean;
|
|
6492
|
+
firstOpenDay: z.ZodNullable<z.ZodISODate>;
|
|
6493
|
+
lastLockedDay: z.ZodNullable<z.ZodISODate>;
|
|
6494
|
+
}, z.core.$strip>;
|
|
6495
|
+
dayLengthMinutes: z.ZodNumber;
|
|
6496
|
+
format: z.ZodObject<{
|
|
6497
|
+
encoding: z.ZodLiteral<"utf-8">;
|
|
6498
|
+
byteOrderMark: z.ZodLiteral<true>;
|
|
6499
|
+
delimiter: z.ZodLiteral<",">;
|
|
6500
|
+
lineEnding: z.ZodLiteral<"crlf">;
|
|
6501
|
+
quoting: z.ZodLiteral<"rfc4180">;
|
|
6502
|
+
decimalSeparator: z.ZodLiteral<".">;
|
|
6503
|
+
decimalPlaces: z.ZodLiteral<2>;
|
|
6504
|
+
dateFormat: z.ZodLiteral<"iso-8601">;
|
|
6505
|
+
}, z.core.$strip>;
|
|
6506
|
+
files: z.ZodArray<z.ZodObject<{
|
|
6507
|
+
name: z.ZodString;
|
|
6508
|
+
columns: z.ZodArray<z.ZodString>;
|
|
6509
|
+
rows: z.ZodNumber;
|
|
6510
|
+
}, z.core.$strip>>;
|
|
6511
|
+
}, z.core.$strip>;
|
|
6512
|
+
refusals: z.ZodArray<z.ZodObject<{
|
|
6513
|
+
code: z.ZodEnum<{
|
|
6514
|
+
"hr.period.not_locked": "hr.period.not_locked";
|
|
6515
|
+
"hr.payroll.empty": "hr.payroll.empty";
|
|
6516
|
+
"hr.payroll.no_employment": "hr.payroll.no_employment";
|
|
6517
|
+
}>;
|
|
6518
|
+
message: z.ZodString;
|
|
6519
|
+
personIds: z.ZodArray<z.ZodUUID>;
|
|
6520
|
+
}, z.core.$strip>>;
|
|
6521
|
+
exportable: z.ZodBoolean;
|
|
6522
|
+
totals: z.ZodObject<{
|
|
6523
|
+
people: z.ZodNumber;
|
|
6524
|
+
daySheets: z.ZodNumber;
|
|
6525
|
+
scheduledMinutes: z.ZodNumber;
|
|
6526
|
+
workedMinutes: z.ZodNumber;
|
|
6527
|
+
scheduledWorkedMinutes: z.ZodNumber;
|
|
6528
|
+
breakMinutes: z.ZodNumber;
|
|
6529
|
+
overtimeMinutes: z.ZodNumber;
|
|
6530
|
+
lateMinutes: z.ZodNumber;
|
|
6531
|
+
earlyLeaveMinutes: z.ZodNumber;
|
|
6532
|
+
beyondCapMinutes: z.ZodNullable<z.ZodNumber>;
|
|
6533
|
+
cappedDays: z.ZodNumber;
|
|
6534
|
+
uncappedDays: z.ZodNumber;
|
|
6535
|
+
lockedDays: z.ZodNumber;
|
|
6536
|
+
openDays: z.ZodNumber;
|
|
6537
|
+
paidLeaveDays: z.ZodNumber;
|
|
6538
|
+
unpaidLeaveDays: z.ZodNumber;
|
|
6539
|
+
}, z.core.$strip>;
|
|
6540
|
+
hours: z.ZodArray<z.ZodObject<{
|
|
6541
|
+
personId: z.ZodUUID;
|
|
6542
|
+
employeeNo: z.ZodNullable<z.ZodString>;
|
|
6543
|
+
displayName: z.ZodString;
|
|
6544
|
+
employmentType: z.ZodString;
|
|
6545
|
+
fte: z.ZodNumber;
|
|
6546
|
+
contractHoursWeek: z.ZodNullable<z.ZodNumber>;
|
|
6547
|
+
costCenterCode: z.ZodNullable<z.ZodString>;
|
|
6548
|
+
positionTitle: z.ZodNullable<z.ZodString>;
|
|
6549
|
+
hiredOn: z.ZodNullable<z.ZodISODate>;
|
|
6550
|
+
terminatedOn: z.ZodNullable<z.ZodISODate>;
|
|
6551
|
+
employmentChangedInPeriod: z.ZodBoolean;
|
|
6552
|
+
daySheets: z.ZodNumber;
|
|
6553
|
+
scheduledMinutes: z.ZodNumber;
|
|
6554
|
+
workedMinutes: z.ZodNumber;
|
|
6555
|
+
scheduledWorkedMinutes: z.ZodNumber;
|
|
6556
|
+
breakMinutes: z.ZodNumber;
|
|
6557
|
+
overtimeMinutes: z.ZodNumber;
|
|
6558
|
+
lateMinutes: z.ZodNumber;
|
|
6559
|
+
earlyLeaveMinutes: z.ZodNumber;
|
|
6560
|
+
beyondCapMinutes: z.ZodNullable<z.ZodNumber>;
|
|
6561
|
+
cappedDays: z.ZodNumber;
|
|
6562
|
+
uncappedDays: z.ZodNumber;
|
|
6563
|
+
lockedDays: z.ZodNumber;
|
|
6564
|
+
openDays: z.ZodNumber;
|
|
6565
|
+
paidLeaveDays: z.ZodNumber;
|
|
6566
|
+
unpaidLeaveDays: z.ZodNumber;
|
|
6567
|
+
}, z.core.$strip>>;
|
|
6568
|
+
leave: z.ZodArray<z.ZodObject<{
|
|
6569
|
+
personId: z.ZodUUID;
|
|
6570
|
+
employeeNo: z.ZodNullable<z.ZodString>;
|
|
6571
|
+
leaveTypeKey: z.ZodString;
|
|
6572
|
+
leaveTypeName: z.ZodString;
|
|
6573
|
+
paid: z.ZodBoolean;
|
|
6574
|
+
unit: z.ZodEnum<{
|
|
6575
|
+
half_day: "half_day";
|
|
6576
|
+
day: "day";
|
|
6577
|
+
hour: "hour";
|
|
6578
|
+
}>;
|
|
6579
|
+
days: z.ZodNumber;
|
|
6580
|
+
requests: z.ZodNumber;
|
|
6581
|
+
}, z.core.$strip>>;
|
|
6582
|
+
}, z.core.$strip>, import("@orpc/contract").MergedErrorMap<Record<never, never>, {
|
|
6583
|
+
BAD_REQUEST: {
|
|
6584
|
+
data: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
6585
|
+
};
|
|
6586
|
+
UNAUTHORIZED: {};
|
|
6587
|
+
FORBIDDEN: {
|
|
6588
|
+
data: z.ZodOptional<z.ZodObject<{
|
|
6589
|
+
permission: z.ZodOptional<z.ZodString>;
|
|
6590
|
+
}, z.core.$strip>>;
|
|
6591
|
+
};
|
|
6592
|
+
NOT_FOUND: {};
|
|
6593
|
+
CONFLICT: {
|
|
6594
|
+
data: z.ZodOptional<z.ZodObject<{
|
|
6595
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
6596
|
+
}, z.core.$strip>>;
|
|
6597
|
+
};
|
|
6598
|
+
RATE_LIMITED: {};
|
|
6599
|
+
MODULE_DISABLED: {
|
|
6600
|
+
data: z.ZodObject<{
|
|
6601
|
+
module: z.ZodString;
|
|
6602
|
+
}, z.core.$strip>;
|
|
6603
|
+
};
|
|
6604
|
+
}>, Record<never, never>>;
|
|
6605
|
+
};
|
|
6606
|
+
};
|
|
6335
6607
|
privacy: {
|
|
6336
6608
|
/**
|
|
6337
6609
|
* Everything HR holds about one person, in one response.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/contract/router.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/contract/router.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAmGvB,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA4BnB;;;;;;WAMG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAqCH,0FAA0F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAyD1F;;;;;WAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAkDD,6EAA6E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAkG/E,0FAA0F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAyB1F;;;;;;WAMG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA6GD;;;eAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAiCH;;;;;;eAMG;;;;;;;;;;;;;;;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"}
|
package/dist/contract/router.js
CHANGED
|
@@ -2,6 +2,7 @@ import { baseContract, PageInput, page, WorkspaceId } from '@kernhq/contracts';
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { ApprovalChain, ApprovalChainSpec, ApprovalRequest, ApprovalSubjectType, Delegation, } from './approvals.js';
|
|
4
4
|
import { AttendanceDay, ClientPunchMethod, ClockState, Punch, PunchDirection, Regularization, Schedule, ScheduleAssignment, ScheduleWeek, } from './attendance.js';
|
|
5
|
+
import { PayrollExport, PayrollExportPreview } from './exports.js';
|
|
5
6
|
import { DayPart, LeaveBalance, LeaveLedgerEntry, LeaveRequest, LeaveSimulation, LeaveType, LeaveUnit, LedgerKind, } from './leave.js';
|
|
6
7
|
import { Calendar, CalendarDayKind, CostCenter, CountryCode, CustomFieldDef, Employment, EmploymentType, IsoDate, LegalEntity, Office, OfficeAssignment, OfficeKind, OrgUnit, Person, PersonDocument, PersonResolution, PersonSensitive, PersonStatus, Position, RegionCode, ResolvedCalendarDay, TimeZone, WorkingWeek, } from './models.js';
|
|
7
8
|
import { AccrualPreview, Period, Policy, PolicyAssignment, PolicyKind, PolicySubjectKind, ResolvedPolicy, } from './policies.js';
|
|
@@ -1162,6 +1163,72 @@ export const hrContract = {
|
|
|
1162
1163
|
}))
|
|
1163
1164
|
.output(LeaveBalanceReport),
|
|
1164
1165
|
},
|
|
1166
|
+
// ---------------------------------------------------------------- payroll export
|
|
1167
|
+
/**
|
|
1168
|
+
* The monthly handover to whoever runs payroll, per legal entity, frozen at v1.
|
|
1169
|
+
*
|
|
1170
|
+
* `exports.ts` carries the reasoning; three things about the *shape of the surface* belong here:
|
|
1171
|
+
*
|
|
1172
|
+
* **`legalEntityId` is required, and `periodId` is the range.** `reportInput` makes its slice
|
|
1173
|
+
* optional with a `workspace` default and takes free `from`/`to` dates; neither is available here.
|
|
1174
|
+
* A workspace is not an employer, and a half-month export is a question about a boundary this
|
|
1175
|
+
* module already has an answer for — letting a caller draw their own reintroduces the mixed-finality
|
|
1176
|
+
* problem `ReportFinality` exists to name.
|
|
1177
|
+
*
|
|
1178
|
+
* **`v1` is a procedure, not a parameter.** A later column set ships as `payroll.export.v2` beside
|
|
1179
|
+
* this one, with this one unchanged, and both live through at least one deprecation window. A
|
|
1180
|
+
* `?version=` on one mutable procedure would make the frozen path a branch inside a function three
|
|
1181
|
+
* people will edit, and freezing by intention has never worked.
|
|
1182
|
+
*
|
|
1183
|
+
* **Both cost three keys.** `hr.payroll.export`, which ships granted to nobody, plus
|
|
1184
|
+
* `hr.attendance.view_team` for the hours file and `hr.leave.view_team` for the leave file — the
|
|
1185
|
+
* same second-check rule the reports follow, because an export must not answer what the row-level
|
|
1186
|
+
* procedure would refuse.
|
|
1187
|
+
*/
|
|
1188
|
+
payroll: {
|
|
1189
|
+
export: {
|
|
1190
|
+
/**
|
|
1191
|
+
* One entity, one period, two CSVs and a manifest.
|
|
1192
|
+
*
|
|
1193
|
+
* Refuses an open period unless `draft` is set, refuses an entity with nobody in it, and
|
|
1194
|
+
* refuses a person with no employment row covering their days here — because a row of zeros is
|
|
1195
|
+
* something a payroll clerk will pay from, and an error is not.
|
|
1196
|
+
*/
|
|
1197
|
+
v1: baseContract
|
|
1198
|
+
.route({ method: 'GET', path: '/payroll/export/v1', tags: t })
|
|
1199
|
+
.input(ws.extend({
|
|
1200
|
+
/** Required. There is no workspace-wide export: a workspace is not an employer. */
|
|
1201
|
+
legalEntityId: z.uuid(),
|
|
1202
|
+
/** The range is the period's, never the caller's. */
|
|
1203
|
+
periodId: z.uuid(),
|
|
1204
|
+
/**
|
|
1205
|
+
* Export an open period anyway, and stamp the file as a draft.
|
|
1206
|
+
*
|
|
1207
|
+
* Not a permission — a statement the caller made, which the file then repeats in its
|
|
1208
|
+
* manifest, its filename and its `open_days`. Defaults to false: `reconcile-days` rebuilds
|
|
1209
|
+
* every day a period does not close, so the same export at 18:00 and at 09:00 the next
|
|
1210
|
+
* morning can differ with nobody having touched anything.
|
|
1211
|
+
*/
|
|
1212
|
+
draft: z.boolean().default(false),
|
|
1213
|
+
}))
|
|
1214
|
+
.output(PayrollExport),
|
|
1215
|
+
/**
|
|
1216
|
+
* The same rows as JSON, with no file written and no refusal thrown.
|
|
1217
|
+
*
|
|
1218
|
+
* So the screen shows the totals and the reasons the export would be refused before anybody
|
|
1219
|
+
* downloads anything. Deliberately not versioned: a preview is this module talking to its own
|
|
1220
|
+
* screen, and nothing outside Kern parses it.
|
|
1221
|
+
*/
|
|
1222
|
+
preview: baseContract
|
|
1223
|
+
.route({ method: 'GET', path: '/payroll/export/preview', tags: t })
|
|
1224
|
+
.input(ws.extend({
|
|
1225
|
+
legalEntityId: z.uuid(),
|
|
1226
|
+
periodId: z.uuid(),
|
|
1227
|
+
draft: z.boolean().default(false),
|
|
1228
|
+
}))
|
|
1229
|
+
.output(PayrollExportPreview),
|
|
1230
|
+
},
|
|
1231
|
+
},
|
|
1165
1232
|
// ---------------------------------------------------------------- privacy
|
|
1166
1233
|
privacy: {
|
|
1167
1234
|
/**
|