@kernhq/module-hr 0.10.0 → 0.10.2

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.
Files changed (90) hide show
  1. package/dist/contract/attendance.d.ts +1 -0
  2. package/dist/contract/attendance.d.ts.map +1 -1
  3. package/dist/contract/attendance.js +9 -0
  4. package/dist/contract/attendance.js.map +1 -1
  5. package/dist/contract/capabilities.d.ts +16 -0
  6. package/dist/contract/capabilities.d.ts.map +1 -1
  7. package/dist/contract/capabilities.js +16 -0
  8. package/dist/contract/capabilities.js.map +1 -1
  9. package/dist/contract/router.d.ts +1 -0
  10. package/dist/contract/router.d.ts.map +1 -1
  11. package/dist/policy/accrual.d.ts +35 -4
  12. package/dist/policy/accrual.d.ts.map +1 -1
  13. package/dist/policy/accrual.js +141 -15
  14. package/dist/policy/accrual.js.map +1 -1
  15. package/dist/policy/working-time.d.ts +115 -9
  16. package/dist/policy/working-time.d.ts.map +1 -1
  17. package/dist/policy/working-time.js +120 -20
  18. package/dist/policy/working-time.js.map +1 -1
  19. package/dist/server/jobs.d.ts +14 -6
  20. package/dist/server/jobs.d.ts.map +1 -1
  21. package/dist/server/jobs.js +489 -144
  22. package/dist/server/jobs.js.map +1 -1
  23. package/dist/server/packs/index.d.ts +14 -0
  24. package/dist/server/packs/index.d.ts.map +1 -1
  25. package/dist/server/packs/index.js +19 -0
  26. package/dist/server/packs/index.js.map +1 -1
  27. package/dist/server/router.d.ts +1888 -111
  28. package/dist/server/router.d.ts.map +1 -1
  29. package/dist/server/router.js +154 -63
  30. package/dist/server/router.js.map +1 -1
  31. package/dist/server/schema.d.ts +17 -0
  32. package/dist/server/schema.d.ts.map +1 -1
  33. package/dist/server/schema.js +81 -2
  34. package/dist/server/schema.js.map +1 -1
  35. package/dist/server/services/approvals.d.ts +0 -2
  36. package/dist/server/services/approvals.d.ts.map +1 -1
  37. package/dist/server/services/approvals.js +12 -4
  38. package/dist/server/services/approvals.js.map +1 -1
  39. package/dist/server/services/attendance.d.ts +120 -8
  40. package/dist/server/services/attendance.d.ts.map +1 -1
  41. package/dist/server/services/attendance.js +226 -14
  42. package/dist/server/services/attendance.js.map +1 -1
  43. package/dist/server/services/ledger.d.ts +0 -2
  44. package/dist/server/services/ledger.d.ts.map +1 -1
  45. package/dist/server/services/ledger.js +1 -2
  46. package/dist/server/services/ledger.js.map +1 -1
  47. package/dist/server/services/policies.d.ts +6 -2
  48. package/dist/server/services/policies.d.ts.map +1 -1
  49. package/dist/server/services/policies.js +7 -2
  50. package/dist/server/services/policies.js.map +1 -1
  51. package/migrations/0005_approval_requester.sql +11 -1
  52. package/migrations/0006_schedule_no_overlap.sql +85 -0
  53. package/migrations/0007_hot_path_indexes.sql +38 -0
  54. package/migrations/0009_beyond_cap_minutes.sql +15 -0
  55. package/migrations/meta/0005_snapshot.json +4047 -0
  56. package/migrations/meta/0007_snapshot.json +4225 -0
  57. package/migrations/meta/0009_snapshot.json +4231 -0
  58. package/migrations/meta/_journal.json +21 -0
  59. package/package.json +7 -7
  60. package/src/client/components/ClockControls.svelte +127 -20
  61. package/src/client/components/ClockControls.test.ts +446 -0
  62. package/src/client/components/DelegationDialog.svelte +12 -3
  63. package/src/client/components/LeaveRequestDialog.svelte +254 -25
  64. package/src/client/components/PersonFormDialog.svelte +53 -3
  65. package/src/client/components/PersonPanel.svelte +134 -26
  66. package/src/client/i18n.ts +5 -927
  67. package/src/client/messages.test.ts +154 -0
  68. package/src/client/messages.ts +3388 -0
  69. package/src/client/mock.ts +1576 -161
  70. package/src/client/module.ts +15 -1
  71. package/src/client/pages/ApprovalsPage.svelte +120 -46
  72. package/src/client/pages/AttendancePage.svelte +106 -20
  73. package/src/client/pages/DirectoryPage.svelte +192 -55
  74. package/src/client/pages/LeavePage.svelte +280 -25
  75. package/src/client/pages/OfficesPage.svelte +26 -8
  76. package/src/client/pages/leave-and-attendance.test.ts +588 -0
  77. package/src/client/query.ts +12 -0
  78. package/src/client/settings/CalendarsSettings.svelte +1363 -12
  79. package/src/client/settings/CapabilitiesSettings.svelte +276 -19
  80. package/src/client/settings/GeneralSettings.svelte +420 -0
  81. package/src/client/settings/LeaveSettings.svelte +884 -12
  82. package/src/client/settings/OfficesSettings.svelte +1182 -12
  83. package/src/client/settings/SchedulesSettings.svelte +1149 -12
  84. package/src/client/summary.ts +14 -7
  85. package/src/client/widgets/ApprovalsWidget.svelte +133 -20
  86. package/src/client/widgets/HeadcountWidget.svelte +74 -8
  87. package/src/client/widgets/LeaveBalanceWidget.svelte +40 -5
  88. package/src/client/widgets/WhosOutWidget.svelte +47 -8
  89. package/src/contract/attendance.ts +9 -0
  90. package/src/contract/capabilities.ts +17 -0
@@ -1,6 +1,8 @@
1
1
  import { type Tx } from '@kernhq/kernel';
2
- import { inArray, sql } from 'drizzle-orm';
3
2
  import { type RoundingPolicy, type ShiftSpec } from '../../policy/working-time.js';
3
+ import { punches } from '../schema.js';
4
+ import { PolicyService } from './policies.js';
5
+ import { ResolveService } from './resolve.js';
4
6
  /**
5
7
  * Punches and the day sheet.
6
8
  *
@@ -21,19 +23,77 @@ export interface ResolvedSchedule {
21
23
  }
22
24
  /** A schedule with no shifts: somebody with no assignment still clocks in, they just owe no hours. */
23
25
  export declare const NO_SCHEDULE: ResolvedSchedule;
26
+ /** A punch exactly as it is stored. What `attribute` hands back, and what the router's guard reads. */
27
+ export type PunchRow = typeof punches.$inferSelect;
28
+ /**
29
+ * One decision about one instant, and everything that follows from it.
30
+ *
31
+ * A punch needs three answers that must agree: which day it counts towards, whether the transition
32
+ * it asks for is possible at all, and what the clock widget was showing the person before they
33
+ * pressed anything. They used to be computed in three places from three reads. Here they are one
34
+ * value, so a disagreement between them is not something the code can express.
35
+ */
36
+ export interface Attribution {
37
+ /** The business date this punch belongs to. */
38
+ businessDate: string;
39
+ /** What that date schedules, if anything. */
40
+ shift: ShiftSpec | null;
41
+ /** The live punches already filed on it, oldest first. */
42
+ punches: PunchRow[];
43
+ /** What those say: whether a shift, and a break, are still running. */
44
+ open: {
45
+ clockedIn: boolean;
46
+ onBreak: boolean;
47
+ };
48
+ }
24
49
  export declare class AttendanceService {
50
+ private readonly resolve;
51
+ private readonly policies;
52
+ /**
53
+ * Both collaborators are defaulted so `new AttendanceService()` still reads as a leaf service.
54
+ * The period is asked about on every recomputation, and who belongs to a legal entity is asked
55
+ * on every lock — neither question has a second implementation in this module and neither may
56
+ * grow one here.
57
+ */
58
+ constructor(resolve?: ResolveService, policies?: PolicyService);
25
59
  /** The schedule in force for a person on a date, as something the pure layer can use. */
26
60
  scheduleFor(tx: Tx, workspaceId: string, personId: string, on: string): Promise<ResolvedSchedule>;
61
+ /**
62
+ * Which shift a punch made at `atMs` joins — decided once, from the punches that are already filed.
63
+ *
64
+ * This is the circularity that made the last three attempts at the night-shift boundary
65
+ * unfixable. The shift a punch belonged to was worked out from the clock alone; the guard that
66
+ * decides whether the punch is even possible was then built by reading `punchesOn(that date)`. So
67
+ * the guard could only ever confirm the attribution's own choice, and where the choice was wrong
68
+ * the person was told they were not clocked in at the end of a shift they had just worked. The
69
+ * fact that settles it — is a shift still open — is a question about punches, so it is asked
70
+ * *before* the attribution instead of after it.
71
+ *
72
+ * Both candidate dates come back in one statement, the punch's own local date and the one before
73
+ * it, on `hr_punches_person_idx`. That is fewer queries than the path it replaces, and it is what
74
+ * makes the guard and the attribution incapable of drifting apart: they are the same rows.
75
+ */
76
+ attribute(tx: Tx, workspaceId: string, personId: string, atMs: number, timezone: string, schedule: ResolvedSchedule): Promise<Attribution>;
27
77
  /**
28
78
  * Record a punch.
29
79
  *
30
- * `at` is the server's clock, always. `clientReportedAt` is kept beside it with the measured skew
31
- * so an offline sync can be told from a device whose clock is wrong and a claim beyond the
32
- * threshold is marked `disputed` rather than silently accepted or silently dropped.
80
+ * Both the instant and the day it counts towards arrive decided. `at` is the server's clock unless
81
+ * the offline sync path says otherwise, and `businessDate` is `attribute`'s answer for that same
82
+ * instant this method used to attribute the punch a second time, from its own `new Date()`
83
+ * rather than from the instant the caller had already reasoned about. Two answers to one question,
84
+ * a millisecond apart, is how both ends of one shift end up on two sheets.
85
+ *
86
+ * `clientReportedAt` is kept beside the instant with the measured skew so an offline sync can be
87
+ * told from a device whose clock is wrong — and a claim beyond the threshold is marked `disputed`
88
+ * rather than silently accepted or silently dropped.
33
89
  */
34
90
  record(tx: Tx, workspaceId: string, input: {
35
91
  personId: string;
36
92
  direction: 'in' | 'out' | 'break_start' | 'break_end';
93
+ /** The instant, exactly as it was attributed. */
94
+ at: Date;
95
+ /** `attribute`'s answer for that instant, never re-derived here. */
96
+ businessDate: string;
37
97
  timezone: string;
38
98
  method: string;
39
99
  clientReportedAt?: string | null;
@@ -41,9 +101,9 @@ export declare class AttendanceService {
41
101
  geo?: Record<string, number> | null;
42
102
  note?: string | null;
43
103
  idempotencyKey?: string | null;
44
- /** Set only by the offline sync path, where the instant genuinely is the client's claim. */
45
- claimedAt?: Date | null;
46
- }, schedule: ResolvedSchedule): Promise<{
104
+ /** Set only by the offline sync path, where `at` genuinely is the client's claim. */
105
+ claimed?: boolean;
106
+ }): Promise<{
47
107
  createdAt: Date;
48
108
  id: string;
49
109
  timezone: string;
@@ -95,6 +155,59 @@ export declare class AttendanceService {
95
155
  recomputeDay(tx: Tx, workspaceId: string, personId: string, businessDate: string, timezone: string, schedule: ResolvedSchedule): Promise<{
96
156
  locked: boolean;
97
157
  }>;
158
+ /**
159
+ * The overtime rules that apply to one person on one date, as numbers a pure function can use.
160
+ *
161
+ * Resolved here rather than passed in, unlike the schedule: `computeDay` may not touch the
162
+ * database and every caller of `recomputeDay` would otherwise have to walk the policy ladder
163
+ * itself, which is how a rule ends up applied on three paths out of four.
164
+ *
165
+ * Undefined where no policy applies, which is what a workspace that never configured overtime
166
+ * means — every minute past the schedule counts, exactly as it did before the policy was read at
167
+ * all.
168
+ */
169
+ private overtimePolicyFor;
170
+ /**
171
+ * Overtime already counted this year, on the days *before* this one.
172
+ *
173
+ * Strictly before, so a day's figure depends only on days that precede it and recomputing one
174
+ * cannot depend on the order the sweep happens to visit them in. The days after it are then stale
175
+ * against a cap that filled earlier, which the nightly recomputation settles — an order-dependent
176
+ * sheet would not settle at all.
177
+ *
178
+ * The year is the calendar one, because `capMinutesPerYear` is what the config offers; a legal
179
+ * entity closing its year elsewhere would need the cap to say so first.
180
+ */
181
+ private overtimeCountedBefore;
182
+ /**
183
+ * Stamp `locked` on every day a period covers — and on nobody else's.
184
+ *
185
+ * A period with no legal entity is the whole workspace's. One that names an entity closes *that
186
+ * entity's* month: `PolicyService.isLocked` has always read it that way, and until this method
187
+ * existed the day sheet did not, so closing the Turkish entity's January froze the Dutch and
188
+ * Iranian ones too. Two enforcement mechanisms disagreeing about who a period covers is worse
189
+ * than either of them being wrong on its own, because each looks right from where it is read.
190
+ *
191
+ * Membership is asked of the resolution ladder rather than joined here: which entity somebody is
192
+ * in is not a column on `people` — the employment in force says, and where it does not, their
193
+ * primary office does — and that order has exactly one implementation in this module. It is asked
194
+ * **as of each day**, the same date `isLocked` will be asked about later, because the day is what
195
+ * belongs to an entity: resolving everybody once at the period's last day stamped the whole month
196
+ * of somebody who transferred in halfway through it, including the half they spent elsewhere —
197
+ * days no Dutch period had closed, frozen by a Turkish one.
198
+ *
199
+ * Releasing is not the mirror of stamping. The exclusion constraint keys on
200
+ * `coalesce(legal_entity_id, …)`, so a workspace-wide period and an entity's period may cover the
201
+ * same dates on purpose — and reopening the narrower one must not unlock a month the wider one
202
+ * has filed. So a day is released only where nothing still closes it. That reads the period's own
203
+ * status, which the handler writes before calling this: a period reopening itself would otherwise
204
+ * be the reason it cannot let go.
205
+ */
206
+ setPeriodLock(tx: Tx, workspaceId: string, period: {
207
+ legalEntityId: string | null;
208
+ startsOn: string;
209
+ endsOn: string;
210
+ }, locked: boolean): Promise<number>;
98
211
  /** Which business dates a person has punches on, in a range. Drives a bulk recompute. */
99
212
  datesWithPunches(tx: Tx, workspaceId: string, personId: string, from: string, to: string): Promise<string[]>;
100
213
  /**
@@ -146,5 +259,4 @@ export declare class AttendanceService {
146
259
  };
147
260
  }>;
148
261
  }
149
- export { inArray, sql };
150
262
  //# sourceMappingURL=attendance.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"attendance.d.ts","sourceRoot":"","sources":["../../../src/server/services/attendance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,EAAE,EAAU,MAAM,gBAAgB,CAAA;AAC3D,OAAO,EAAqB,OAAO,EAAe,GAAG,EAAE,MAAM,aAAa,CAAA;AAG1E,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,8BAA8B,CAAA;AAIrC;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAA;IACxC,QAAQ,EAAE,cAAc,CAAA;IACxB,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAA;IACvC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED,sGAAsG;AACtG,eAAO,MAAM,WAAW,EAAE,gBAKzB,CAAA;AAED,qBAAa,iBAAiB;IAC5B,yFAAyF;IACnF,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA2CvG;;;;;;OAMG;IACG,MAAM,CACV,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAA;QAChB,SAAS,EAAE,IAAI,GAAG,KAAK,GAAG,aAAa,GAAG,WAAW,CAAA;QACrD,QAAQ,EAAE,MAAM,CAAA;QAChB,MAAM,EAAE,MAAM,CAAA;QACd,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAChC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACxB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAA;QACnC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACpB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAC9B,4FAA4F;QAC5F,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;KACxB,EACD,QAAQ,EAAE,gBAAgB;;;;;;;;;;;;;;;;;;;;IAuC5B,4FAA4F;IACtF,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;IAenF;;;;;;;OAOG;IACG,YAAY,CAChB,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC;IA0F/B,yFAAyF;IACnF,gBAAgB,CACpB,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,MAAM,EAAE,CAAC;IAepB;;;;;OAKG;IACG,SAAS,CACb,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyC/B;AAYD,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAA"}
1
+ {"version":3,"file":"attendance.d.ts","sourceRoot":"","sources":["../../../src/server/services/attendance.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,12 @@
1
1
  import { KernError, uuidv7 } from '@kernhq/kernel';
2
- import { and, asc, eq, gte, inArray, isNull, lte, sql } from 'drizzle-orm';
2
+ import { and, asc, eq, gte, inArray, isNull, lt, lte, or, sql } from 'drizzle-orm';
3
3
  import { weekdayOf } from '../../policy/calendar.js';
4
- import { businessDateFor, computeDay, } from '../../policy/working-time.js';
4
+ import { dateIn, previousDate } from '../../policy/time.js';
5
+ import { attributeToShift, computeDay, openState, } from '../../policy/working-time.js';
5
6
  import { attendanceDays, leaveRequestDays, punches, scheduleAssignments, schedules } from '../schema.js';
6
7
  import { inForceOn } from './db.js';
8
+ import { PolicyService } from './policies.js';
9
+ import { ResolveService } from './resolve.js';
7
10
  /** A schedule with no shifts: somebody with no assignment still clocks in, they just owe no hours. */
8
11
  export const NO_SCHEDULE = {
9
12
  shiftFor: () => null,
@@ -12,6 +15,18 @@ export const NO_SCHEDULE = {
12
15
  scheduleId: null,
13
16
  };
14
17
  export class AttendanceService {
18
+ resolve;
19
+ policies;
20
+ /**
21
+ * Both collaborators are defaulted so `new AttendanceService()` still reads as a leaf service.
22
+ * The period is asked about on every recomputation, and who belongs to a legal entity is asked
23
+ * on every lock — neither question has a second implementation in this module and neither may
24
+ * grow one here.
25
+ */
26
+ constructor(resolve = new ResolveService(), policies = new PolicyService(resolve)) {
27
+ this.resolve = resolve;
28
+ this.policies = policies;
29
+ }
15
30
  /** The schedule in force for a person on a date, as something the pure layer can use. */
16
31
  async scheduleFor(tx, workspaceId, personId, on) {
17
32
  const [assignment] = await tx
@@ -50,21 +65,57 @@ export class AttendanceService {
50
65
  autoClockOutAfterMinutes: schedule.autoClockOutAfterMinutes,
51
66
  };
52
67
  }
68
+ /**
69
+ * Which shift a punch made at `atMs` joins — decided once, from the punches that are already filed.
70
+ *
71
+ * This is the circularity that made the last three attempts at the night-shift boundary
72
+ * unfixable. The shift a punch belonged to was worked out from the clock alone; the guard that
73
+ * decides whether the punch is even possible was then built by reading `punchesOn(that date)`. So
74
+ * the guard could only ever confirm the attribution's own choice, and where the choice was wrong
75
+ * the person was told they were not clocked in at the end of a shift they had just worked. The
76
+ * fact that settles it — is a shift still open — is a question about punches, so it is asked
77
+ * *before* the attribution instead of after it.
78
+ *
79
+ * Both candidate dates come back in one statement, the punch's own local date and the one before
80
+ * it, on `hr_punches_person_idx`. That is fewer queries than the path it replaces, and it is what
81
+ * makes the guard and the attribution incapable of drifting apart: they are the same rows.
82
+ */
83
+ async attribute(tx, workspaceId, personId, atMs, timezone, schedule) {
84
+ const local = dateIn(atMs, timezone);
85
+ const yesterday = previousDate(local);
86
+ const rows = await tx
87
+ .select()
88
+ .from(punches)
89
+ .where(and(eq(punches.workspaceId, workspaceId), eq(punches.personId, personId), inArray(punches.businessDate, [yesterday, local]), isNull(punches.voidedByPunchId)))
90
+ .orderBy(asc(punches.at));
91
+ const filedOn = (date) => rows.filter((r) => r.businessDate === date);
92
+ const { businessDate, shift } = attributeToShift(atMs, timezone, (d) => schedule.shiftFor(d), {
93
+ onLocalDate: openState(filedOn(local)).clockedIn,
94
+ onPreviousDate: openState(filedOn(yesterday)).clockedIn,
95
+ workedPreviousDate: filedOn(yesterday).length > 0,
96
+ });
97
+ const mine = filedOn(businessDate);
98
+ return { businessDate, shift, punches: mine, open: openState(mine) };
99
+ }
53
100
  /**
54
101
  * Record a punch.
55
102
  *
56
- * `at` is the server's clock, always. `clientReportedAt` is kept beside it with the measured skew
57
- * so an offline sync can be told from a device whose clock is wrong and a claim beyond the
58
- * threshold is marked `disputed` rather than silently accepted or silently dropped.
103
+ * Both the instant and the day it counts towards arrive decided. `at` is the server's clock unless
104
+ * the offline sync path says otherwise, and `businessDate` is `attribute`'s answer for that same
105
+ * instant this method used to attribute the punch a second time, from its own `new Date()`
106
+ * rather than from the instant the caller had already reasoned about. Two answers to one question,
107
+ * a millisecond apart, is how both ends of one shift end up on two sheets.
108
+ *
109
+ * `clientReportedAt` is kept beside the instant with the measured skew so an offline sync can be
110
+ * told from a device whose clock is wrong — and a claim beyond the threshold is marked `disputed`
111
+ * rather than silently accepted or silently dropped.
59
112
  */
60
- async record(tx, workspaceId, input, schedule) {
113
+ async record(tx, workspaceId, input) {
61
114
  const serverNow = new Date();
62
- const at = input.claimedAt ?? serverNow;
63
115
  const clientAt = input.clientReportedAt ? new Date(input.clientReportedAt) : null;
64
116
  const skewMs = clientAt ? clientAt.getTime() - serverNow.getTime() : null;
65
117
  // A claim more than an hour out is not a slow network; it is a clock somebody should look at.
66
- const trust = input.claimedAt ? (Math.abs(skewMs ?? 0) > 3600_000 ? 'disputed' : 'claimed') : 'trusted';
67
- const businessDate = businessDateFor(at.getTime(), input.timezone, schedule.shiftFor(new Date(at.getTime()).toISOString().slice(0, 10)));
118
+ const trust = input.claimed ? (Math.abs(skewMs ?? 0) > 3600_000 ? 'disputed' : 'claimed') : 'trusted';
68
119
  const [row] = await tx
69
120
  .insert(punches)
70
121
  .values({
@@ -72,10 +123,10 @@ export class AttendanceService {
72
123
  workspaceId,
73
124
  personId: input.personId,
74
125
  direction: input.direction,
75
- at,
126
+ at: input.at,
76
127
  clientReportedAt: clientAt,
77
128
  skewMs,
78
- businessDate,
129
+ businessDate: input.businessDate,
79
130
  timezone: input.timezone,
80
131
  method: input.method,
81
132
  officeId: input.officeId ?? null,
@@ -104,13 +155,36 @@ export class AttendanceService {
104
155
  * month looks identical to one that had nothing to do.
105
156
  */
106
157
  async recomputeDay(tx, workspaceId, personId, businessDate, timezone, schedule) {
158
+ const day = and(eq(attendanceDays.workspaceId, workspaceId), eq(attendanceDays.personId, personId), eq(attendanceDays.businessDate, businessDate));
107
159
  const [existing] = await tx
108
160
  .select({ locked: attendanceDays.locked })
109
161
  .from(attendanceDays)
110
- .where(and(eq(attendanceDays.workspaceId, workspaceId), eq(attendanceDays.personId, personId), eq(attendanceDays.businessDate, businessDate)))
162
+ .where(day)
111
163
  .limit(1);
112
- if (existing?.locked)
164
+ // Which entity's payroll a day belongs to is a question **about that day**, so it is asked here
165
+ // rather than taken as an argument. Every caller had one to hand and three of them had the
166
+ // wrong one: `clockContext` resolves as of today and its answer was then applied to arbitrary
167
+ // past dates by `punches.void`, `days.recompute` over a whole range, and an approved
168
+ // regularization — so somebody who changed legal entity had March recomputed against the entity
169
+ // they joined in April, found it open, and wrote into a month already filed.
170
+ const { legalEntityId } = await this.resolve.forPerson(tx, workspaceId, personId, businessDate);
171
+ // The column is a *cache* of the period's status, and the period is the authority — asked
172
+ // first, every time, and in both directions. A cache that defaults to false lies about every
173
+ // date the lock swept before the row existed: `periods.lock` stamps the rows that are there,
174
+ // and the first punch on a date inside a closed month then creates a fresh one at the default.
175
+ // Believing a `true` before asking lied the other way, and only ever grew: a row stamped by a
176
+ // lock that has since been reopened, or by a person's employment being corrected underneath
177
+ // one, refused recomputation for ever with nothing behind it.
178
+ //
179
+ // So where a row exists the flag is repaired from the period in whichever direction disagrees —
180
+ // upwards here, downwards in the rebuild below. Where none exists none is written: an absent
181
+ // sheet reads as "nothing was filed for that day", which is true, while a permanently frozen
182
+ // half-day reads as a figure somebody can act on, which it is not.
183
+ if (await this.policies.isLocked(tx, workspaceId, businessDate, legalEntityId)) {
184
+ if (existing && !existing.locked)
185
+ await tx.update(attendanceDays).set({ locked: true }).where(day);
113
186
  return { locked: true };
187
+ }
114
188
  const rows = await this.punchesOn(tx, workspaceId, personId, businessDate);
115
189
  const punchInputs = rows.map((r) => ({
116
190
  at: r.at.getTime(),
@@ -123,12 +197,14 @@ export class AttendanceService {
123
197
  .from(leaveRequestDays)
124
198
  .where(and(eq(leaveRequestDays.workspaceId, workspaceId), eq(leaveRequestDays.personId, personId), eq(leaveRequestDays.date, businessDate), eq(leaveRequestDays.counted, true), eq(leaveRequestDays.status, 'approved')))
125
199
  .limit(1);
200
+ const overtimePolicy = await this.overtimePolicyFor(tx, workspaceId, personId, businessDate);
126
201
  const computed = computeDay({
127
202
  businessDate,
128
203
  timeZone: timezone,
129
204
  shift: schedule.shiftFor(businessDate),
130
205
  punches: punchInputs,
131
206
  rounding: schedule.rounding,
207
+ overtime: overtimePolicy,
132
208
  excused: !!onLeave,
133
209
  });
134
210
  const status = onLeave && computed.workedMinutes === 0 ? 'leave' : computed.status;
@@ -143,6 +219,7 @@ export class AttendanceService {
143
219
  workedMinutes: computed.workedMinutes,
144
220
  breakMinutes: computed.breakMinutes,
145
221
  overtimeMinutes: computed.overtimeMinutes,
222
+ beyondCapMinutes: computed.beyondCapMinutes,
146
223
  lateMinutes: computed.lateMinutes,
147
224
  earlyLeaveMinutes: computed.earlyLeaveMinutes,
148
225
  status,
@@ -160,6 +237,7 @@ export class AttendanceService {
160
237
  workedMinutes: computed.workedMinutes,
161
238
  breakMinutes: computed.breakMinutes,
162
239
  overtimeMinutes: computed.overtimeMinutes,
240
+ beyondCapMinutes: computed.beyondCapMinutes,
163
241
  lateMinutes: computed.lateMinutes,
164
242
  earlyLeaveMinutes: computed.earlyLeaveMinutes,
165
243
  status,
@@ -169,10 +247,145 @@ export class AttendanceService {
169
247
  lastOut: computed.lastOut ? new Date(computed.lastOut) : null,
170
248
  policyHash: hashSchedule(schedule),
171
249
  computedAt: new Date(),
250
+ // The other half of the repair: no period closes this date, so a row still carrying the
251
+ // flag lets go of it here. Rebuilding the figures while leaving `locked` true would
252
+ // publish a sheet nothing can move next to a flag saying nothing may.
253
+ locked: false,
172
254
  },
173
255
  });
174
256
  return { locked: false };
175
257
  }
258
+ /**
259
+ * The overtime rules that apply to one person on one date, as numbers a pure function can use.
260
+ *
261
+ * Resolved here rather than passed in, unlike the schedule: `computeDay` may not touch the
262
+ * database and every caller of `recomputeDay` would otherwise have to walk the policy ladder
263
+ * itself, which is how a rule ends up applied on three paths out of four.
264
+ *
265
+ * Undefined where no policy applies, which is what a workspace that never configured overtime
266
+ * means — every minute past the schedule counts, exactly as it did before the policy was read at
267
+ * all.
268
+ */
269
+ async overtimePolicyFor(tx, workspaceId, personId, businessDate) {
270
+ const resolved = await this.policies.forPerson(tx, workspaceId, personId, 'overtime', businessDate);
271
+ if (!resolved.config)
272
+ return undefined;
273
+ const config = resolved.config;
274
+ const capMinutes = config.capMinutesPerYear ?? null;
275
+ return {
276
+ thresholdMinutes: config.thresholdMinutes ?? 0,
277
+ capMinutes,
278
+ alreadyCountedMinutes: capMinutes === null ? 0 : await this.overtimeCountedBefore(tx, workspaceId, personId, businessDate),
279
+ };
280
+ }
281
+ /**
282
+ * Overtime already counted this year, on the days *before* this one.
283
+ *
284
+ * Strictly before, so a day's figure depends only on days that precede it and recomputing one
285
+ * cannot depend on the order the sweep happens to visit them in. The days after it are then stale
286
+ * against a cap that filled earlier, which the nightly recomputation settles — an order-dependent
287
+ * sheet would not settle at all.
288
+ *
289
+ * The year is the calendar one, because `capMinutesPerYear` is what the config offers; a legal
290
+ * entity closing its year elsewhere would need the cap to say so first.
291
+ */
292
+ async overtimeCountedBefore(tx, workspaceId, personId, businessDate) {
293
+ const [row] = await tx
294
+ .select({ minutes: sql `coalesce(sum(${attendanceDays.overtimeMinutes}), 0)` })
295
+ .from(attendanceDays)
296
+ .where(and(eq(attendanceDays.workspaceId, workspaceId), eq(attendanceDays.personId, personId), gte(attendanceDays.businessDate, `${businessDate.slice(0, 4)}-01-01`), lt(attendanceDays.businessDate, businessDate)));
297
+ return Number(row?.minutes ?? 0);
298
+ }
299
+ /**
300
+ * Stamp `locked` on every day a period covers — and on nobody else's.
301
+ *
302
+ * A period with no legal entity is the whole workspace's. One that names an entity closes *that
303
+ * entity's* month: `PolicyService.isLocked` has always read it that way, and until this method
304
+ * existed the day sheet did not, so closing the Turkish entity's January froze the Dutch and
305
+ * Iranian ones too. Two enforcement mechanisms disagreeing about who a period covers is worse
306
+ * than either of them being wrong on its own, because each looks right from where it is read.
307
+ *
308
+ * Membership is asked of the resolution ladder rather than joined here: which entity somebody is
309
+ * in is not a column on `people` — the employment in force says, and where it does not, their
310
+ * primary office does — and that order has exactly one implementation in this module. It is asked
311
+ * **as of each day**, the same date `isLocked` will be asked about later, because the day is what
312
+ * belongs to an entity: resolving everybody once at the period's last day stamped the whole month
313
+ * of somebody who transferred in halfway through it, including the half they spent elsewhere —
314
+ * days no Dutch period had closed, frozen by a Turkish one.
315
+ *
316
+ * Releasing is not the mirror of stamping. The exclusion constraint keys on
317
+ * `coalesce(legal_entity_id, …)`, so a workspace-wide period and an entity's period may cover the
318
+ * same dates on purpose — and reopening the narrower one must not unlock a month the wider one
319
+ * has filed. So a day is released only where nothing still closes it. That reads the period's own
320
+ * status, which the handler writes before calling this: a period reopening itself would otherwise
321
+ * be the reason it cannot let go.
322
+ */
323
+ async setPeriodLock(tx, workspaceId, period, locked) {
324
+ const inRange = [
325
+ eq(attendanceDays.workspaceId, workspaceId),
326
+ gte(attendanceDays.businessDate, period.startsOn),
327
+ lte(attendanceDays.businessDate, period.endsOn),
328
+ ];
329
+ // Closing a period that names no entity closes the workspace, and there is nothing to ask the
330
+ // ladder about: one statement, as it always was. Every other combination needs to know which
331
+ // entity somebody was in on the day — to decide whether the period covers them, or whether
332
+ // anything else still does.
333
+ if (!period.legalEntityId && locked) {
334
+ const swept = await tx
335
+ .update(attendanceDays)
336
+ .set({ locked })
337
+ .where(and(...inRange))
338
+ .returning({ id: attendanceDays.id });
339
+ return swept.length;
340
+ }
341
+ const candidates = await tx
342
+ .selectDistinct({ personId: attendanceDays.personId, businessDate: attendanceDays.businessDate })
343
+ .from(attendanceDays)
344
+ .where(and(...inRange));
345
+ if (!candidates.length)
346
+ return 0;
347
+ // One resolution per date rather than per row: a month is at most thirty-one ladder walks
348
+ // whatever the headcount, where a walk per person-day would be that times everybody.
349
+ const peopleOn = new Map();
350
+ for (const c of candidates)
351
+ peopleOn.set(c.businessDate, [...(peopleOn.get(c.businessDate) ?? []), c.personId]);
352
+ const entityOn = new Map();
353
+ for (const [date, ids] of peopleOn) {
354
+ const resolved = await this.resolve.forPeople(tx, workspaceId, [...new Set(ids)], date);
355
+ for (const id of ids)
356
+ entityOn.set(`${id}|${date}`, resolved.get(id)?.legalEntityId ?? null);
357
+ }
358
+ const stillClosed = new Map();
359
+ const closedByAnything = async (date, entity) => {
360
+ const key = `${entity ?? 'workspace'}|${date}`;
361
+ const seen = stillClosed.get(key);
362
+ if (seen !== undefined)
363
+ return seen;
364
+ const answer = await this.policies.isLocked(tx, workspaceId, date, entity);
365
+ stillClosed.set(key, answer);
366
+ return answer;
367
+ };
368
+ const mine = [];
369
+ for (const c of candidates) {
370
+ const entity = entityOn.get(`${c.personId}|${c.businessDate}`) ?? null;
371
+ if (period.legalEntityId && entity !== period.legalEntityId)
372
+ continue;
373
+ if (!locked && (await closedByAnything(c.businessDate, entity)))
374
+ continue;
375
+ mine.push(c);
376
+ }
377
+ if (!mine.length)
378
+ return 0;
379
+ const days = new Map();
380
+ for (const m of mine)
381
+ days.set(m.personId, [...(days.get(m.personId) ?? []), m.businessDate]);
382
+ const rows = await tx
383
+ .update(attendanceDays)
384
+ .set({ locked })
385
+ .where(and(eq(attendanceDays.workspaceId, workspaceId), or(...[...days].map(([personId, dates]) => and(eq(attendanceDays.personId, personId), inArray(attendanceDays.businessDate, dates))))))
386
+ .returning({ id: attendanceDays.id });
387
+ return rows.length;
388
+ }
176
389
  /** Which business dates a person has punches on, in a range. Drives a bulk recompute. */
177
390
  async datesWithPunches(tx, workspaceId, personId, from, to) {
178
391
  const rows = await tx
@@ -235,5 +448,4 @@ export class AttendanceService {
235
448
  function hashSchedule(schedule) {
236
449
  return `${schedule.scheduleId ?? 'none'}:${schedule.rounding.stepMinutes}:${schedule.rounding.direction}`;
237
450
  }
238
- export { inArray, sql };
239
451
  //# sourceMappingURL=attendance.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"attendance.js","sourceRoot":"","sources":["../../../src/server/services/attendance.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"attendance.js","sourceRoot":"","sources":["../../../src/server/services/attendance.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,4 @@
1
1
  import { type Tx } from '@kernhq/kernel';
2
- import { inArray } from 'drizzle-orm';
3
2
  import type { LedgerKind } from '../../contract/index.js';
4
3
  /**
5
4
  * The leave balance, and the concurrency that makes it hard.
@@ -131,5 +130,4 @@ export declare class LedgerService {
131
130
  rebuildCursors(tx: Tx, workspaceId: string, personIds: string[]): Promise<void>;
132
131
  }
133
132
  export declare const yearOf: (isoDate: string) => number;
134
- export { inArray };
135
133
  //# sourceMappingURL=ledger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../../../src/server/services/ledger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,EAAE,EAAU,MAAM,gBAAgB,CAAA;AAC3D,OAAO,EAAW,OAAO,EAAO,MAAM,aAAa,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAGzD;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,0FAA0F;AAC1F,eAAO,MAAM,MAAM,GAAI,SAAS,MAAM,EAAE,MAAM,MAAM,KAAG,MACgD,CAAA;AAEvG,sFAAsF;AACtF,eAAO,MAAM,eAAe,QAAS,CAAA;AAErC,qBAAa,aAAa;IACxB;;;;;;OAMG;IACG,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;;;;cAmDvD,KAAK,GAAG,UAAU,GAAG,MAAM;;;;;;;;;IAYpD;;;;;OAKG;IACG,WAAW,CACf,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC;IA6BlB,gEAAgE;IAC1D,MAAM,CACV,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAA;QAChB,WAAW,EAAE,MAAM,CAAA;QACnB,IAAI,EAAE,UAAU,CAAA;QAChB,aAAa,EAAE,MAAM,CAAA;QACrB,WAAW,EAAE,MAAM,CAAA;QACnB,UAAU,EAAE,MAAM,CAAA;QAClB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACzB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACtB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAC3B;;;;;;;;;;;;;;;;IAyBH;;;;;;OAMG;IACG,OAAO,CACX,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;IAiCZ,yDAAyD;IACnD,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;;;;;;;;;;;;;;;IAO/D,oGAAoG;IAC9F,cAAc,CAAC,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE;CAuBtE;AAED,eAAO,MAAM,MAAM,GAAI,SAAS,MAAM,KAAG,MAAqC,CAAA;AAC9E,OAAO,EAAE,OAAO,EAAE,CAAA"}
1
+ {"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../../../src/server/services/ledger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,EAAE,EAAU,MAAM,gBAAgB,CAAA;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAGzD;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,0FAA0F;AAC1F,eAAO,MAAM,MAAM,GAAI,SAAS,MAAM,EAAE,MAAM,MAAM,KAAG,MACgD,CAAA;AAEvG,sFAAsF;AACtF,eAAO,MAAM,eAAe,QAAS,CAAA;AAErC,qBAAa,aAAa;IACxB;;;;;;OAMG;IACG,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;;;;cAmDvD,KAAK,GAAG,UAAU,GAAG,MAAM;;;;;;;;;IAYpD;;;;;OAKG;IACG,WAAW,CACf,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC;IA6BlB,gEAAgE;IAC1D,MAAM,CACV,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAA;QAChB,WAAW,EAAE,MAAM,CAAA;QACnB,IAAI,EAAE,UAAU,CAAA;QAChB,aAAa,EAAE,MAAM,CAAA;QACrB,WAAW,EAAE,MAAM,CAAA;QACnB,UAAU,EAAE,MAAM,CAAA;QAClB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACzB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACtB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAC3B;;;;;;;;;;;;;;;;IAyBH;;;;;;OAMG;IACG,OAAO,CACX,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;IAiCZ,yDAAyD;IACnD,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;;;;;;;;;;;;;;;IAO/D,oGAAoG;IAC9F,cAAc,CAAC,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE;CAuBtE;AAED,eAAO,MAAM,MAAM,GAAI,SAAS,MAAM,KAAG,MAAqC,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { KernError, uuidv7 } from '@kernhq/kernel';
2
- import { and, eq, inArray, sql } from 'drizzle-orm';
2
+ import { and, eq, sql } from 'drizzle-orm';
3
3
  import { leaveBalanceCursor, leaveLedger, leaveRequestDays, leaveTypes } from '../schema.js';
4
4
  /** A minute count in whatever unit the type displays. Hours to one place, days to two. */
5
5
  export const toUnit = (minutes, unit) => unit === 'hour' ? Math.round((minutes / 60) * 10) / 10 : Math.round((minutes / (60 * 8)) * 100) / 100;
@@ -174,5 +174,4 @@ export class LedgerService {
174
174
  }
175
175
  }
176
176
  export const yearOf = (isoDate) => Number(isoDate.slice(0, 4));
177
- export { inArray };
178
177
  //# sourceMappingURL=ledger.js.map