@kernhq/module-hr 0.1.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/LICENSE +662 -0
- package/README.md +71 -0
- package/dist/contract/capabilities.d.ts +45 -0
- package/dist/contract/capabilities.d.ts.map +1 -0
- package/dist/contract/capabilities.js +114 -0
- package/dist/contract/capabilities.js.map +1 -0
- package/dist/contract/events.d.ts +74 -0
- package/dist/contract/events.d.ts.map +1 -0
- package/dist/contract/events.js +63 -0
- package/dist/contract/events.js.map +1 -0
- package/dist/contract/index.d.ts +15 -0
- package/dist/contract/index.d.ts.map +1 -0
- package/dist/contract/index.js +15 -0
- package/dist/contract/index.js.map +1 -0
- package/dist/contract/models.d.ts +457 -0
- package/dist/contract/models.d.ts.map +1 -0
- package/dist/contract/models.js +381 -0
- package/dist/contract/models.js.map +1 -0
- package/dist/contract/permissions.d.ts +174 -0
- package/dist/contract/permissions.d.ts.map +1 -0
- package/dist/contract/permissions.js +209 -0
- package/dist/contract/permissions.js.map +1 -0
- package/dist/contract/router.d.ts +2720 -0
- package/dist/contract/router.d.ts.map +1 -0
- package/dist/contract/router.js +520 -0
- package/dist/contract/router.js.map +1 -0
- package/dist/contract/settings.d.ts +20 -0
- package/dist/contract/settings.d.ts.map +1 -0
- package/dist/contract/settings.js +34 -0
- package/dist/contract/settings.js.map +1 -0
- package/dist/policy/calendar.d.ts +64 -0
- package/dist/policy/calendar.d.ts.map +1 -0
- package/dist/policy/calendar.js +113 -0
- package/dist/policy/calendar.js.map +1 -0
- package/dist/server/index.d.ts +8 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +141 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/packs/index.d.ts +50 -0
- package/dist/server/packs/index.d.ts.map +1 -0
- package/dist/server/packs/index.js +121 -0
- package/dist/server/packs/index.js.map +1 -0
- package/dist/server/router.d.ts +3095 -0
- package/dist/server/router.d.ts.map +1 -0
- package/dist/server/router.js +1537 -0
- package/dist/server/router.js.map +1 -0
- package/dist/server/schema.d.ts +2828 -0
- package/dist/server/schema.d.ts.map +1 -0
- package/dist/server/schema.js +313 -0
- package/dist/server/schema.js.map +1 -0
- package/dist/server/services/db.d.ts +22 -0
- package/dist/server/services/db.d.ts.map +1 -0
- package/dist/server/services/db.js +23 -0
- package/dist/server/services/db.js.map +1 -0
- package/dist/server/services/people.d.ts +110 -0
- package/dist/server/services/people.d.ts.map +1 -0
- package/dist/server/services/people.js +182 -0
- package/dist/server/services/people.js.map +1 -0
- package/dist/server/services/resolve.d.ts +66 -0
- package/dist/server/services/resolve.d.ts.map +1 -0
- package/dist/server/services/resolve.js +145 -0
- package/dist/server/services/resolve.js.map +1 -0
- package/migrations/0000_init.sql +223 -0
- package/migrations/0001_rls.sql +141 -0
- package/migrations/meta/0000_snapshot.json +1715 -0
- package/migrations/meta/_journal.json +20 -0
- package/package.json +59 -0
- package/src/client/index.ts +62 -0
- package/src/contract/capabilities.ts +117 -0
- package/src/contract/events.ts +84 -0
- package/src/contract/index.ts +14 -0
- package/src/contract/models.ts +437 -0
- package/src/contract/permissions.ts +217 -0
- package/src/contract/router.ts +611 -0
- package/src/contract/settings.ts +35 -0
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
import { Timestamp, WorkspaceId } from '@kernhq/contracts';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/** Lowercase, 2-32 characters. Names the API prefix, the Postgres schema `mod_hr` and every event. */
|
|
4
|
+
export const MODULE_ID = 'hr';
|
|
5
|
+
/** A calendar date with no time and no zone: `2026-08-24`. */
|
|
6
|
+
export const IsoDate = z.iso.date();
|
|
7
|
+
/**
|
|
8
|
+
* An IANA zone name, never an offset.
|
|
9
|
+
*
|
|
10
|
+
* `+03:00` is a fact about one instant; `Europe/Istanbul` is a fact about a place, and only the
|
|
11
|
+
* second survives a daylight-saving transition. Everything in this module that has to turn a wall
|
|
12
|
+
* clock into an instant reads one of these.
|
|
13
|
+
*/
|
|
14
|
+
export const TimeZone = z.string().min(1).max(64);
|
|
15
|
+
/** ISO 3166-1 alpha-2, upper case: `TR`, `NL`, `DE`. */
|
|
16
|
+
export const CountryCode = z
|
|
17
|
+
.string()
|
|
18
|
+
.length(2)
|
|
19
|
+
.regex(/^[A-Z]{2}$/);
|
|
20
|
+
/** ISO 3166-2 subdivision, without the country prefix: `34` for Istanbul, `BY` for Bavaria. */
|
|
21
|
+
export const RegionCode = z.string().min(1).max(8);
|
|
22
|
+
/** `09:00` — a wall clock reading, meaningless until a date and a zone are supplied. */
|
|
23
|
+
export const WallClock = z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/);
|
|
24
|
+
const ws = { workspaceId: WorkspaceId };
|
|
25
|
+
// =====================================================================================
|
|
26
|
+
// people
|
|
27
|
+
// =====================================================================================
|
|
28
|
+
export const PersonStatus = z.enum(['onboarding', 'active', 'on_leave', 'offboarding', 'terminated']);
|
|
29
|
+
export const Person = z.object({
|
|
30
|
+
id: z.uuid(),
|
|
31
|
+
...ws,
|
|
32
|
+
/**
|
|
33
|
+
* The Kern account, when there is one.
|
|
34
|
+
*
|
|
35
|
+
* Nullable on purpose. Plenty of employees never sign in — factory floor, drivers, seasonal staff
|
|
36
|
+
* — and a directory that can only hold people with logins is not a directory. It also means HR can
|
|
37
|
+
* be populated before anyone is invited.
|
|
38
|
+
*/
|
|
39
|
+
userId: z.uuid().nullable(),
|
|
40
|
+
employeeNo: z.string().min(1).max(32).nullable(),
|
|
41
|
+
displayName: z.string().min(1).max(160),
|
|
42
|
+
workEmail: z.email().max(254).nullable(),
|
|
43
|
+
personalEmail: z.email().max(254).nullable(),
|
|
44
|
+
phone: z.string().max(32).nullable(),
|
|
45
|
+
photoFileId: z.uuid().nullable(),
|
|
46
|
+
status: PersonStatus,
|
|
47
|
+
hiredOn: IsoDate.nullable(),
|
|
48
|
+
terminatedOn: IsoDate.nullable(),
|
|
49
|
+
/** Overrides the primary office's zone for somebody who genuinely works elsewhere. */
|
|
50
|
+
timezone: TimeZone.nullable(),
|
|
51
|
+
custom: z.record(z.string(), z.unknown()),
|
|
52
|
+
createdAt: Timestamp,
|
|
53
|
+
updatedAt: Timestamp,
|
|
54
|
+
});
|
|
55
|
+
/**
|
|
56
|
+
* The fields that need a second permission.
|
|
57
|
+
*
|
|
58
|
+
* A separate shape, not optional fields on `Person`, because optional fields get returned by
|
|
59
|
+
* accident. Somebody with `hr.person.view` can read the directory; reading a national identity
|
|
60
|
+
* number takes `hr.person.view_sensitive`, and the two never travel in the same object.
|
|
61
|
+
*/
|
|
62
|
+
export const PersonSensitive = z.object({
|
|
63
|
+
personId: z.uuid(),
|
|
64
|
+
...ws,
|
|
65
|
+
nationalId: z.string().max(64).nullable(),
|
|
66
|
+
birthDate: IsoDate.nullable(),
|
|
67
|
+
iban: z.string().max(48).nullable(),
|
|
68
|
+
emergencyContact: z
|
|
69
|
+
.object({
|
|
70
|
+
name: z.string().max(160),
|
|
71
|
+
relationship: z.string().max(64).optional(),
|
|
72
|
+
phone: z.string().max(32),
|
|
73
|
+
})
|
|
74
|
+
.nullable(),
|
|
75
|
+
});
|
|
76
|
+
// =====================================================================================
|
|
77
|
+
// employment — effective-dated
|
|
78
|
+
// =====================================================================================
|
|
79
|
+
export const EmploymentType = z.enum([
|
|
80
|
+
'full_time',
|
|
81
|
+
'part_time',
|
|
82
|
+
'contract',
|
|
83
|
+
'intern',
|
|
84
|
+
'temporary',
|
|
85
|
+
'freelance',
|
|
86
|
+
]);
|
|
87
|
+
/**
|
|
88
|
+
* One row per period a person's job was a given shape. Never updated in place.
|
|
89
|
+
*
|
|
90
|
+
* Titles, managers, departments and hours all change, and a system that overwrites them cannot
|
|
91
|
+
* answer "who did she report to in March", which is the question a leave approval from March needs.
|
|
92
|
+
* A change closes the current row (`effectiveTo`) and opens a new one; `effectiveTo === null` is the
|
|
93
|
+
* present. The database refuses overlaps.
|
|
94
|
+
*
|
|
95
|
+
* **Office is deliberately not here.** People change desks and change jobs on different days, and
|
|
96
|
+
* folding the two together forces a fake promotion every time somebody relocates. See
|
|
97
|
+
* `OfficeAssignment`.
|
|
98
|
+
*/
|
|
99
|
+
export const Employment = z.object({
|
|
100
|
+
id: z.uuid(),
|
|
101
|
+
...ws,
|
|
102
|
+
personId: z.uuid(),
|
|
103
|
+
effectiveFrom: IsoDate,
|
|
104
|
+
effectiveTo: IsoDate.nullable(),
|
|
105
|
+
orgUnitId: z.uuid().nullable(),
|
|
106
|
+
positionId: z.uuid().nullable(),
|
|
107
|
+
legalEntityId: z.uuid().nullable(),
|
|
108
|
+
costCenterId: z.uuid().nullable(),
|
|
109
|
+
managerPersonId: z.uuid().nullable(),
|
|
110
|
+
employmentType: EmploymentType,
|
|
111
|
+
/** 1.0 is full time; 0.5 is a half-time contract. Drives proration everywhere. */
|
|
112
|
+
fte: z.number().min(0).max(1),
|
|
113
|
+
contractHoursWeek: z.number().min(0).max(168).nullable(),
|
|
114
|
+
reason: z.string().max(200).nullable(),
|
|
115
|
+
createdAt: Timestamp,
|
|
116
|
+
});
|
|
117
|
+
// =====================================================================================
|
|
118
|
+
// org structure
|
|
119
|
+
// =====================================================================================
|
|
120
|
+
export const OrgUnit = z.object({
|
|
121
|
+
id: z.uuid(),
|
|
122
|
+
...ws,
|
|
123
|
+
parentId: z.uuid().nullable(),
|
|
124
|
+
/** Materialised ltree path, e.g. `root.engineering.platform`. Read-only: `org.units.move` sets it. */
|
|
125
|
+
path: z.string().max(512),
|
|
126
|
+
name: z.string().min(1).max(160),
|
|
127
|
+
code: z.string().max(32).nullable(),
|
|
128
|
+
headPersonId: z.uuid().nullable(),
|
|
129
|
+
archivedAt: Timestamp.nullable(),
|
|
130
|
+
});
|
|
131
|
+
export const Position = z.object({
|
|
132
|
+
id: z.uuid(),
|
|
133
|
+
...ws,
|
|
134
|
+
title: z.string().min(1).max(160),
|
|
135
|
+
code: z.string().max(32).nullable(),
|
|
136
|
+
jobFamily: z.string().max(64).nullable(),
|
|
137
|
+
level: z.string().max(32).nullable(),
|
|
138
|
+
archivedAt: Timestamp.nullable(),
|
|
139
|
+
});
|
|
140
|
+
// =====================================================================================
|
|
141
|
+
// offices — the unit of inheritance
|
|
142
|
+
// =====================================================================================
|
|
143
|
+
export const OfficeKind = z.enum([
|
|
144
|
+
'head_office',
|
|
145
|
+
'branch',
|
|
146
|
+
'site',
|
|
147
|
+
'warehouse',
|
|
148
|
+
'store',
|
|
149
|
+
/** Where remote people belong. Carries a country, a zone and a calendar like anywhere else. */
|
|
150
|
+
'remote',
|
|
151
|
+
]);
|
|
152
|
+
/**
|
|
153
|
+
* A place the company operates, and the thing a person inherits from.
|
|
154
|
+
*
|
|
155
|
+
* One workspace, many offices: a head office in Istanbul, a branch in Amsterdam, two sites in the
|
|
156
|
+
* same city, and the remote people. Each carries what differs by geography — country, timezone,
|
|
157
|
+
* working week, holidays — so "which days am I off" has a local answer without a workspace per
|
|
158
|
+
* country.
|
|
159
|
+
*
|
|
160
|
+
* A workspace always has exactly one office even when the `offices` capability is off; it is created
|
|
161
|
+
* from the workspace country and never shown. That is what lets the capability be a *reveal* rather
|
|
162
|
+
* than a migration, and it is why nothing in this module has a "no office" branch.
|
|
163
|
+
*/
|
|
164
|
+
export const Office = z.object({
|
|
165
|
+
id: z.uuid(),
|
|
166
|
+
...ws,
|
|
167
|
+
name: z.string().min(1).max(160),
|
|
168
|
+
code: z.string().max(32).nullable(),
|
|
169
|
+
kind: OfficeKind,
|
|
170
|
+
/** A campus with buildings. This is geography, *not* the org chart — see `OrgUnit`. */
|
|
171
|
+
parentOfficeId: z.uuid().nullable(),
|
|
172
|
+
legalEntityId: z.uuid().nullable(),
|
|
173
|
+
country: CountryCode,
|
|
174
|
+
region: RegionCode.nullable(),
|
|
175
|
+
city: z.string().max(120).nullable(),
|
|
176
|
+
timezone: TimeZone,
|
|
177
|
+
calendarId: z.uuid().nullable(),
|
|
178
|
+
address: z
|
|
179
|
+
.object({
|
|
180
|
+
line1: z.string().max(200).optional(),
|
|
181
|
+
line2: z.string().max(200).optional(),
|
|
182
|
+
postalCode: z.string().max(32).optional(),
|
|
183
|
+
})
|
|
184
|
+
.nullable(),
|
|
185
|
+
/** Exactly one office per workspace carries this. Where a new person lands with no assignment. */
|
|
186
|
+
isDefault: z.boolean(),
|
|
187
|
+
headPersonId: z.uuid().nullable(),
|
|
188
|
+
archivedAt: Timestamp.nullable(),
|
|
189
|
+
createdAt: Timestamp,
|
|
190
|
+
});
|
|
191
|
+
/**
|
|
192
|
+
* Who works where, over time.
|
|
193
|
+
*
|
|
194
|
+
* A person may hold several of these at once — somebody splitting the week between two sites — but
|
|
195
|
+
* **exactly one is primary at any date, and only the primary decides.** Non-primary offices grant
|
|
196
|
+
* presence: the person appears in that office's directory, its local HR can see them, and later its
|
|
197
|
+
* geofence will accept their punch. They never decide which holidays apply, which policy applies, or
|
|
198
|
+
* which timezone the person's day is attributed in.
|
|
199
|
+
*
|
|
200
|
+
* Any other rule turns "how many days off do I have" into a question with two answers, which is not
|
|
201
|
+
* a thing an employee or an auditor will accept.
|
|
202
|
+
*/
|
|
203
|
+
export const OfficeAssignment = z.object({
|
|
204
|
+
id: z.uuid(),
|
|
205
|
+
...ws,
|
|
206
|
+
personId: z.uuid(),
|
|
207
|
+
officeId: z.uuid(),
|
|
208
|
+
isPrimary: z.boolean(),
|
|
209
|
+
effectiveFrom: IsoDate,
|
|
210
|
+
effectiveTo: IsoDate.nullable(),
|
|
211
|
+
reason: z.string().max(200).nullable(),
|
|
212
|
+
createdAt: Timestamp,
|
|
213
|
+
});
|
|
214
|
+
/**
|
|
215
|
+
* Who actually employs somebody.
|
|
216
|
+
*
|
|
217
|
+
* Distinct from the office: two Turkish offices can share one entity, and one office can host two.
|
|
218
|
+
* It exists because payroll is filed per legal employer, never per workspace — so a group with a
|
|
219
|
+
* Dutch B.V. and a Turkish A.Ş. closes two different payrolls out of one Kern workspace.
|
|
220
|
+
*/
|
|
221
|
+
export const LegalEntity = z.object({
|
|
222
|
+
id: z.uuid(),
|
|
223
|
+
...ws,
|
|
224
|
+
name: z.string().min(1).max(200),
|
|
225
|
+
registrationNo: z.string().max(64).nullable(),
|
|
226
|
+
taxNo: z.string().max(64).nullable(),
|
|
227
|
+
country: CountryCode,
|
|
228
|
+
/** ISO 4217. */
|
|
229
|
+
currency: z.string().length(3).nullable(),
|
|
230
|
+
archivedAt: Timestamp.nullable(),
|
|
231
|
+
});
|
|
232
|
+
export const CostCenter = z.object({
|
|
233
|
+
id: z.uuid(),
|
|
234
|
+
...ws,
|
|
235
|
+
code: z.string().min(1).max(32),
|
|
236
|
+
name: z.string().min(1).max(160),
|
|
237
|
+
officeId: z.uuid().nullable(),
|
|
238
|
+
orgUnitId: z.uuid().nullable(),
|
|
239
|
+
legalEntityId: z.uuid().nullable(),
|
|
240
|
+
archivedAt: Timestamp.nullable(),
|
|
241
|
+
});
|
|
242
|
+
// =====================================================================================
|
|
243
|
+
// custom fields and documents
|
|
244
|
+
// =====================================================================================
|
|
245
|
+
export const FieldType = z.enum(['text', 'number', 'date', 'select', 'multi_select', 'boolean', 'url']);
|
|
246
|
+
export const CustomFieldDef = z.object({
|
|
247
|
+
id: z.uuid(),
|
|
248
|
+
...ws,
|
|
249
|
+
key: z
|
|
250
|
+
.string()
|
|
251
|
+
.min(1)
|
|
252
|
+
.max(48)
|
|
253
|
+
.regex(/^[a-z][a-z0-9_]*$/),
|
|
254
|
+
name: z.string().min(1).max(120),
|
|
255
|
+
type: FieldType,
|
|
256
|
+
options: z.array(z.object({ value: z.string(), label: z.string() })).nullable(),
|
|
257
|
+
required: z.boolean(),
|
|
258
|
+
/** Needs `hr.person.view_sensitive`, like a national identity number. */
|
|
259
|
+
sensitive: z.boolean(),
|
|
260
|
+
section: z.enum(['profile', 'employment', 'other']),
|
|
261
|
+
order: z.number().int(),
|
|
262
|
+
archivedAt: Timestamp.nullable(),
|
|
263
|
+
});
|
|
264
|
+
export const PersonDocument = z.object({
|
|
265
|
+
id: z.uuid(),
|
|
266
|
+
...ws,
|
|
267
|
+
personId: z.uuid(),
|
|
268
|
+
fileId: z.uuid(),
|
|
269
|
+
name: z.string().min(1).max(200),
|
|
270
|
+
kind: z.string().max(48),
|
|
271
|
+
issuedOn: IsoDate.nullable(),
|
|
272
|
+
expiresOn: IsoDate.nullable(),
|
|
273
|
+
uploadedBy: z.uuid().nullable(),
|
|
274
|
+
createdAt: Timestamp,
|
|
275
|
+
});
|
|
276
|
+
// =====================================================================================
|
|
277
|
+
// calendars
|
|
278
|
+
// =====================================================================================
|
|
279
|
+
export const CalendarDayKind = z.enum([
|
|
280
|
+
'public_holiday',
|
|
281
|
+
'religious',
|
|
282
|
+
'company_closure',
|
|
283
|
+
'half_day',
|
|
284
|
+
/** The country has a holiday and this company works it. `workingFraction` is 1. */
|
|
285
|
+
'working_override',
|
|
286
|
+
/** The Friday between a Thursday holiday and the weekend. */
|
|
287
|
+
'bridge',
|
|
288
|
+
]);
|
|
289
|
+
/** Which weekdays are worked, and how much of each. Iran is `{fri: 0}` with a half Thursday. */
|
|
290
|
+
export const WorkingWeek = z.object({
|
|
291
|
+
mon: z.number().min(0).max(1).default(1),
|
|
292
|
+
tue: z.number().min(0).max(1).default(1),
|
|
293
|
+
wed: z.number().min(0).max(1).default(1),
|
|
294
|
+
thu: z.number().min(0).max(1).default(1),
|
|
295
|
+
fri: z.number().min(0).max(1).default(1),
|
|
296
|
+
sat: z.number().min(0).max(1).default(0),
|
|
297
|
+
sun: z.number().min(0).max(1).default(0),
|
|
298
|
+
});
|
|
299
|
+
/**
|
|
300
|
+
* A set of non-working days, composed rather than copied.
|
|
301
|
+
*
|
|
302
|
+
* `extendsId` points at a country pack, and this calendar's own days sit on top: *"Amsterdam = the
|
|
303
|
+
* NL pack, plus our two company closures, minus the one we work through"*. Copying the pack into
|
|
304
|
+
* every office instead would mean a yearly pack refresh reconciling N copies against N sets of local
|
|
305
|
+
* edits, which is exactly the problem per-day `source` exists to avoid.
|
|
306
|
+
*/
|
|
307
|
+
export const Calendar = z.object({
|
|
308
|
+
id: z.uuid(),
|
|
309
|
+
...ws,
|
|
310
|
+
name: z.string().min(1).max(160),
|
|
311
|
+
extendsId: z.uuid().nullable(),
|
|
312
|
+
country: CountryCode.nullable(),
|
|
313
|
+
region: RegionCode.nullable(),
|
|
314
|
+
workingWeek: WorkingWeek,
|
|
315
|
+
source: z.enum(['pack', 'custom']),
|
|
316
|
+
packKey: z.string().max(32).nullable(),
|
|
317
|
+
packVersion: z.string().max(32).nullable(),
|
|
318
|
+
archivedAt: Timestamp.nullable(),
|
|
319
|
+
});
|
|
320
|
+
export const CalendarDay = z.object({
|
|
321
|
+
id: z.uuid(),
|
|
322
|
+
...ws,
|
|
323
|
+
calendarId: z.uuid(),
|
|
324
|
+
date: IsoDate,
|
|
325
|
+
kind: CalendarDayKind,
|
|
326
|
+
name: z.string().min(1).max(160),
|
|
327
|
+
/** 0 is a full day off, 0.5 a half day, 1 a day worked despite the pack saying otherwise. */
|
|
328
|
+
workingFraction: z.number().min(0).max(1),
|
|
329
|
+
/**
|
|
330
|
+
* Per **day**, not per calendar. A pack upgrade replaces `pack` rows and never touches `custom`
|
|
331
|
+
* ones — which is the entire reason HR can safely add their own holidays to a pack calendar.
|
|
332
|
+
*/
|
|
333
|
+
source: z.enum(['pack', 'custom']),
|
|
334
|
+
paid: z.boolean(),
|
|
335
|
+
note: z.string().max(500).nullable(),
|
|
336
|
+
});
|
|
337
|
+
/** A day as the composed calendar sees it, with where it came from. */
|
|
338
|
+
export const ResolvedCalendarDay = CalendarDay.extend({
|
|
339
|
+
/** The calendar in the `extends` chain that contributed this day. */
|
|
340
|
+
fromCalendarId: z.uuid(),
|
|
341
|
+
fromCalendarName: z.string(),
|
|
342
|
+
/** True when a nearer calendar overrode a day the base calendar had. */
|
|
343
|
+
overrides: z.boolean(),
|
|
344
|
+
});
|
|
345
|
+
// =====================================================================================
|
|
346
|
+
// resolution — the ladder, made inspectable
|
|
347
|
+
// =====================================================================================
|
|
348
|
+
export const ResolutionRung = z.enum([
|
|
349
|
+
'person',
|
|
350
|
+
'office',
|
|
351
|
+
'legal_entity',
|
|
352
|
+
'org_unit',
|
|
353
|
+
'position',
|
|
354
|
+
'workspace',
|
|
355
|
+
]);
|
|
356
|
+
/**
|
|
357
|
+
* What actually applies to one person on one date, and which rung answered.
|
|
358
|
+
*
|
|
359
|
+
* The ladder is `person → primary office → org unit → workspace`, nearest wins, and it decides both
|
|
360
|
+
* the calendar and every policy. Exposing *which rung answered* is not a nicety: "why does Ayşe have
|
|
361
|
+
* different holidays from her team" is the support question this module will be asked most, and
|
|
362
|
+
* without this it is answered with a database session.
|
|
363
|
+
*/
|
|
364
|
+
export const PersonResolution = z.object({
|
|
365
|
+
personId: z.uuid(),
|
|
366
|
+
on: IsoDate,
|
|
367
|
+
primaryOfficeId: z.uuid().nullable(),
|
|
368
|
+
primaryOfficeName: z.string().nullable(),
|
|
369
|
+
otherOfficeIds: z.array(z.uuid()),
|
|
370
|
+
country: CountryCode.nullable(),
|
|
371
|
+
timezone: TimeZone,
|
|
372
|
+
timezoneFrom: ResolutionRung,
|
|
373
|
+
calendarId: z.uuid().nullable(),
|
|
374
|
+
calendarFrom: ResolutionRung.nullable(),
|
|
375
|
+
workingWeek: WorkingWeek,
|
|
376
|
+
legalEntityId: z.uuid().nullable(),
|
|
377
|
+
orgUnitId: z.uuid().nullable(),
|
|
378
|
+
orgUnitPath: z.string().nullable(),
|
|
379
|
+
managerPersonId: z.uuid().nullable(),
|
|
380
|
+
});
|
|
381
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/contract/models.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Who may see and change what.
|
|
3
|
+
*
|
|
4
|
+
* HR holds the most sensitive data in the product, so the split is finer than other modules':
|
|
5
|
+
*
|
|
6
|
+
* - **Your own record is not a permission.** Everybody reads and edits their own profile; there is
|
|
7
|
+
* no `hr.person.view_self` because a permission somebody can never lack is noise in the role
|
|
8
|
+
* editor. The router enforces it by identity instead.
|
|
9
|
+
* - **Three widths of "other people".** `view_team` is the org-unit subtree you head plus your direct
|
|
10
|
+
* reports; `view_office` is everybody assigned to an office you administer, which is what a local
|
|
11
|
+
* HR person in Amsterdam holds; `view_all` is the workspace. None of them implies the others, so a
|
|
12
|
+
* country HR manager does not silently become a global one.
|
|
13
|
+
* - **Sensitive fields are their own pair.** A directory is `hr.person.view`. A national identity
|
|
14
|
+
* number, a birth date and a bank account are `hr.person.view_sensitive`, which nobody holds by
|
|
15
|
+
* default — not even an owner's role, though an owner passes every check anyway.
|
|
16
|
+
*
|
|
17
|
+
* `scope: 'object'` on the team and office reads is deliberate: `PermissionScopeKind` has no
|
|
18
|
+
* `org_unit` or `office` member, and adding one is a change to `@kernhq/contracts` that would have
|
|
19
|
+
* to roll through the kernel and core. Binding at object scope with the unit or office id gets the
|
|
20
|
+
* same result today; `HrAccessService` is what resolves it.
|
|
21
|
+
*/
|
|
22
|
+
export declare const hrPermissions: readonly [{
|
|
23
|
+
readonly key: "hr.person.view";
|
|
24
|
+
readonly label: "View the staff directory";
|
|
25
|
+
readonly scope: "workspace";
|
|
26
|
+
readonly defaultRoles: ["owner", "admin", "member"];
|
|
27
|
+
readonly dangerous: false;
|
|
28
|
+
}, {
|
|
29
|
+
readonly key: "hr.person.view_team";
|
|
30
|
+
readonly label: "View your team's records";
|
|
31
|
+
readonly scope: "object";
|
|
32
|
+
readonly defaultRoles: ["owner", "admin"];
|
|
33
|
+
readonly dangerous: false;
|
|
34
|
+
}, {
|
|
35
|
+
readonly key: "hr.person.view_office";
|
|
36
|
+
readonly label: "View an office's records";
|
|
37
|
+
readonly scope: "object";
|
|
38
|
+
readonly defaultRoles: ["owner", "admin"];
|
|
39
|
+
readonly dangerous: false;
|
|
40
|
+
}, {
|
|
41
|
+
readonly key: "hr.person.view_all";
|
|
42
|
+
readonly label: "View every record in the workspace";
|
|
43
|
+
readonly scope: "workspace";
|
|
44
|
+
readonly defaultRoles: ["owner", "admin"];
|
|
45
|
+
readonly dangerous: false;
|
|
46
|
+
}, {
|
|
47
|
+
readonly key: "hr.person.manage";
|
|
48
|
+
readonly label: "Add, edit and offboard people";
|
|
49
|
+
readonly scope: "workspace";
|
|
50
|
+
readonly defaultRoles: ["owner", "admin"];
|
|
51
|
+
readonly dangerous: false;
|
|
52
|
+
}, {
|
|
53
|
+
readonly key: "hr.person.view_sensitive";
|
|
54
|
+
readonly label: "View identity, birth date and bank details";
|
|
55
|
+
readonly description: "Personal data protected under GDPR and KVKK. Grant to HR only.";
|
|
56
|
+
readonly scope: "workspace";
|
|
57
|
+
readonly defaultRoles: [];
|
|
58
|
+
readonly dangerous: true;
|
|
59
|
+
}, {
|
|
60
|
+
readonly key: "hr.person.manage_sensitive";
|
|
61
|
+
readonly label: "Edit identity, birth date and bank details";
|
|
62
|
+
readonly scope: "workspace";
|
|
63
|
+
readonly defaultRoles: [];
|
|
64
|
+
readonly dangerous: true;
|
|
65
|
+
}, {
|
|
66
|
+
readonly key: "hr.employment.view";
|
|
67
|
+
readonly label: "View employment records and history";
|
|
68
|
+
readonly scope: "workspace";
|
|
69
|
+
readonly defaultRoles: ["owner", "admin"];
|
|
70
|
+
readonly dangerous: false;
|
|
71
|
+
}, {
|
|
72
|
+
readonly key: "hr.employment.manage";
|
|
73
|
+
readonly label: "Change job, manager, department or hours";
|
|
74
|
+
readonly scope: "workspace";
|
|
75
|
+
readonly defaultRoles: ["owner", "admin"];
|
|
76
|
+
readonly dangerous: true;
|
|
77
|
+
}, {
|
|
78
|
+
readonly key: "hr.org.view";
|
|
79
|
+
readonly label: "View the org chart, departments and positions";
|
|
80
|
+
readonly scope: "workspace";
|
|
81
|
+
readonly defaultRoles: ["owner", "admin", "member"];
|
|
82
|
+
readonly dangerous: false;
|
|
83
|
+
}, {
|
|
84
|
+
readonly key: "hr.org.manage";
|
|
85
|
+
readonly label: "Change departments, positions and reporting lines";
|
|
86
|
+
readonly scope: "workspace";
|
|
87
|
+
readonly defaultRoles: ["owner", "admin"];
|
|
88
|
+
readonly dangerous: false;
|
|
89
|
+
}, {
|
|
90
|
+
readonly key: "hr.office.view";
|
|
91
|
+
readonly label: "View offices";
|
|
92
|
+
readonly scope: "workspace";
|
|
93
|
+
readonly defaultRoles: ["owner", "admin", "member"];
|
|
94
|
+
readonly dangerous: false;
|
|
95
|
+
}, {
|
|
96
|
+
readonly key: "hr.office.manage";
|
|
97
|
+
readonly label: "Add and edit offices";
|
|
98
|
+
readonly scope: "workspace";
|
|
99
|
+
readonly defaultRoles: ["owner", "admin"];
|
|
100
|
+
readonly dangerous: false;
|
|
101
|
+
}, {
|
|
102
|
+
readonly key: "hr.office.assign";
|
|
103
|
+
readonly label: "Assign people to offices";
|
|
104
|
+
readonly scope: "object";
|
|
105
|
+
readonly defaultRoles: ["owner", "admin"];
|
|
106
|
+
readonly dangerous: false;
|
|
107
|
+
}, {
|
|
108
|
+
readonly key: "hr.entity.view";
|
|
109
|
+
readonly label: "View legal entities and cost centres";
|
|
110
|
+
readonly scope: "workspace";
|
|
111
|
+
readonly defaultRoles: ["owner", "admin"];
|
|
112
|
+
readonly dangerous: false;
|
|
113
|
+
}, {
|
|
114
|
+
readonly key: "hr.entity.manage";
|
|
115
|
+
readonly label: "Add and edit legal entities and cost centres";
|
|
116
|
+
readonly scope: "workspace";
|
|
117
|
+
readonly defaultRoles: ["owner"];
|
|
118
|
+
readonly dangerous: false;
|
|
119
|
+
}, {
|
|
120
|
+
readonly key: "hr.calendar.view";
|
|
121
|
+
readonly label: "View holiday calendars";
|
|
122
|
+
readonly scope: "workspace";
|
|
123
|
+
readonly defaultRoles: ["owner", "admin", "member", "guest"];
|
|
124
|
+
readonly dangerous: false;
|
|
125
|
+
}, {
|
|
126
|
+
readonly key: "hr.calendar.manage";
|
|
127
|
+
readonly label: "Add and edit holidays and closures";
|
|
128
|
+
readonly scope: "workspace";
|
|
129
|
+
readonly defaultRoles: ["owner", "admin"];
|
|
130
|
+
readonly dangerous: false;
|
|
131
|
+
}, {
|
|
132
|
+
readonly key: "hr.document.view";
|
|
133
|
+
readonly label: "View employee documents";
|
|
134
|
+
readonly scope: "workspace";
|
|
135
|
+
readonly defaultRoles: [];
|
|
136
|
+
readonly dangerous: true;
|
|
137
|
+
}, {
|
|
138
|
+
readonly key: "hr.document.manage";
|
|
139
|
+
readonly label: "Attach and remove employee documents";
|
|
140
|
+
readonly scope: "workspace";
|
|
141
|
+
readonly defaultRoles: [];
|
|
142
|
+
readonly dangerous: true;
|
|
143
|
+
}, {
|
|
144
|
+
readonly key: "hr.field.manage";
|
|
145
|
+
readonly label: "Add and edit custom fields";
|
|
146
|
+
readonly scope: "workspace";
|
|
147
|
+
readonly defaultRoles: ["owner", "admin"];
|
|
148
|
+
readonly dangerous: false;
|
|
149
|
+
}];
|
|
150
|
+
/** The keys, so nothing gates on a string somebody retyped. */
|
|
151
|
+
export declare const HR_PERMISSIONS: {
|
|
152
|
+
readonly personView: "hr.person.view";
|
|
153
|
+
readonly personViewTeam: "hr.person.view_team";
|
|
154
|
+
readonly personViewOffice: "hr.person.view_office";
|
|
155
|
+
readonly personViewAll: "hr.person.view_all";
|
|
156
|
+
readonly personManage: "hr.person.manage";
|
|
157
|
+
readonly personViewSensitive: "hr.person.view_sensitive";
|
|
158
|
+
readonly personManageSensitive: "hr.person.manage_sensitive";
|
|
159
|
+
readonly employmentView: "hr.employment.view";
|
|
160
|
+
readonly employmentManage: "hr.employment.manage";
|
|
161
|
+
readonly orgView: "hr.org.view";
|
|
162
|
+
readonly orgManage: "hr.org.manage";
|
|
163
|
+
readonly officeView: "hr.office.view";
|
|
164
|
+
readonly officeManage: "hr.office.manage";
|
|
165
|
+
readonly officeAssign: "hr.office.assign";
|
|
166
|
+
readonly entityView: "hr.entity.view";
|
|
167
|
+
readonly entityManage: "hr.entity.manage";
|
|
168
|
+
readonly calendarView: "hr.calendar.view";
|
|
169
|
+
readonly calendarManage: "hr.calendar.manage";
|
|
170
|
+
readonly documentView: "hr.document.view";
|
|
171
|
+
readonly documentManage: "hr.document.manage";
|
|
172
|
+
readonly fieldManage: "hr.field.manage";
|
|
173
|
+
};
|
|
174
|
+
//# sourceMappingURL=permissions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/contract/permissions.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwKxB,CAAA;AAEF,+DAA+D;AAC/D,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;CAsBjB,CAAA"}
|