@kernhq/module-hr 0.11.0 → 0.13.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.
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/contract/capabilities.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,cAAc;;;;;;;;GAyGzB,CAAA;AAEF,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAA;AAElE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,GAAI,IAAI,MAAM,WAAmB,CAAA;AAChE,eAAO,MAAM,wBAAwB,GAAI,IAAI,MAAM,WAAwB,CAAA;AAE3E;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAmFpE,CAAA"}
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/contract/capabilities.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,cAAc;;;;;;;;GAiGzB,CAAA;AAEF,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAA;AAElE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,GAAI,IAAI,MAAM,WAAmB,CAAA;AAChE,eAAO,MAAM,wBAAwB,GAAI,IAAI,MAAM,WAAwB,CAAA;AAE3E;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAmFpE,CAAA"}
@@ -111,14 +111,6 @@ export const hrCapabilities = defineCapabilities([
111
111
  defaultEnabled: false,
112
112
  level: 1,
113
113
  },
114
- {
115
- id: 'overtime',
116
- label: 'Overtime',
117
- description: 'Detect and approve time worked beyond the schedule',
118
- dependsOn: ['attendance'],
119
- defaultEnabled: false,
120
- level: 2,
121
- },
122
114
  {
123
115
  id: 'documents',
124
116
  label: 'Employee documents',
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/contract/capabilities.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/contract/capabilities.ts"],"names":[],"mappings":"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"}
@@ -202,18 +202,6 @@ export declare const hrPermissions: readonly [{
202
202
  readonly scope: "workspace";
203
203
  readonly defaultRoles: ["owner", "admin"];
204
204
  readonly dangerous: true;
205
- }, {
206
- readonly key: "hr.overtime.view";
207
- readonly label: "View overtime";
208
- readonly scope: "workspace";
209
- readonly defaultRoles: ["owner", "admin"];
210
- readonly dangerous: false;
211
- }, {
212
- readonly key: "hr.overtime.manage";
213
- readonly label: "Approve and adjust overtime";
214
- readonly scope: "workspace";
215
- readonly defaultRoles: ["owner", "admin"];
216
- readonly dangerous: false;
217
205
  }, {
218
206
  readonly key: "hr.policy.view";
219
207
  readonly label: "View accrual, overtime and rounding policies";
@@ -286,8 +274,6 @@ export declare const HR_PERMISSIONS: {
286
274
  readonly attendanceView: "hr.attendance.view";
287
275
  readonly attendanceViewTeam: "hr.attendance.view_team";
288
276
  readonly attendanceManage: "hr.attendance.manage";
289
- readonly overtimeView: "hr.overtime.view";
290
- readonly overtimeManage: "hr.overtime.manage";
291
277
  readonly policyView: "hr.policy.view";
292
278
  readonly policyManage: "hr.policy.manage";
293
279
  readonly periodManage: "hr.period.manage";
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/contract/permissions.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6SxB,CAAA;AAEF,+DAA+D;AAC/D,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCjB,CAAA"}
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/contract/permissions.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmSxB,CAAA;AAEF,+DAA+D;AAC/D,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCjB,CAAA"}
@@ -249,20 +249,10 @@ export const hrPermissions = definePermissions([
249
249
  defaultRoles: ['owner', 'admin'],
250
250
  dangerous: true,
251
251
  },
252
- {
253
- key: 'hr.overtime.view',
254
- label: 'View overtime',
255
- scope: 'workspace',
256
- defaultRoles: ['owner', 'admin'],
257
- dangerous: false,
258
- },
259
- {
260
- key: 'hr.overtime.manage',
261
- label: 'Approve and adjust overtime',
262
- scope: 'workspace',
263
- defaultRoles: ['owner', 'admin'],
264
- dangerous: false,
265
- },
252
+ // No `hr.overtime.*` here. Overtime is detected, stored and shown as part of attendance, and
253
+ // nothing asks a question these keys could answer — a role checkbox that gates nothing teaches an
254
+ // administrator the same lesson a dead capability switch does. They come back with the approval
255
+ // flow that needs them.
266
256
  // ---------------------------------------------------------------- policies and periods
267
257
  {
268
258
  key: 'hr.policy.view',
@@ -344,8 +334,6 @@ export const HR_PERMISSIONS = {
344
334
  attendanceView: 'hr.attendance.view',
345
335
  attendanceViewTeam: 'hr.attendance.view_team',
346
336
  attendanceManage: 'hr.attendance.manage',
347
- overtimeView: 'hr.overtime.view',
348
- overtimeManage: 'hr.overtime.manage',
349
337
  policyView: 'hr.policy.view',
350
338
  policyManage: 'hr.policy.manage',
351
339
  periodManage: 'hr.period.manage',
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/contract/permissions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/contract/permissions.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kernhq/module-hr",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "description": "Kern HR module: people, offices, org chart, calendars",
5
5
  "license": "AGPL-3.0-only",
6
6
  "type": "module",
@@ -25,7 +25,6 @@ export const HR_CAPABILITIES = {
25
25
  periods: 'periods',
26
26
  approvals: 'approvals',
27
27
  attendance: 'attendance',
28
- overtime: 'overtime',
29
28
  } as const
30
29
 
31
30
  export type HrCapabilityId = (typeof HR_CAPABILITIES)[keyof typeof HR_CAPABILITIES]
@@ -469,8 +469,6 @@ export const en: Record<string, Message> = {
469
469
  'hr.cap_legal_entities_desc': 'Several employing companies, for a group operating across borders',
470
470
  'hr.cap_offices': 'Offices',
471
471
  'hr.cap_offices_desc': 'More than one place of work, each with its own country, timezone and holidays',
472
- 'hr.cap_overtime': 'Overtime',
473
- 'hr.cap_overtime_desc': 'Detect and approve time worked beyond the schedule',
474
472
  'hr.cap_periods': 'Payroll periods',
475
473
  'hr.cap_periods_desc': 'Close a month so a filed payroll cannot move underneath it',
476
474
  'hr.capabilities_desc':
@@ -549,7 +547,6 @@ export const en: Record<string, Message> = {
549
547
  'hr.chain_perm_attendance': 'Manage attendance',
550
548
  'hr.chain_perm_leave': 'Manage time off',
551
549
  'hr.chain_perm_office': 'Manage offices',
552
- 'hr.chain_perm_overtime': 'Manage overtime',
553
550
  'hr.chain_perm_person': 'Manage people',
554
551
  'hr.chain_remove_approver': 'Remove this approver',
555
552
  'hr.chain_remove_step': 'Remove this step',
@@ -1857,8 +1854,6 @@ export const ar: Record<string, Message> = {
1857
1854
  'hr.cap_legal_entities_desc': 'عدة شركات موظِّفة، لمجموعة تعمل عبر الحدود',
1858
1855
  'hr.cap_offices': 'المكاتب',
1859
1856
  'hr.cap_offices_desc': 'أكثر من مكان عمل، لكلٍّ منه بلده ومنطقته الزمنية وعطلاته',
1860
- 'hr.cap_overtime': 'العمل الإضافي',
1861
- 'hr.cap_overtime_desc': 'رصد العمل خارج المناوبة والموافقة عليه',
1862
1857
  'hr.cap_periods': 'فترات الرواتب',
1863
1858
  'hr.cap_periods_desc': 'إغلاق الشهر حتى لا يتغيّر كشف رواتب مُعتمد بعد اعتماده',
1864
1859
  'hr.capabilities_desc':
@@ -1933,7 +1928,6 @@ export const ar: Record<string, Message> = {
1933
1928
  'hr.chain_perm_attendance': 'إدارة الحضور',
1934
1929
  'hr.chain_perm_leave': 'إدارة الإجازات',
1935
1930
  'hr.chain_perm_office': 'إدارة المكاتب',
1936
- 'hr.chain_perm_overtime': 'إدارة العمل الإضافي',
1937
1931
  'hr.chain_perm_person': 'إدارة الأفراد',
1938
1932
  'hr.chain_remove_approver': 'إزالة هذا الموقّع',
1939
1933
  'hr.chain_remove_step': 'إزالة هذه الخطوة',
@@ -3271,8 +3265,6 @@ export const de: Record<string, Message> = {
3271
3265
  'hr.cap_offices': 'Standorte',
3272
3266
  'hr.cap_offices_desc':
3273
3267
  'Mehr als ein Arbeitsort, jeder mit eigenem Land, eigener Zeitzone und eigenen Feiertagen',
3274
- 'hr.cap_overtime': 'Überstunden',
3275
- 'hr.cap_overtime_desc': 'Über die Arbeitszeit hinaus geleistete Zeit erkennen und freigeben',
3276
3268
  'hr.cap_periods': 'Abrechnungszeiträume',
3277
3269
  'hr.cap_periods_desc':
3278
3270
  'Einen Monat schließen, damit eine eingereichte Abrechnung sich nicht nachträglich verschiebt',
@@ -3355,7 +3347,6 @@ export const de: Record<string, Message> = {
3355
3347
  'hr.chain_perm_attendance': 'Zeiterfassung verwalten',
3356
3348
  'hr.chain_perm_leave': 'Abwesenheit verwalten',
3357
3349
  'hr.chain_perm_office': 'Standorte verwalten',
3358
- 'hr.chain_perm_overtime': 'Überstunden verwalten',
3359
3350
  'hr.chain_perm_person': 'Personen verwalten',
3360
3351
  'hr.chain_remove_approver': 'Diese freigebende Person entfernen',
3361
3352
  'hr.chain_remove_step': 'Diesen Schritt entfernen',
@@ -4607,8 +4598,6 @@ export const fa: Record<string, Message> = {
4607
4598
  'hr.cap_legal_entities_desc': 'چند شرکت کارفرما، برای گروهی که در چند کشور فعالیت می‌کند',
4608
4599
  'hr.cap_offices': 'دفاتر',
4609
4600
  'hr.cap_offices_desc': 'بیش از یک محل کار، هرکدام با کشور، منطقهٔ زمانی و تعطیلات خودش',
4610
- 'hr.cap_overtime': 'اضافه‌کاری',
4611
- 'hr.cap_overtime_desc': 'تشخیص و تأیید کارکرد بیش از شیفت',
4612
4601
  'hr.cap_periods': 'دوره‌های حقوق و دستمزد',
4613
4602
  'hr.cap_periods_desc': 'بستن یک ماه تا حقوق ثبت‌شده دیگر تغییر نکند',
4614
4603
  'hr.capabilities_desc':
@@ -4687,7 +4676,6 @@ export const fa: Record<string, Message> = {
4687
4676
  'hr.chain_perm_attendance': 'مدیریت حضور',
4688
4677
  'hr.chain_perm_leave': 'مدیریت مرخصی',
4689
4678
  'hr.chain_perm_office': 'مدیریت دفترها',
4690
- 'hr.chain_perm_overtime': 'مدیریت اضافه‌کار',
4691
4679
  'hr.chain_perm_person': 'مدیریت افراد',
4692
4680
  'hr.chain_remove_approver': 'برداشتن این تأییدکننده',
4693
4681
  'hr.chain_remove_step': 'برداشتن این مرحله',
@@ -5911,8 +5899,6 @@ export const tr: Record<string, Message> = {
5911
5899
  'hr.cap_legal_entities_desc': 'Sınır ötesinde faaliyet gösteren bir grup için birden fazla işveren şirket',
5912
5900
  'hr.cap_offices': 'Ofisler',
5913
5901
  'hr.cap_offices_desc': 'Birden fazla çalışma yeri; her biri kendi ülkesi, saat dilimi ve tatilleriyle',
5914
- 'hr.cap_overtime': 'Fazla mesai',
5915
- 'hr.cap_overtime_desc': 'Vardiyanın ötesinde çalışılan süreyi bulun ve onaylayın',
5916
5902
  'hr.cap_periods': 'Bordro dönemleri',
5917
5903
  'hr.cap_periods_desc': 'Bir ayı kapatın; böylece verilmiş bordro sonradan kaymaz',
5918
5904
  'hr.capabilities_desc':
@@ -5990,7 +5976,6 @@ export const tr: Record<string, Message> = {
5990
5976
  'hr.chain_perm_attendance': 'Devamı yönetme',
5991
5977
  'hr.chain_perm_leave': 'İzinleri yönetme',
5992
5978
  'hr.chain_perm_office': 'Ofisleri yönetme',
5993
- 'hr.chain_perm_overtime': 'Fazla mesaiyi yönetme',
5994
5979
  'hr.chain_perm_person': 'Personeli yönetme',
5995
5980
  'hr.chain_remove_approver': 'Bu onaylayanı kaldır',
5996
5981
  'hr.chain_remove_step': 'Bu adımı kaldır',
@@ -32,7 +32,7 @@ import type {
32
32
  ResolvedCalendarDay,
33
33
  WorkingWeek,
34
34
  } from '../contract/models.js'
35
- import type { Period } from '../contract/policies.js'
35
+ import type { Period, Policy, PolicyAssignment, PolicySubjectKind } from '../contract/policies.js'
36
36
 
37
37
  /**
38
38
  * A refusal the client cannot tell from the server's.
@@ -254,6 +254,7 @@ export function createMockHrApi() {
254
254
  {
255
255
  id: id('d001'),
256
256
  displayName: 'Ayşe Yılmaz',
257
+ hiredOn: day(-400),
257
258
  workEmail: 'ayse@example.test',
258
259
  status: 'active',
259
260
  timezone: 'Europe/Istanbul',
@@ -262,6 +263,7 @@ export function createMockHrApi() {
262
263
  {
263
264
  id: id('d002'),
264
265
  displayName: 'Sanne de Vries',
266
+ hiredOn: day(-300),
265
267
  workEmail: 'sanne@example.test',
266
268
  status: 'active',
267
269
  timezone: 'Europe/Amsterdam',
@@ -270,6 +272,7 @@ export function createMockHrApi() {
270
272
  {
271
273
  id: id('d003'),
272
274
  displayName: 'Mehmet Kaya',
275
+ hiredOn: day(-2000),
273
276
  workEmail: 'mehmet@example.test',
274
277
  status: 'on_leave',
275
278
  timezone: 'Europe/Istanbul',
@@ -278,6 +281,7 @@ export function createMockHrApi() {
278
281
  {
279
282
  id: id('d004'),
280
283
  displayName: 'Jonas Weber',
284
+ hiredOn: day(-80),
281
285
  workEmail: 'jonas@example.test',
282
286
  status: 'active',
283
287
  timezone: 'Europe/Berlin',
@@ -369,7 +373,6 @@ export function createMockHrApi() {
369
373
  personalEmail: null,
370
374
  phone: null,
371
375
  photoFileId: null,
372
- hiredOn: day(-400),
373
376
  terminatedOn: null,
374
377
  custom: {},
375
378
  createdAt: iso(400 * 86_400_000),
@@ -1149,6 +1152,270 @@ export function createMockHrApi() {
1149
1152
  return weekday !== 'sat' && weekday !== 'sun' && date <= day(0)
1150
1153
  }).length
1151
1154
 
1155
+ // ---------------------------------------------------------------- accrual policies
1156
+
1157
+ /** The ladder made explicit, straight from `SUBJECT_PRIORITY` in the contract. */
1158
+ const PRIORITY: Record<PolicySubjectKind, number> = {
1159
+ person: 100,
1160
+ office: 80,
1161
+ legal_entity: 60,
1162
+ org_unit: 40,
1163
+ position: 30,
1164
+ workspace: 0,
1165
+ }
1166
+
1167
+ /**
1168
+ * Two policies that differ in more than their name.
1169
+ *
1170
+ * A list whose column reads the same sentence twice demonstrates nothing — these take different
1171
+ * branches of the evaluator: one accrues monthly with a waiting period for joiners, the other on
1172
+ * the employee's own anniversary with seniority tiers.
1173
+ */
1174
+ const policies: Row<Policy>[] = [
1175
+ {
1176
+ id: id('b011'),
1177
+ kind: 'accrual',
1178
+ name: 'Monthly accrual',
1179
+ config: {
1180
+ frequency: 'monthly',
1181
+ daysPerYear: 20,
1182
+ minutesPerDay: 480,
1183
+ seniorityTiers: [],
1184
+ waitingPeriodMonths: 3,
1185
+ calendar: 'gregorian',
1186
+ roundToMinutes: 30,
1187
+ leaveTypeKey: 'annual',
1188
+ },
1189
+ effectiveFrom: `${YEAR}-01-01`,
1190
+ effectiveTo: null,
1191
+ source: 'custom',
1192
+ packKey: null,
1193
+ configHash: 'a1b2c3d4',
1194
+ archivedAt: null,
1195
+ },
1196
+ {
1197
+ id: id('b012'),
1198
+ kind: 'accrual',
1199
+ name: 'Anniversary accrual, with seniority',
1200
+ config: {
1201
+ frequency: 'anniversary',
1202
+ daysPerYear: 22,
1203
+ minutesPerDay: 480,
1204
+ seniorityTiers: [
1205
+ { afterYears: 5, daysPerYear: 26 },
1206
+ { afterYears: 10, daysPerYear: 30 },
1207
+ ],
1208
+ waitingPeriodMonths: 0,
1209
+ calendar: 'gregorian',
1210
+ roundToMinutes: 0,
1211
+ leaveTypeKey: 'annual',
1212
+ },
1213
+ effectiveFrom: `${YEAR}-01-01`,
1214
+ effectiveTo: null,
1215
+ source: 'custom',
1216
+ packKey: null,
1217
+ configHash: 'e5f6a7b8',
1218
+ archivedAt: null,
1219
+ },
1220
+ ]
1221
+
1222
+ /**
1223
+ * Two rungs, on purpose.
1224
+ *
1225
+ * The screen's copy says the nearest subject wins; with everything assigned at one rung nothing on
1226
+ * screen tests that claim. The workspace-wide monthly policy is what most people get, and Sanne
1227
+ * has the anniversary one at the `person` rung — which must visibly beat the office below it.
1228
+ */
1229
+ const policyAssignments: Row<PolicyAssignment>[] = [
1230
+ {
1231
+ id: id('b0a1'),
1232
+ policyId: id('b011'),
1233
+ subjectKind: 'workspace',
1234
+ subjectId: null,
1235
+ effectiveFrom: `${YEAR}-01-01`,
1236
+ effectiveTo: null,
1237
+ priority: PRIORITY.workspace,
1238
+ },
1239
+ {
1240
+ id: id('b0a2'),
1241
+ policyId: id('b012'),
1242
+ subjectKind: 'office',
1243
+ subjectId: id('e002'),
1244
+ effectiveFrom: `${YEAR}-01-01`,
1245
+ effectiveTo: null,
1246
+ priority: PRIORITY.office,
1247
+ },
1248
+ // Mehmet has been here five years, so the tier above `afterYears: 5` is the one that answers
1249
+ // for him — without somebody long-serving the seniority branch of the evaluator never fires and
1250
+ // the second policy's whole reason for existing goes untested.
1251
+ {
1252
+ id: id('b0a4'),
1253
+ policyId: id('b012'),
1254
+ subjectKind: 'person',
1255
+ subjectId: people[2]!.id,
1256
+ effectiveFrom: `${YEAR}-01-01`,
1257
+ effectiveTo: null,
1258
+ priority: PRIORITY.person,
1259
+ },
1260
+ {
1261
+ id: id('b0a3'),
1262
+ policyId: id('b012'),
1263
+ subjectKind: 'person',
1264
+ subjectId: people[1]!.id,
1265
+ effectiveFrom: `${YEAR}-01-01`,
1266
+ effectiveTo: null,
1267
+ priority: PRIORITY.person,
1268
+ },
1269
+ ]
1270
+
1271
+ const assignmentsOf = (policyId: string) => policyAssignments.filter((a) => a.policyId === policyId)
1272
+
1273
+ /**
1274
+ * Which policy applies to somebody, and which rung answered.
1275
+ *
1276
+ * Nearest wins, by the priority the contract publishes — so a policy given to one person beats the
1277
+ * one on their office, which beats their legal entity, their department, their position, and
1278
+ * finally the whole workspace. This is the claim the screen's copy makes, so it has to be the
1279
+ * claim the fixture keeps.
1280
+ */
1281
+ function resolvePolicyFor(personId: string) {
1282
+ const officeId = primaryOfficeId(personId)
1283
+ const job = employments.find((e) => e.personId === personId && e.effectiveTo === null)
1284
+ const matches = (a: Row<PolicyAssignment>) => {
1285
+ switch (a.subjectKind) {
1286
+ case 'person':
1287
+ return a.subjectId === personId
1288
+ case 'office':
1289
+ return a.subjectId === officeId
1290
+ case 'legal_entity':
1291
+ return a.subjectId === job?.legalEntityId
1292
+ case 'org_unit':
1293
+ return a.subjectId === job?.orgUnitId
1294
+ case 'position':
1295
+ return a.subjectId === job?.positionId
1296
+ default:
1297
+ return true
1298
+ }
1299
+ }
1300
+ const best = policyAssignments
1301
+ .filter((a) => {
1302
+ if (a.effectiveTo !== null) return false
1303
+ const policy = policies.find((x) => x.id === a.policyId)
1304
+ return Boolean(policy && policy.archivedAt === null) && matches(a)
1305
+ })
1306
+ .sort((a, b) => b.priority - a.priority)[0]
1307
+ const policy = best ? policies.find((x) => x.id === best.policyId) : undefined
1308
+ return best && policy ? { assignment: best, policy } : null
1309
+ }
1310
+
1311
+ const wholeMonthsBetween = (from: string, to: string) => {
1312
+ const a = new Date(`${from}T00:00:00Z`)
1313
+ const b = new Date(`${to}T00:00:00Z`)
1314
+ let months = (b.getUTCFullYear() - a.getUTCFullYear()) * 12 + (b.getUTCMonth() - a.getUTCMonth())
1315
+ if (b.getUTCDate() < a.getUTCDate()) months -= 1
1316
+ return months
1317
+ }
1318
+
1319
+ /**
1320
+ * What a run would credit — computed, never written.
1321
+ *
1322
+ * `preview` and `run` share this function for the reason the contract gives: a preview computed
1323
+ * differently from the thing it previews is a preview that eventually lies. Only `run` writes,
1324
+ * and it writes from these rows.
1325
+ */
1326
+ function accrualRows(from: string, to: string, onlyPersonId?: string) {
1327
+ const rows: Array<{
1328
+ personId: string
1329
+ displayName: string
1330
+ leaveTypeId: string
1331
+ leaveTypeName: string
1332
+ minutes: number
1333
+ days: number
1334
+ reason: string
1335
+ alreadyAccrued: boolean
1336
+ }> = []
1337
+ const skipped: Array<{ personId: string; displayName: string; reason: string }> = []
1338
+
1339
+ for (const who of people) {
1340
+ if (onlyPersonId && who.id !== onlyPersonId) continue
1341
+ const skip = (reason: string) =>
1342
+ skipped.push({ personId: who.id, displayName: who.displayName, reason })
1343
+
1344
+ if (who.status === 'terminated') {
1345
+ skip('No longer employed')
1346
+ continue
1347
+ }
1348
+ const applicable = resolvePolicyFor(who.id)
1349
+ if (!applicable) {
1350
+ skip('No accrual policy applies')
1351
+ continue
1352
+ }
1353
+ const config = applicable.policy.config as {
1354
+ frequency: string
1355
+ daysPerYear: number
1356
+ minutesPerDay: number
1357
+ seniorityTiers: Array<{ afterYears: number; daysPerYear: number }>
1358
+ waitingPeriodMonths: number
1359
+ roundToMinutes: number
1360
+ leaveTypeKey: string
1361
+ }
1362
+ const served = wholeMonthsBetween(who.hiredOn, from)
1363
+ if (served < config.waitingPeriodMonths) {
1364
+ skip(`Within the ${config.waitingPeriodMonths}-month waiting period — ${served} served`)
1365
+ continue
1366
+ }
1367
+ const leaveType = leaveTypes.find((lt) => lt.key === config.leaveTypeKey && lt.archivedAt === null)
1368
+ if (!leaveType) {
1369
+ skip(`No leave type keyed "${config.leaveTypeKey}"`)
1370
+ continue
1371
+ }
1372
+
1373
+ // Most senior tier reached wins, whatever order they are written in.
1374
+ const years = Math.floor(served / 12)
1375
+ const tier = [...(config.seniorityTiers ?? [])]
1376
+ .filter((t) => years >= t.afterYears)
1377
+ .sort((a, b) => b.afterYears - a.afterYears)[0]
1378
+ const perYear = tier?.daysPerYear ?? config.daysPerYear
1379
+
1380
+ let minutes = Math.round((perYear * config.minutesPerDay) / 12)
1381
+ if (config.roundToMinutes > 0) {
1382
+ minutes = Math.round(minutes / config.roundToMinutes) * config.roundToMinutes
1383
+ }
1384
+ const alreadyAccrued = ledger.some(
1385
+ (e) =>
1386
+ e.personId === who.id &&
1387
+ e.leaveTypeId === leaveType.id &&
1388
+ e.kind === 'accrual' &&
1389
+ e.effectiveOn >= from &&
1390
+ e.effectiveOn <= to,
1391
+ )
1392
+ const basis = tier
1393
+ ? `${perYear} days a year after ${tier.afterYears} years' service`
1394
+ : `${perYear} days a year`
1395
+ rows.push({
1396
+ personId: who.id,
1397
+ displayName: who.displayName,
1398
+ leaveTypeId: leaveType.id,
1399
+ leaveTypeName: leaveType.name,
1400
+ minutes,
1401
+ days: Math.round((minutes / config.minutesPerDay) * 100) / 100,
1402
+ reason: alreadyAccrued
1403
+ ? `${basis}, ${config.frequency} — already credited for this period`
1404
+ : `${basis}, ${config.frequency}`,
1405
+ alreadyAccrued,
1406
+ })
1407
+ }
1408
+
1409
+ return {
1410
+ periodFrom: from,
1411
+ periodTo: to,
1412
+ rows,
1413
+ // What the run would actually add: a row already credited contributes nothing to it.
1414
+ totalMinutes: rows.filter((r) => !r.alreadyAccrued).reduce((sum, r) => sum + r.minutes, 0),
1415
+ skipped,
1416
+ }
1417
+ }
1418
+
1152
1419
  // ---------------------------------------------------------------- approval chains
1153
1420
 
1154
1421
  const chains: Row<ApprovalChain>[] = [
@@ -1477,6 +1744,7 @@ export function createMockHrApi() {
1477
1744
  workEmail: input.workEmail ?? '',
1478
1745
  status: 'active' as const,
1479
1746
  timezone: 'Europe/Istanbul',
1747
+ hiredOn: input.hiredOn ?? day(0),
1480
1748
  employeeNo: input.employeeNo ?? `E-${people.length + 1}`,
1481
1749
  }
1482
1750
  people.push(added)
@@ -3037,6 +3305,203 @@ export function createMockHrApi() {
3037
3305
  },
3038
3306
  },
3039
3307
 
3308
+ policies: {
3309
+ list: async ({
3310
+ workspaceId,
3311
+ kind,
3312
+ includeArchived = false,
3313
+ }: {
3314
+ workspaceId: string
3315
+ kind?: string
3316
+ includeArchived?: boolean
3317
+ }) =>
3318
+ policies
3319
+ .filter((row) => (!kind || row.kind === kind) && (includeArchived || row.archivedAt === null))
3320
+ .map((row) => ({
3321
+ ...row,
3322
+ workspaceId,
3323
+ assignments: assignmentsOf(row.id).map((a) => ({ ...a, workspaceId })),
3324
+ })),
3325
+
3326
+ get: async ({ workspaceId, policyId }: { workspaceId: string; policyId: string }) => {
3327
+ const found = policies.find((row) => row.id === policyId)
3328
+ if (!found) refuse('NOT_FOUND', 'Policy not found')
3329
+ return {
3330
+ ...found,
3331
+ workspaceId,
3332
+ assignments: assignmentsOf(found.id).map((a) => ({ ...a, workspaceId })),
3333
+ }
3334
+ },
3335
+
3336
+ create: async (input: {
3337
+ workspaceId: string
3338
+ kind: Policy['kind']
3339
+ name: string
3340
+ config: Record<string, unknown>
3341
+ effectiveFrom: string
3342
+ effectiveTo?: string | null
3343
+ }) => {
3344
+ const created: Row<Policy> = {
3345
+ id: crypto.randomUUID(),
3346
+ kind: input.kind,
3347
+ name: input.name,
3348
+ config: clone(input.config),
3349
+ effectiveFrom: input.effectiveFrom,
3350
+ effectiveTo: input.effectiveTo ?? null,
3351
+ source: 'custom',
3352
+ packKey: null,
3353
+ // A hash of the config, because that is what a derived row records — a literal would make
3354
+ // every policy look identical to a recomputation deciding whether a figure is stale.
3355
+ configHash: Math.abs(
3356
+ [...JSON.stringify(input.config)].reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 7),
3357
+ )
3358
+ .toString(16)
3359
+ .padStart(8, '0'),
3360
+ archivedAt: null,
3361
+ }
3362
+ policies.push(created)
3363
+ return { ...created, workspaceId: input.workspaceId }
3364
+ },
3365
+
3366
+ update: async (input: {
3367
+ workspaceId: string
3368
+ policyId: string
3369
+ name?: string
3370
+ config?: Record<string, unknown>
3371
+ effectiveTo?: string | null
3372
+ }) => {
3373
+ const found = policies.find((row) => row.id === input.policyId)
3374
+ if (!found) refuse('NOT_FOUND', 'Policy not found')
3375
+ if (input.name !== undefined) found.name = input.name
3376
+ if (input.config !== undefined) found.config = clone(input.config)
3377
+ if (input.effectiveTo !== undefined) found.effectiveTo = input.effectiveTo
3378
+ return { ...found, workspaceId: input.workspaceId }
3379
+ },
3380
+
3381
+ /**
3382
+ * Archived, never deleted, and **the assignments are left where they are**.
3383
+ *
3384
+ * The router neither refuses nor cascades — a ledger entry names the policy that produced it,
3385
+ * so a movement whose policy had vanished would be a number nobody can explain. That means an
3386
+ * archived policy with live assignments is a state an administrator genuinely reaches, and the
3387
+ * fixture can reach it too rather than only in theory.
3388
+ */
3389
+ archive: async ({ policyId }: { workspaceId: string; policyId: string }) => {
3390
+ const found = policies.find((row) => row.id === policyId)
3391
+ if (!found) refuse('NOT_FOUND', 'Policy not found')
3392
+ found.archivedAt = iso()
3393
+ return { ok: true as const }
3394
+ },
3395
+
3396
+ assign: async (input: {
3397
+ workspaceId: string
3398
+ policyId: string
3399
+ subjectKind: PolicySubjectKind
3400
+ subjectId?: string | null
3401
+ effectiveFrom: string
3402
+ effectiveTo?: string | null
3403
+ }) => {
3404
+ const created: Row<PolicyAssignment> = {
3405
+ id: crypto.randomUUID(),
3406
+ policyId: input.policyId,
3407
+ subjectKind: input.subjectKind,
3408
+ // `workspace` needs no id, and storing one would make the rung look narrower than it is.
3409
+ subjectId: input.subjectKind === 'workspace' ? null : (input.subjectId ?? null),
3410
+ effectiveFrom: input.effectiveFrom,
3411
+ effectiveTo: input.effectiveTo ?? null,
3412
+ priority: PRIORITY[input.subjectKind],
3413
+ }
3414
+ policyAssignments.push(created)
3415
+ return { ...created, workspaceId: input.workspaceId }
3416
+ },
3417
+
3418
+ unassign: async ({ assignmentId }: { workspaceId: string; assignmentId: string }) => {
3419
+ const at = policyAssignments.findIndex((a) => a.id === assignmentId)
3420
+ if (at < 0) refuse('NOT_FOUND', 'Policy assignment not found')
3421
+ policyAssignments.splice(at, 1)
3422
+ return { ok: true as const }
3423
+ },
3424
+
3425
+ resolveFor: async ({ workspaceId, personId }: { workspaceId: string; personId: string }) => {
3426
+ const applicable = resolvePolicyFor(personId)
3427
+ void workspaceId
3428
+ return applicable
3429
+ ? [
3430
+ {
3431
+ kind: 'accrual' as const,
3432
+ policyId: applicable.policy.id,
3433
+ policyName: applicable.policy.name,
3434
+ config: applicable.policy.config,
3435
+ from: applicable.assignment.subjectKind,
3436
+ subjectId: applicable.assignment.subjectId,
3437
+ },
3438
+ ]
3439
+ : []
3440
+ },
3441
+ },
3442
+
3443
+ accrual: {
3444
+ /**
3445
+ * A query, and it **writes nothing**.
3446
+ *
3447
+ * The contract makes it a query for exactly this reason: a preview that filed ledger entries
3448
+ * would credit everybody the moment somebody looked at the screen meant to tell them what a
3449
+ * run *would* do. It returns the same rows `run` credits from, so the two cannot disagree.
3450
+ */
3451
+ preview: async ({
3452
+ workspaceId,
3453
+ from,
3454
+ to,
3455
+ personId,
3456
+ }: {
3457
+ workspaceId: string
3458
+ from: string
3459
+ to: string
3460
+ personId?: string
3461
+ }) => {
3462
+ void workspaceId
3463
+ return accrualRows(from, to, personId)
3464
+ },
3465
+
3466
+ /**
3467
+ * Credits the ledger, and is idempotent per person, per leave type, per period.
3468
+ *
3469
+ * A second run over the same window credits nothing, because every row it would write is
3470
+ * already `alreadyAccrued` — an accrual job that double-credits when somebody clicks twice is
3471
+ * worse than one that never ran.
3472
+ */
3473
+ run: async ({
3474
+ workspaceId,
3475
+ from,
3476
+ to,
3477
+ personId,
3478
+ }: {
3479
+ workspaceId: string
3480
+ from: string
3481
+ to: string
3482
+ personId?: string
3483
+ }) => {
3484
+ void workspaceId
3485
+ const preview = accrualRows(from, to, personId)
3486
+ let credited = 0
3487
+ let totalMinutes = 0
3488
+ for (const row of preview.rows) {
3489
+ if (row.alreadyAccrued) continue
3490
+ ledger.push(
3491
+ entry(row.personId, row.leaveTypeId, 'accrual', row.minutes, to, { reason: row.reason }),
3492
+ )
3493
+ credited += 1
3494
+ totalMinutes += row.minutes
3495
+ }
3496
+ return {
3497
+ credited,
3498
+ // Everything the run passed over: those already credited, and those it never reached.
3499
+ skipped: preview.skipped.length + preview.rows.filter((r) => r.alreadyAccrued).length,
3500
+ totalMinutes,
3501
+ }
3502
+ },
3503
+ },
3504
+
3040
3505
  periods: {
3041
3506
  list: async ({
3042
3507
  workspaceId,
@@ -77,13 +77,19 @@ const manage = $derived(canHr('approvalManage'))
77
77
 
78
78
  // ---------------------------------------------------------------- vocabulary
79
79
 
80
- const SUBJECT_TYPES: ApprovalSubjectType[] = [
81
- 'leave',
82
- 'regularization',
83
- 'overtime',
84
- 'timesheet',
85
- 'shift_swap',
86
- ]
80
+ /**
81
+ * What an admin may build a chain *for* — the two things this module can actually raise.
82
+ *
83
+ * `ApprovalSubjectType` still carries `overtime`, `timesheet` and `shift_swap`, because the engine
84
+ * is keyed by subject type on purpose and a stored chain must keep parsing. But offering them here
85
+ * let somebody design, name and save a chain that nothing can ever fire, and then wait for
86
+ * approvals that never arrive — a worse failure than the feature being absent, because it looks
87
+ * configured. They join this list with the code that raises them.
88
+ *
89
+ * `subjectLabel` below stays exhaustive: a workspace that already saved one of those chains must
90
+ * still see it named rather than rendered as a raw enum value.
91
+ */
92
+ const SUBJECT_TYPES: ApprovalSubjectType[] = ['leave', 'regularization']
87
93
 
88
94
  /** The same names the inbox uses. An approval called one thing here and another there is two things. */
89
95
  const subjectLabel = (subject: ApprovalSubjectType): string =>
@@ -145,7 +151,6 @@ const APPROVER_PERMISSIONS = [
145
151
  'hr.person.manage',
146
152
  'hr.leave.manage',
147
153
  'hr.attendance.manage',
148
- 'hr.overtime.manage',
149
154
  'hr.office.manage',
150
155
  'hr.approval.manage',
151
156
  ] as const
@@ -157,13 +162,11 @@ const permissionLabel = (key: string): string =>
157
162
  ? t('chain_perm_leave')
158
163
  : key === 'hr.attendance.manage'
159
164
  ? t('chain_perm_attendance')
160
- : key === 'hr.overtime.manage'
161
- ? t('chain_perm_overtime')
162
- : key === 'hr.office.manage'
163
- ? t('chain_perm_office')
164
- : key === 'hr.approval.manage'
165
- ? t('chain_perm_approval')
166
- : key
165
+ : key === 'hr.office.manage'
166
+ ? t('chain_perm_office')
167
+ : key === 'hr.approval.manage'
168
+ ? t('chain_perm_approval')
169
+ : key
167
170
 
168
171
  const modeLabel = (mode: ApprovalStepSpec['mode']): string =>
169
172
  mode === 'all' ? t('chain_mode_all') : mode === 'any' ? t('chain_mode_any') : t('chain_mode_quorum')
@@ -112,14 +112,6 @@ export const hrCapabilities = defineCapabilities([
112
112
  defaultEnabled: false,
113
113
  level: 1,
114
114
  },
115
- {
116
- id: 'overtime',
117
- label: 'Overtime',
118
- description: 'Detect and approve time worked beyond the schedule',
119
- dependsOn: ['attendance'],
120
- defaultEnabled: false,
121
- level: 2,
122
- },
123
115
  {
124
116
  id: 'documents',
125
117
  label: 'Employee documents',
@@ -258,20 +258,10 @@ export const hrPermissions = definePermissions([
258
258
  defaultRoles: ['owner', 'admin'],
259
259
  dangerous: true,
260
260
  },
261
- {
262
- key: 'hr.overtime.view',
263
- label: 'View overtime',
264
- scope: 'workspace',
265
- defaultRoles: ['owner', 'admin'],
266
- dangerous: false,
267
- },
268
- {
269
- key: 'hr.overtime.manage',
270
- label: 'Approve and adjust overtime',
271
- scope: 'workspace',
272
- defaultRoles: ['owner', 'admin'],
273
- dangerous: false,
274
- },
261
+ // No `hr.overtime.*` here. Overtime is detected, stored and shown as part of attendance, and
262
+ // nothing asks a question these keys could answer — a role checkbox that gates nothing teaches an
263
+ // administrator the same lesson a dead capability switch does. They come back with the approval
264
+ // flow that needs them.
275
265
 
276
266
  // ---------------------------------------------------------------- policies and periods
277
267
  {
@@ -357,8 +347,6 @@ export const HR_PERMISSIONS = {
357
347
  attendanceView: 'hr.attendance.view',
358
348
  attendanceViewTeam: 'hr.attendance.view_team',
359
349
  attendanceManage: 'hr.attendance.manage',
360
- overtimeView: 'hr.overtime.view',
361
- overtimeManage: 'hr.overtime.manage',
362
350
  policyView: 'hr.policy.view',
363
351
  policyManage: 'hr.policy.manage',
364
352
  periodManage: 'hr.period.manage',