@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.
@@ -0,0 +1,318 @@
1
+ import { z } from 'zod';
2
+ import { LeaveUnit } from './leave.js';
3
+ import { IsoDate } from './models.js';
4
+ /**
5
+ * Four numbers a company acts on, and the three rules that make them safe to act on.
6
+ *
7
+ * **1. A total states its own denominator.** "47 hours of overtime" means nothing on its own; "47
8
+ * hours · 12 of 38 people · 1–31 October · Istanbul office" is a fact. Every report here carries a
9
+ * `ReportHeader` saying who it counted, over what range, under which slice, and — because two
10
+ * managers must never read the same title over different populations — **which permission produced
11
+ * it**. A report is a separate grant, not a narrowing: a reader without the key gets nothing rather
12
+ * than a quieter number.
13
+ *
14
+ * **2. Unknown is not zero.** Every figure a person's data cannot answer is `null` here, and a
15
+ * screen renders `null` as an em dash. Never 0%, never "0 days absent". The three that bite:
16
+ * somebody with no schedule has no attendance percentage (the denominator is zero, not the
17
+ * numerator); an office with no calendar attached has no expected working days (Mon–Fri would be an
18
+ * assumption this module does not make, and it is wrong for every Gulf and Iranian office); and
19
+ * `beyondCapMinutes` is null where **no cap was in force**, which is a different fact from a cap
20
+ * that nothing exceeded.
21
+ *
22
+ * **3. Nothing here is projected or entitled.** No year-end balance, no "at this rate you will pass
23
+ * the annual ceiling in November", no allowance remaining. All three need either a policy that may
24
+ * not exist or a workspace day length this module does not hold — `MINUTES_PER_DAY` is a constant,
25
+ * so a `day`-unit figure is an 8-hour day whatever the leave type is called. `dayLengthMinutes` on
26
+ * the balance report says so on its face rather than leaving a reader to assume their own.
27
+ *
28
+ * The reports read; nothing here recomputes a day sheet. A "refresh" on a reports page is a write
29
+ * into a month payroll may already have filed, and `AttendanceService.recomputeDay` is the only
30
+ * thing entitled to decide whether a day may move.
31
+ */
32
+ /**
33
+ * The longest range a report may cover, in days.
34
+ *
35
+ * A year, because an annual overtime figure against a statutory ceiling is a real question and a
36
+ * two-year one is not. An unsliced attendance or overtime report is a single grouped aggregate, so
37
+ * the length costs the database and nothing else.
38
+ */
39
+ export const MAX_REPORT_DAYS = 366;
40
+ /**
41
+ * The longest range a report may cover once it is **sliced**, and the range the absence report is
42
+ * held to whatever it is sliced by.
43
+ *
44
+ * Both walk the resolution ladder once per day in the range, because a number has to be attributed
45
+ * to the office in force on the day it describes rather than the one somebody sits in today. That
46
+ * is a handful of small indexed queries per day; a quarter is fine and a year is not. The absence
47
+ * report pays it unsliced as well, because a person's expected days come from their office's
48
+ * calendar and that is the same walk.
49
+ *
50
+ * The honest fix is a range-aware batch in `ResolveService` — one walk that answers a span rather
51
+ * than a date. Until that exists, this is the cap rather than a slow report nobody can cancel.
52
+ */
53
+ export const MAX_SLICED_REPORT_DAYS = 92;
54
+ /**
55
+ * The most person-days a per-day report will resolve before refusing.
56
+ *
57
+ * `people × days`, and it is a refusal with both numbers in it rather than a timeout: a report that
58
+ * quietly takes four minutes is worse than one that says "1,900 people over 92 days is 174,800
59
+ * person-days — ask for one office, or a shorter range".
60
+ */
61
+ export const MAX_PERSON_DAYS = 60_000;
62
+ /**
63
+ * How a report was narrowed.
64
+ *
65
+ * `workspace` is everybody; `office` and `legal_entity` are what the resolution ladder can answer
66
+ * about a person on a date. **There is no `cost_center`**, and the omission is deliberate:
67
+ * `PersonResolution` carries `primaryOfficeId`, `legalEntityId` and `orgUnitId` and no cost centre,
68
+ * so a cost-centre slice would have to join `employments` inside a report handler — a second
69
+ * resolution ladder, which is the drift `ResolveService`'s header exists to prevent. It arrives
70
+ * when `PersonResolution` grows the field, not before.
71
+ */
72
+ export const ReportSliceBy = z.enum(['workspace', 'office', 'legal_entity']);
73
+ export const ReportSlice = z.object({
74
+ by: ReportSliceBy,
75
+ /** Null for `workspace`, which needs no id. */
76
+ id: z.uuid().nullable(),
77
+ /** Resolved for the reader, so the report can name its own population without a second call. */
78
+ name: z.string().nullable(),
79
+ });
80
+ /**
81
+ * When a person was attributed to the slice.
82
+ *
83
+ * `each_day` is what everything in this module that computes a *number* already does — a day sheet
84
+ * is rebuilt against the entity in force on the day it covers, a period lock resolves per date, the
85
+ * accrual job resolves on the last day of the period. Copying the nearest list handler, which
86
+ * filters on "assignment with no end date", is the wrong instinct: it hands a transfer's whole
87
+ * previous quarter to the receiving office.
88
+ *
89
+ * `as_of_date` is honest for a balance, which is a position rather than a per-day quantity, and
90
+ * `attributionOn` says which date. `not_applicable` is an unsliced report, where nobody is
91
+ * attributed to anything.
92
+ */
93
+ export const ReportAttribution = z.enum(['each_day', 'as_of_date', 'not_applicable']);
94
+ /**
95
+ * Which grant produced this population, and at what scope it was asked.
96
+ *
97
+ * On the response rather than left implicit, because the failure this prevents is not a leak: it is
98
+ * two managers opening "Overtime · October · Istanbul", getting different totals under one title,
99
+ * and neither being told why. `askedAt` is always `workspace` — `hr.attendance.view_team` and
100
+ * `hr.leave.view_team` are declared at object scope, and `Authz.can(object, id)` falls through to
101
+ * the workspace-level effective set, so binding a key to an office id narrows nothing today. Saying
102
+ * so here stops a reader inferring a narrowing that is not happening.
103
+ */
104
+ export const ReportScope = z.object({
105
+ /** `hr.report.view`, plus the data key the figures needed. */
106
+ permissions: z.array(z.string()).min(1),
107
+ askedAt: z.literal('workspace'),
108
+ });
109
+ export const ReportHeader = z.object({
110
+ from: IsoDate,
111
+ to: IsoDate,
112
+ slice: ReportSlice,
113
+ scope: ReportScope,
114
+ /** Everybody the slice covers over the range. **The denominator**, and never omitted. */
115
+ population: z.number().int(),
116
+ /** How many of `population` have anything at all behind the figures. */
117
+ counted: z.number().int(),
118
+ attribution: ReportAttribution,
119
+ /** The date `as_of_date` attribution used. Null for the other two. */
120
+ attributionOn: IsoDate.nullable(),
121
+ /** True when `rows` is the top `limit` of `counted` rather than all of it. */
122
+ truncated: z.boolean(),
123
+ });
124
+ /**
125
+ * Whether the figures can move again.
126
+ *
127
+ * A range that straddles a lock boundary mixes final figures with provisional ones — tonight's
128
+ * `reconcile-days` will change the open half — so a report must never present the mixed total as
129
+ * final. Where a workspace has no periods at all (the `periods` capability ships off), every day is
130
+ * open and that is entirely normal: `final: false` with `lockedDays: 0` is not a warning.
131
+ */
132
+ export const ReportFinality = z.object({
133
+ lockedDays: z.number().int(),
134
+ openDays: z.number().int(),
135
+ /** True only when every day counted sits inside a locked period. */
136
+ final: z.boolean(),
137
+ /** The earliest day still able to move, or null when none is. */
138
+ firstOpenDay: IsoDate.nullable(),
139
+ /** The latest day already frozen, or null when none is. */
140
+ lastLockedDay: IsoDate.nullable(),
141
+ });
142
+ // ---------------------------------------------------------------- attendance summary
143
+ export const AttendanceSummaryRow = z.object({
144
+ personId: z.uuid(),
145
+ /**
146
+ * The directory name, and the erasure token for somebody who has been erased.
147
+ *
148
+ * Their day sheets and ledger entries survive an erasure by design, so the row stays and the
149
+ * token is shown as it is stored. Dropping the row would change the total; printing "Unknown"
150
+ * would hide that this is a person the workspace deliberately redacted.
151
+ */
152
+ displayName: z.string(),
153
+ /** Day sheets counted. Not the length of the range — a day nobody punched has no sheet. */
154
+ days: z.number().int(),
155
+ scheduledMinutes: z.number().int(),
156
+ workedMinutes: z.number().int(),
157
+ breakMinutes: z.number().int(),
158
+ lateMinutes: z.number().int(),
159
+ earlyLeaveMinutes: z.number().int(),
160
+ /**
161
+ * `worked ÷ scheduled`, 0–1 — **null when nothing was scheduled**.
162
+ *
163
+ * Somebody with no schedule assignment owes no hours, so the denominator is zero and the answer
164
+ * is unknown rather than 0% or 100%. In a workspace that clocks in only part of its staff, that
165
+ * is most of the directory.
166
+ */
167
+ workedRatio: z.number().nullable(),
168
+ /** Sheets produced with no schedule in force, read off the policy stamp rather than guessed. */
169
+ noScheduleDays: z.number().int(),
170
+ /** Sheets with no policy stamp at all, where neither state can be claimed. */
171
+ unknownScheduleDays: z.number().int(),
172
+ });
173
+ export const AttendanceSummaryTotals = AttendanceSummaryRow.omit({
174
+ personId: true,
175
+ displayName: true,
176
+ });
177
+ export const AttendanceSummaryReport = z.object({
178
+ header: ReportHeader,
179
+ finality: ReportFinality,
180
+ /** Over the whole population, never only the rows returned. */
181
+ totals: AttendanceSummaryTotals,
182
+ rows: z.array(AttendanceSummaryRow),
183
+ });
184
+ // ---------------------------------------------------------------- overtime
185
+ export const OvertimeRow = z.object({
186
+ personId: z.uuid(),
187
+ displayName: z.string(),
188
+ days: z.number().int(),
189
+ overtimeMinutes: z.number().int(),
190
+ /**
191
+ * Overtime an annual ceiling would not take — **null when no ceiling was in force on any day
192
+ * counted**, which is not zero.
193
+ *
194
+ * Zero means a ceiling applied and nothing passed it. Null means the question was never asked of
195
+ * these days. Coalescing the two destroys the distinction the column exists for, and it is the
196
+ * distinction a statutory-ceiling conversation turns on.
197
+ */
198
+ beyondCapMinutes: z.number().int().nullable(),
199
+ /** Days a ceiling applied to. Zero here is why `beyondCapMinutes` is null. */
200
+ cappedDays: z.number().int(),
201
+ uncappedDays: z.number().int(),
202
+ });
203
+ export const OvertimeTotals = OvertimeRow.omit({ personId: true, displayName: true });
204
+ export const OvertimeReport = z.object({
205
+ header: ReportHeader,
206
+ finality: ReportFinality,
207
+ totals: OvertimeTotals,
208
+ rows: z.array(OvertimeRow),
209
+ });
210
+ // ---------------------------------------------------------------- absence
211
+ /**
212
+ * What the expected-days figure rests on, per person.
213
+ *
214
+ * `no_schedule` and `no_calendar` are **named rows, not silent drops**. A person with no schedule
215
+ * assignment owes no hours, so "absent" is not a fact this module holds about them — and in a
216
+ * workspace that clocks in only its shift staff they are the majority. An office with no calendar
217
+ * attached would fall back to Monday–Friday, which is an assumption rather than an answer, so the
218
+ * expectation is withheld and the reason is printed instead.
219
+ */
220
+ export const AbsenceBasis = z.enum(['calendar', 'no_calendar', 'no_schedule']);
221
+ export const AbsenceRow = z.object({
222
+ personId: z.uuid(),
223
+ displayName: z.string(),
224
+ basis: AbsenceBasis,
225
+ /** Working days the calendar expected, weighted for half days. Null unless `basis` is `calendar`. */
226
+ expectedDays: z.number().nullable(),
227
+ /** Expected days with a day sheet showing work. */
228
+ workedDays: z.number().nullable(),
229
+ /**
230
+ * Expected days covered by approved, counted leave.
231
+ *
232
+ * **Null when the `leave` capability is off** rather than zero — the column is omitted, not
233
+ * answered. There is no breakdown by leave type here and there will not be one under this key:
234
+ * the team calendar deliberately withholds the type from anybody without `hr.leave.view_ledger`,
235
+ * so that the team can know somebody is away without knowing it is sick leave, and a per-type
236
+ * column would republish exactly that.
237
+ */
238
+ leaveDays: z.number().nullable(),
239
+ /** `expected − worked − leave`, floored at zero. Null wherever `expectedDays` is. */
240
+ absentDays: z.number().nullable(),
241
+ /** `absent ÷ expected`, 0–1. Null when there was nothing to expect. */
242
+ absenceRate: z.number().nullable(),
243
+ });
244
+ export const AbsenceTotals = z.object({
245
+ /** People whose `basis` is `calendar` — the only ones the totals below are computed over. */
246
+ measured: z.number().int(),
247
+ expectedDays: z.number(),
248
+ workedDays: z.number(),
249
+ leaveDays: z.number().nullable(),
250
+ absentDays: z.number(),
251
+ absenceRate: z.number().nullable(),
252
+ });
253
+ export const AbsenceReport = z.object({
254
+ header: ReportHeader,
255
+ finality: ReportFinality,
256
+ /**
257
+ * Whether approved leave was subtracted at all.
258
+ *
259
+ * False when the `leave` capability is off in this workspace, in which case every `leaveDays` is
260
+ * null and `absentDays` is `expected − worked`. Saying so is what stops a reader treating an
261
+ * inflated absence figure as a fact about attendance.
262
+ */
263
+ leaveCounted: z.boolean(),
264
+ totals: AbsenceTotals,
265
+ /** The two named buckets held out of the denominator, so nobody is dropped in silence. */
266
+ excluded: z.object({ noSchedule: z.number().int(), noCalendar: z.number().int() }),
267
+ rows: z.array(AbsenceRow),
268
+ });
269
+ // ---------------------------------------------------------------- leave balance
270
+ export const LeaveBalanceRow = z.object({
271
+ personId: z.uuid(),
272
+ displayName: z.string(),
273
+ leaveTypeId: z.uuid(),
274
+ leaveTypeName: z.string(),
275
+ unit: LeaveUnit,
276
+ /** The authoritative figures. Minutes, because half days and hourly leave divide a day. */
277
+ balanceMinutes: z.number().int(),
278
+ bookedMinutes: z.number().int(),
279
+ pendingMinutes: z.number().int(),
280
+ availableMinutes: z.number().int(),
281
+ /** The same two in the leave type's own unit, for display. Read `dayLengthMinutes` first. */
282
+ balance: z.number(),
283
+ available: z.number(),
284
+ });
285
+ export const LeaveBalanceReport = z.object({
286
+ header: ReportHeader,
287
+ periodYear: z.number().int(),
288
+ /**
289
+ * How long a `day` is when a day-unit figure is rendered here.
290
+ *
291
+ * A constant in this module, not a workspace setting — so "12.5 days" is 12.5 eight-hour days
292
+ * whatever the workspace's own day happens to be. Published rather than assumed, because a report
293
+ * that prints days without saying which day is the quiet way this goes wrong.
294
+ */
295
+ dayLengthMinutes: z.number().int(),
296
+ /**
297
+ * One line per leave type, over the whole population.
298
+ *
299
+ * There is no entitlement, allowance-remaining or projected year-end column, here or on a row.
300
+ * Each of those needs an accrual policy, and a company that grants a fixed allowance on 1 January
301
+ * has none — `PolicyService.forPerson` answers `{ policyId: null }` rather than throwing, and a
302
+ * balance relabelled as an entitlement would be this module inventing the number it declined to
303
+ * guess everywhere else.
304
+ */
305
+ totals: z.array(z.object({
306
+ leaveTypeId: z.uuid(),
307
+ leaveTypeName: z.string(),
308
+ unit: LeaveUnit,
309
+ /** People holding a non-zero position in this type. */
310
+ people: z.number().int(),
311
+ balanceMinutes: z.number().int(),
312
+ bookedMinutes: z.number().int(),
313
+ pendingMinutes: z.number().int(),
314
+ availableMinutes: z.number().int(),
315
+ })),
316
+ rows: z.array(LeaveBalanceRow),
317
+ });
318
+ //# sourceMappingURL=reports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reports.js","sourceRoot":"","sources":["../../src/contract/reports.ts"],"names":[],"mappings":"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"}