@kernhq/module-hr 0.17.0 → 0.18.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.
@@ -5910,6 +5910,426 @@ export declare const hrContract: {
5910
5910
  * nobody by default and ships in the same change as these — see `privacy.ts` for why there is one
5911
5911
  * key rather than four, and why none of this is a capability.
5912
5912
  */
5913
+ /**
5914
+ * Four aggregates, and one rule that decides all four: **a report may not answer a question its
5915
+ * row-level procedure would refuse, and may not narrow below what that procedure already
5916
+ * returns.**
5917
+ *
5918
+ * So each of these costs `hr.report.view` *and* the key that already guards the rows it sums —
5919
+ * `hr.attendance.view_team`, which is what reading a whole office's day sheets costs on
5920
+ * `attendance.days.list`, or `hr.leave.view_team`, which is what reading somebody else's balance
5921
+ * costs on `leave.balance.get`. A reader holding neither gets nothing: not a one-row self-report,
5922
+ * because a reports menu that quietly collapses to your own attendance is a menu entry that lies
5923
+ * about what it is, and your own attendance is already the attendance page.
5924
+ *
5925
+ * The population is **not** intersected with `HrAccessService.visiblePersonIds`. That service
5926
+ * narrows *fields* rather than rows — it withholds `personalEmail`, `phone`, `hiredOn` and
5927
+ * `terminatedOn`, none of which any report reads — and intersecting on it would produce the worst
5928
+ * outcome available here: two managers reading different totals under the same title, with
5929
+ * nothing on the page to say so.
5930
+ */
5931
+ reports: {
5932
+ /**
5933
+ * Scheduled against worked, per person, over a range.
5934
+ *
5935
+ * Built from `attendance_days` and never from `punches`: punches are raw and append-only, a
5936
+ * voided punch survives beside its correction, and summing them double-counts every fix. The
5937
+ * day sheet is the projection those punches produce.
5938
+ */
5939
+ attendance: import("@orpc/contract").ContractProcedureBuilderWithInputOutput<z.ZodObject<{
5940
+ workspaceId: z.core.$ZodBranded<z.ZodUUID, "WorkspaceId", "out">;
5941
+ from: z.ZodISODate;
5942
+ to: z.ZodISODate;
5943
+ by: z.ZodDefault<z.ZodEnum<{
5944
+ office: "office";
5945
+ legal_entity: "legal_entity";
5946
+ workspace: "workspace";
5947
+ }>>;
5948
+ sliceId: z.ZodOptional<z.ZodUUID>;
5949
+ limit: z.ZodDefault<z.ZodNumber>;
5950
+ }, z.core.$strip>, z.ZodObject<{
5951
+ header: z.ZodObject<{
5952
+ from: z.ZodISODate;
5953
+ to: z.ZodISODate;
5954
+ slice: z.ZodObject<{
5955
+ by: z.ZodEnum<{
5956
+ office: "office";
5957
+ legal_entity: "legal_entity";
5958
+ workspace: "workspace";
5959
+ }>;
5960
+ id: z.ZodNullable<z.ZodUUID>;
5961
+ name: z.ZodNullable<z.ZodString>;
5962
+ }, z.core.$strip>;
5963
+ scope: z.ZodObject<{
5964
+ permissions: z.ZodArray<z.ZodString>;
5965
+ askedAt: z.ZodLiteral<"workspace">;
5966
+ }, z.core.$strip>;
5967
+ population: z.ZodNumber;
5968
+ counted: z.ZodNumber;
5969
+ attribution: z.ZodEnum<{
5970
+ each_day: "each_day";
5971
+ as_of_date: "as_of_date";
5972
+ not_applicable: "not_applicable";
5973
+ }>;
5974
+ attributionOn: z.ZodNullable<z.ZodISODate>;
5975
+ truncated: z.ZodBoolean;
5976
+ }, z.core.$strip>;
5977
+ finality: z.ZodObject<{
5978
+ lockedDays: z.ZodNumber;
5979
+ openDays: z.ZodNumber;
5980
+ final: z.ZodBoolean;
5981
+ firstOpenDay: z.ZodNullable<z.ZodISODate>;
5982
+ lastLockedDay: z.ZodNullable<z.ZodISODate>;
5983
+ }, z.core.$strip>;
5984
+ totals: z.ZodObject<{
5985
+ scheduledMinutes: z.ZodNumber;
5986
+ workedMinutes: z.ZodNumber;
5987
+ breakMinutes: z.ZodNumber;
5988
+ lateMinutes: z.ZodNumber;
5989
+ earlyLeaveMinutes: z.ZodNumber;
5990
+ days: z.ZodNumber;
5991
+ workedRatio: z.ZodNullable<z.ZodNumber>;
5992
+ noScheduleDays: z.ZodNumber;
5993
+ unknownScheduleDays: z.ZodNumber;
5994
+ }, z.core.$strip>;
5995
+ rows: z.ZodArray<z.ZodObject<{
5996
+ personId: z.ZodUUID;
5997
+ displayName: z.ZodString;
5998
+ days: z.ZodNumber;
5999
+ scheduledMinutes: z.ZodNumber;
6000
+ workedMinutes: z.ZodNumber;
6001
+ breakMinutes: z.ZodNumber;
6002
+ lateMinutes: z.ZodNumber;
6003
+ earlyLeaveMinutes: z.ZodNumber;
6004
+ workedRatio: z.ZodNullable<z.ZodNumber>;
6005
+ noScheduleDays: z.ZodNumber;
6006
+ unknownScheduleDays: z.ZodNumber;
6007
+ }, z.core.$strip>>;
6008
+ }, z.core.$strip>, import("@orpc/contract").MergedErrorMap<Record<never, never>, {
6009
+ BAD_REQUEST: {
6010
+ data: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
6011
+ };
6012
+ UNAUTHORIZED: {};
6013
+ FORBIDDEN: {
6014
+ data: z.ZodOptional<z.ZodObject<{
6015
+ permission: z.ZodOptional<z.ZodString>;
6016
+ }, z.core.$strip>>;
6017
+ };
6018
+ NOT_FOUND: {};
6019
+ CONFLICT: {
6020
+ data: z.ZodOptional<z.ZodObject<{
6021
+ reason: z.ZodOptional<z.ZodString>;
6022
+ }, z.core.$strip>>;
6023
+ };
6024
+ RATE_LIMITED: {};
6025
+ MODULE_DISABLED: {
6026
+ data: z.ZodObject<{
6027
+ module: z.ZodString;
6028
+ }, z.core.$strip>;
6029
+ };
6030
+ }>, Record<never, never>>;
6031
+ /**
6032
+ * Overtime, and how much of it an annual ceiling would not take.
6033
+ *
6034
+ * `beyondCapMinutes` is null where no ceiling was in force — summed as a nullable column rather
6035
+ * than coalesced, so "no ceiling applied to these days" and "a ceiling applied and nothing
6036
+ * passed it" stay different answers. No projection: there is no "at this rate you will pass the
6037
+ * ceiling in November", because that needs a policy that may not exist.
6038
+ */
6039
+ overtime: import("@orpc/contract").ContractProcedureBuilderWithInputOutput<z.ZodObject<{
6040
+ workspaceId: z.core.$ZodBranded<z.ZodUUID, "WorkspaceId", "out">;
6041
+ from: z.ZodISODate;
6042
+ to: z.ZodISODate;
6043
+ by: z.ZodDefault<z.ZodEnum<{
6044
+ office: "office";
6045
+ legal_entity: "legal_entity";
6046
+ workspace: "workspace";
6047
+ }>>;
6048
+ sliceId: z.ZodOptional<z.ZodUUID>;
6049
+ limit: z.ZodDefault<z.ZodNumber>;
6050
+ }, z.core.$strip>, z.ZodObject<{
6051
+ header: z.ZodObject<{
6052
+ from: z.ZodISODate;
6053
+ to: z.ZodISODate;
6054
+ slice: z.ZodObject<{
6055
+ by: z.ZodEnum<{
6056
+ office: "office";
6057
+ legal_entity: "legal_entity";
6058
+ workspace: "workspace";
6059
+ }>;
6060
+ id: z.ZodNullable<z.ZodUUID>;
6061
+ name: z.ZodNullable<z.ZodString>;
6062
+ }, z.core.$strip>;
6063
+ scope: z.ZodObject<{
6064
+ permissions: z.ZodArray<z.ZodString>;
6065
+ askedAt: z.ZodLiteral<"workspace">;
6066
+ }, z.core.$strip>;
6067
+ population: z.ZodNumber;
6068
+ counted: z.ZodNumber;
6069
+ attribution: z.ZodEnum<{
6070
+ each_day: "each_day";
6071
+ as_of_date: "as_of_date";
6072
+ not_applicable: "not_applicable";
6073
+ }>;
6074
+ attributionOn: z.ZodNullable<z.ZodISODate>;
6075
+ truncated: z.ZodBoolean;
6076
+ }, z.core.$strip>;
6077
+ finality: z.ZodObject<{
6078
+ lockedDays: z.ZodNumber;
6079
+ openDays: z.ZodNumber;
6080
+ final: z.ZodBoolean;
6081
+ firstOpenDay: z.ZodNullable<z.ZodISODate>;
6082
+ lastLockedDay: z.ZodNullable<z.ZodISODate>;
6083
+ }, z.core.$strip>;
6084
+ totals: z.ZodObject<{
6085
+ overtimeMinutes: z.ZodNumber;
6086
+ beyondCapMinutes: z.ZodNullable<z.ZodNumber>;
6087
+ days: z.ZodNumber;
6088
+ cappedDays: z.ZodNumber;
6089
+ uncappedDays: z.ZodNumber;
6090
+ }, z.core.$strip>;
6091
+ rows: z.ZodArray<z.ZodObject<{
6092
+ personId: z.ZodUUID;
6093
+ displayName: z.ZodString;
6094
+ days: z.ZodNumber;
6095
+ overtimeMinutes: z.ZodNumber;
6096
+ beyondCapMinutes: z.ZodNullable<z.ZodNumber>;
6097
+ cappedDays: z.ZodNumber;
6098
+ uncappedDays: z.ZodNumber;
6099
+ }, z.core.$strip>>;
6100
+ }, z.core.$strip>, import("@orpc/contract").MergedErrorMap<Record<never, never>, {
6101
+ BAD_REQUEST: {
6102
+ data: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
6103
+ };
6104
+ UNAUTHORIZED: {};
6105
+ FORBIDDEN: {
6106
+ data: z.ZodOptional<z.ZodObject<{
6107
+ permission: z.ZodOptional<z.ZodString>;
6108
+ }, z.core.$strip>>;
6109
+ };
6110
+ NOT_FOUND: {};
6111
+ CONFLICT: {
6112
+ data: z.ZodOptional<z.ZodObject<{
6113
+ reason: z.ZodOptional<z.ZodString>;
6114
+ }, z.core.$strip>>;
6115
+ };
6116
+ RATE_LIMITED: {};
6117
+ MODULE_DISABLED: {
6118
+ data: z.ZodObject<{
6119
+ module: z.ZodString;
6120
+ }, z.core.$strip>;
6121
+ };
6122
+ }>, Record<never, never>>;
6123
+ /**
6124
+ * Expected working days, minus days worked, minus approved leave.
6125
+ *
6126
+ * **Never `status = 'absent'`.** `attendance_days` has a row only where somebody punched — no
6127
+ * writer creates one for a day nobody clocked in on — so counting absent rows reports near-zero
6128
+ * absence everywhere and looks entirely healthy while doing it. The denominator comes from the
6129
+ * calendar instead, and a person the module cannot build one for lands in a named row rather
6130
+ * than being counted as present.
6131
+ *
6132
+ * Held to `MAX_SLICED_REPORT_DAYS` whether it is sliced or not: every person's expectation is
6133
+ * their office's calendar on each day, which is a ladder walk per day.
6134
+ */
6135
+ absence: import("@orpc/contract").ContractProcedureBuilderWithInputOutput<z.ZodObject<{
6136
+ workspaceId: z.core.$ZodBranded<z.ZodUUID, "WorkspaceId", "out">;
6137
+ from: z.ZodISODate;
6138
+ to: z.ZodISODate;
6139
+ by: z.ZodDefault<z.ZodEnum<{
6140
+ office: "office";
6141
+ legal_entity: "legal_entity";
6142
+ workspace: "workspace";
6143
+ }>>;
6144
+ sliceId: z.ZodOptional<z.ZodUUID>;
6145
+ limit: z.ZodDefault<z.ZodNumber>;
6146
+ }, z.core.$strip>, z.ZodObject<{
6147
+ header: z.ZodObject<{
6148
+ from: z.ZodISODate;
6149
+ to: z.ZodISODate;
6150
+ slice: z.ZodObject<{
6151
+ by: z.ZodEnum<{
6152
+ office: "office";
6153
+ legal_entity: "legal_entity";
6154
+ workspace: "workspace";
6155
+ }>;
6156
+ id: z.ZodNullable<z.ZodUUID>;
6157
+ name: z.ZodNullable<z.ZodString>;
6158
+ }, z.core.$strip>;
6159
+ scope: z.ZodObject<{
6160
+ permissions: z.ZodArray<z.ZodString>;
6161
+ askedAt: z.ZodLiteral<"workspace">;
6162
+ }, z.core.$strip>;
6163
+ population: z.ZodNumber;
6164
+ counted: z.ZodNumber;
6165
+ attribution: z.ZodEnum<{
6166
+ each_day: "each_day";
6167
+ as_of_date: "as_of_date";
6168
+ not_applicable: "not_applicable";
6169
+ }>;
6170
+ attributionOn: z.ZodNullable<z.ZodISODate>;
6171
+ truncated: z.ZodBoolean;
6172
+ }, z.core.$strip>;
6173
+ finality: z.ZodObject<{
6174
+ lockedDays: z.ZodNumber;
6175
+ openDays: z.ZodNumber;
6176
+ final: z.ZodBoolean;
6177
+ firstOpenDay: z.ZodNullable<z.ZodISODate>;
6178
+ lastLockedDay: z.ZodNullable<z.ZodISODate>;
6179
+ }, z.core.$strip>;
6180
+ leaveCounted: z.ZodBoolean;
6181
+ totals: z.ZodObject<{
6182
+ measured: z.ZodNumber;
6183
+ expectedDays: z.ZodNumber;
6184
+ workedDays: z.ZodNumber;
6185
+ leaveDays: z.ZodNullable<z.ZodNumber>;
6186
+ absentDays: z.ZodNumber;
6187
+ absenceRate: z.ZodNullable<z.ZodNumber>;
6188
+ }, z.core.$strip>;
6189
+ excluded: z.ZodObject<{
6190
+ noSchedule: z.ZodNumber;
6191
+ noCalendar: z.ZodNumber;
6192
+ }, z.core.$strip>;
6193
+ rows: z.ZodArray<z.ZodObject<{
6194
+ personId: z.ZodUUID;
6195
+ displayName: z.ZodString;
6196
+ basis: z.ZodEnum<{
6197
+ calendar: "calendar";
6198
+ no_calendar: "no_calendar";
6199
+ no_schedule: "no_schedule";
6200
+ }>;
6201
+ expectedDays: z.ZodNullable<z.ZodNumber>;
6202
+ workedDays: z.ZodNullable<z.ZodNumber>;
6203
+ leaveDays: z.ZodNullable<z.ZodNumber>;
6204
+ absentDays: z.ZodNullable<z.ZodNumber>;
6205
+ absenceRate: z.ZodNullable<z.ZodNumber>;
6206
+ }, z.core.$strip>>;
6207
+ }, z.core.$strip>, import("@orpc/contract").MergedErrorMap<Record<never, never>, {
6208
+ BAD_REQUEST: {
6209
+ data: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
6210
+ };
6211
+ UNAUTHORIZED: {};
6212
+ FORBIDDEN: {
6213
+ data: z.ZodOptional<z.ZodObject<{
6214
+ permission: z.ZodOptional<z.ZodString>;
6215
+ }, z.core.$strip>>;
6216
+ };
6217
+ NOT_FOUND: {};
6218
+ CONFLICT: {
6219
+ data: z.ZodOptional<z.ZodObject<{
6220
+ reason: z.ZodOptional<z.ZodString>;
6221
+ }, z.core.$strip>>;
6222
+ };
6223
+ RATE_LIMITED: {};
6224
+ MODULE_DISABLED: {
6225
+ data: z.ZodObject<{
6226
+ module: z.ZodString;
6227
+ }, z.core.$strip>;
6228
+ };
6229
+ }>, Record<never, never>>;
6230
+ /**
6231
+ * Every balance in the population, per leave type, for one entitlement year.
6232
+ *
6233
+ * A balance is a position rather than a per-day quantity, so it is attributed as of one date —
6234
+ * `asOf`, defaulting to today — and the response says so. Summed from `leave_ledger`, never
6235
+ * from `leave_balance_cursor`: the cursor exists to be locked, and a cache that is also the
6236
+ * source of truth is one that eventually disagrees with it.
6237
+ */
6238
+ leaveBalance: import("@orpc/contract").ContractProcedureBuilderWithInputOutput<z.ZodObject<{
6239
+ workspaceId: z.core.$ZodBranded<z.ZodUUID, "WorkspaceId", "out">;
6240
+ periodYear: z.ZodOptional<z.ZodNumber>;
6241
+ asOf: z.ZodOptional<z.ZodISODate>;
6242
+ by: z.ZodDefault<z.ZodEnum<{
6243
+ office: "office";
6244
+ legal_entity: "legal_entity";
6245
+ workspace: "workspace";
6246
+ }>>;
6247
+ sliceId: z.ZodOptional<z.ZodUUID>;
6248
+ limit: z.ZodDefault<z.ZodNumber>;
6249
+ }, z.core.$strip>, z.ZodObject<{
6250
+ header: z.ZodObject<{
6251
+ from: z.ZodISODate;
6252
+ to: z.ZodISODate;
6253
+ slice: z.ZodObject<{
6254
+ by: z.ZodEnum<{
6255
+ office: "office";
6256
+ legal_entity: "legal_entity";
6257
+ workspace: "workspace";
6258
+ }>;
6259
+ id: z.ZodNullable<z.ZodUUID>;
6260
+ name: z.ZodNullable<z.ZodString>;
6261
+ }, z.core.$strip>;
6262
+ scope: z.ZodObject<{
6263
+ permissions: z.ZodArray<z.ZodString>;
6264
+ askedAt: z.ZodLiteral<"workspace">;
6265
+ }, z.core.$strip>;
6266
+ population: z.ZodNumber;
6267
+ counted: z.ZodNumber;
6268
+ attribution: z.ZodEnum<{
6269
+ each_day: "each_day";
6270
+ as_of_date: "as_of_date";
6271
+ not_applicable: "not_applicable";
6272
+ }>;
6273
+ attributionOn: z.ZodNullable<z.ZodISODate>;
6274
+ truncated: z.ZodBoolean;
6275
+ }, z.core.$strip>;
6276
+ periodYear: z.ZodNumber;
6277
+ dayLengthMinutes: z.ZodNumber;
6278
+ totals: z.ZodArray<z.ZodObject<{
6279
+ leaveTypeId: z.ZodUUID;
6280
+ leaveTypeName: z.ZodString;
6281
+ unit: z.ZodEnum<{
6282
+ half_day: "half_day";
6283
+ day: "day";
6284
+ hour: "hour";
6285
+ }>;
6286
+ people: z.ZodNumber;
6287
+ balanceMinutes: z.ZodNumber;
6288
+ bookedMinutes: z.ZodNumber;
6289
+ pendingMinutes: z.ZodNumber;
6290
+ availableMinutes: z.ZodNumber;
6291
+ }, z.core.$strip>>;
6292
+ rows: z.ZodArray<z.ZodObject<{
6293
+ personId: z.ZodUUID;
6294
+ displayName: z.ZodString;
6295
+ leaveTypeId: z.ZodUUID;
6296
+ leaveTypeName: z.ZodString;
6297
+ unit: z.ZodEnum<{
6298
+ half_day: "half_day";
6299
+ day: "day";
6300
+ hour: "hour";
6301
+ }>;
6302
+ balanceMinutes: z.ZodNumber;
6303
+ bookedMinutes: z.ZodNumber;
6304
+ pendingMinutes: z.ZodNumber;
6305
+ availableMinutes: z.ZodNumber;
6306
+ balance: z.ZodNumber;
6307
+ available: z.ZodNumber;
6308
+ }, z.core.$strip>>;
6309
+ }, z.core.$strip>, import("@orpc/contract").MergedErrorMap<Record<never, never>, {
6310
+ BAD_REQUEST: {
6311
+ data: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
6312
+ };
6313
+ UNAUTHORIZED: {};
6314
+ FORBIDDEN: {
6315
+ data: z.ZodOptional<z.ZodObject<{
6316
+ permission: z.ZodOptional<z.ZodString>;
6317
+ }, z.core.$strip>>;
6318
+ };
6319
+ NOT_FOUND: {};
6320
+ CONFLICT: {
6321
+ data: z.ZodOptional<z.ZodObject<{
6322
+ reason: z.ZodOptional<z.ZodString>;
6323
+ }, z.core.$strip>>;
6324
+ };
6325
+ RATE_LIMITED: {};
6326
+ MODULE_DISABLED: {
6327
+ data: z.ZodObject<{
6328
+ module: z.ZodString;
6329
+ }, z.core.$strip>;
6330
+ };
6331
+ }>, Record<never, never>>;
6332
+ };
5913
6333
  privacy: {
5914
6334
  /**
5915
6335
  * 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;AA2EvB,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA4BnB;;;;;;WAMG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAqCH,0FAA0F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAyD1F;;;;;WAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAkDD,6EAA6E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAkG/E,0FAA0F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAyB1F;;;;;;WAMG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA6GD;;;eAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAiCH;;;;;;eAMG;;;;;;;;;;;;;;;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"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/contract/router.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAkGvB,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA4BnB;;;;;;WAMG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAqCH,0FAA0F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAyD1F;;;;;WAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAkDD,6EAA6E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAkG/E,0FAA0F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAyB1F;;;;;;WAMG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA6GD;;;eAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAiCH;;;;;;eAMG;;;;;;;;;;;;;;;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"}
@@ -6,9 +6,25 @@ import { DayPart, LeaveBalance, LeaveLedgerEntry, LeaveRequest, LeaveSimulation,
6
6
  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
7
  import { AccrualPreview, Period, Policy, PolicyAssignment, PolicyKind, PolicySubjectKind, ResolvedPolicy, } from './policies.js';
8
8
  import { ErasureReport, HrRetention, RetentionSettings, SensitiveAccess, SubjectAccessBundle, } from './privacy.js';
9
+ import { AbsenceReport, AttendanceSummaryReport, LeaveBalanceReport, OvertimeReport, ReportSliceBy, } from './reports.js';
9
10
  const ws = z.object({ workspaceId: WorkspaceId });
10
11
  const t = ['hr'];
11
12
  const ok = z.object({ ok: z.literal(true) });
13
+ /**
14
+ * What every report takes: a range, a slice and how many rows to draw.
15
+ *
16
+ * `limit` bounds the rows, never the figures — `totals` and `population` are computed over everyone
17
+ * the slice covers and `truncated` says when the rows are the top of a longer list. A headline that
18
+ * silently described only the first page would be the exact defect these reports exist to avoid.
19
+ */
20
+ const reportInput = ws.extend({
21
+ from: IsoDate,
22
+ to: IsoDate,
23
+ by: ReportSliceBy.default('workspace'),
24
+ /** Required by `office` and `legal_entity`, ignored by `workspace`. */
25
+ sliceId: z.uuid().optional(),
26
+ limit: z.number().int().min(1).max(1000).default(100),
27
+ });
12
28
  export const hrContract = {
13
29
  // ---------------------------------------------------------------- people
14
30
  people: {
@@ -1066,6 +1082,87 @@ export const hrContract = {
1066
1082
  * nobody by default and ships in the same change as these — see `privacy.ts` for why there is one
1067
1083
  * key rather than four, and why none of this is a capability.
1068
1084
  */
1085
+ // ---------------------------------------------------------------- reports
1086
+ /**
1087
+ * Four aggregates, and one rule that decides all four: **a report may not answer a question its
1088
+ * row-level procedure would refuse, and may not narrow below what that procedure already
1089
+ * returns.**
1090
+ *
1091
+ * So each of these costs `hr.report.view` *and* the key that already guards the rows it sums —
1092
+ * `hr.attendance.view_team`, which is what reading a whole office's day sheets costs on
1093
+ * `attendance.days.list`, or `hr.leave.view_team`, which is what reading somebody else's balance
1094
+ * costs on `leave.balance.get`. A reader holding neither gets nothing: not a one-row self-report,
1095
+ * because a reports menu that quietly collapses to your own attendance is a menu entry that lies
1096
+ * about what it is, and your own attendance is already the attendance page.
1097
+ *
1098
+ * The population is **not** intersected with `HrAccessService.visiblePersonIds`. That service
1099
+ * narrows *fields* rather than rows — it withholds `personalEmail`, `phone`, `hiredOn` and
1100
+ * `terminatedOn`, none of which any report reads — and intersecting on it would produce the worst
1101
+ * outcome available here: two managers reading different totals under the same title, with
1102
+ * nothing on the page to say so.
1103
+ */
1104
+ reports: {
1105
+ /**
1106
+ * Scheduled against worked, per person, over a range.
1107
+ *
1108
+ * Built from `attendance_days` and never from `punches`: punches are raw and append-only, a
1109
+ * voided punch survives beside its correction, and summing them double-counts every fix. The
1110
+ * day sheet is the projection those punches produce.
1111
+ */
1112
+ attendance: baseContract
1113
+ .route({ method: 'GET', path: '/reports/attendance', tags: t })
1114
+ .input(reportInput)
1115
+ .output(AttendanceSummaryReport),
1116
+ /**
1117
+ * Overtime, and how much of it an annual ceiling would not take.
1118
+ *
1119
+ * `beyondCapMinutes` is null where no ceiling was in force — summed as a nullable column rather
1120
+ * than coalesced, so "no ceiling applied to these days" and "a ceiling applied and nothing
1121
+ * passed it" stay different answers. No projection: there is no "at this rate you will pass the
1122
+ * ceiling in November", because that needs a policy that may not exist.
1123
+ */
1124
+ overtime: baseContract
1125
+ .route({ method: 'GET', path: '/reports/overtime', tags: t })
1126
+ .input(reportInput)
1127
+ .output(OvertimeReport),
1128
+ /**
1129
+ * Expected working days, minus days worked, minus approved leave.
1130
+ *
1131
+ * **Never `status = 'absent'`.** `attendance_days` has a row only where somebody punched — no
1132
+ * writer creates one for a day nobody clocked in on — so counting absent rows reports near-zero
1133
+ * absence everywhere and looks entirely healthy while doing it. The denominator comes from the
1134
+ * calendar instead, and a person the module cannot build one for lands in a named row rather
1135
+ * than being counted as present.
1136
+ *
1137
+ * Held to `MAX_SLICED_REPORT_DAYS` whether it is sliced or not: every person's expectation is
1138
+ * their office's calendar on each day, which is a ladder walk per day.
1139
+ */
1140
+ absence: baseContract
1141
+ .route({ method: 'GET', path: '/reports/absence', tags: t })
1142
+ .input(reportInput)
1143
+ .output(AbsenceReport),
1144
+ /**
1145
+ * Every balance in the population, per leave type, for one entitlement year.
1146
+ *
1147
+ * A balance is a position rather than a per-day quantity, so it is attributed as of one date —
1148
+ * `asOf`, defaulting to today — and the response says so. Summed from `leave_ledger`, never
1149
+ * from `leave_balance_cursor`: the cursor exists to be locked, and a cache that is also the
1150
+ * source of truth is one that eventually disagrees with it.
1151
+ */
1152
+ leaveBalance: baseContract
1153
+ .route({ method: 'GET', path: '/reports/leave-balance', tags: t })
1154
+ .input(ws.extend({
1155
+ /** Defaults to the year `asOf` falls in. */
1156
+ periodYear: z.number().int().min(1970).max(2200).optional(),
1157
+ /** Which day decides who is in the slice. Defaults to today. */
1158
+ asOf: IsoDate.optional(),
1159
+ by: ReportSliceBy.default('workspace'),
1160
+ sliceId: z.uuid().optional(),
1161
+ limit: z.number().int().min(1).max(1000).default(100),
1162
+ }))
1163
+ .output(LeaveBalanceReport),
1164
+ },
1165
+ // ---------------------------------------------------------------- privacy
1069
1166
  privacy: {
1070
1167
  /**
1071
1168
  * Everything HR holds about one person, in one response.