@t4dhg/mcp-factorial 10.2.0 → 11.0.1
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/README.md +54 -43
- package/dist/api/attendance.d.ts +17 -1
- package/dist/api/attendance.d.ts.map +1 -1
- package/dist/api/attendance.js +38 -1
- package/dist/api/attendance.js.map +1 -1
- package/dist/api/index.d.ts +1 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +1 -1
- package/dist/api/index.js.map +1 -1
- package/dist/attendance/backfill.d.ts +18 -3
- package/dist/attendance/backfill.d.ts.map +1 -1
- package/dist/attendance/backfill.js +51 -9
- package/dist/attendance/backfill.js.map +1 -1
- package/dist/attendance/planner.d.ts +64 -4
- package/dist/attendance/planner.d.ts.map +1 -1
- package/dist/attendance/planner.js +145 -16
- package/dist/attendance/planner.js.map +1 -1
- package/dist/attendance/report.d.ts +3 -0
- package/dist/attendance/report.d.ts.map +1 -1
- package/dist/attendance/report.js +92 -12
- package/dist/attendance/report.js.map +1 -1
- package/dist/endpoints.d.ts +2 -0
- package/dist/endpoints.d.ts.map +1 -1
- package/dist/endpoints.js +2 -0
- package/dist/endpoints.js.map +1 -1
- package/dist/errors.d.ts +6 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +10 -5
- package/dist/errors.js.map +1 -1
- package/dist/http-client.d.ts +6 -0
- package/dist/http-client.d.ts.map +1 -1
- package/dist/http-client.js +28 -4
- package/dist/http-client.js.map +1 -1
- package/dist/prompts/attendance.d.ts +19 -2
- package/dist/prompts/attendance.d.ts.map +1 -1
- package/dist/prompts/attendance.js +297 -40
- package/dist/prompts/attendance.js.map +1 -1
- package/dist/schemas/attendance.d.ts +123 -0
- package/dist/schemas/attendance.d.ts.map +1 -1
- package/dist/schemas/attendance.js +58 -0
- package/dist/schemas/attendance.js.map +1 -1
- package/dist/schemas/documents.d.ts +2 -2
- package/dist/schemas/index.d.ts +1 -1
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +1 -1
- package/dist/schemas/index.js.map +1 -1
- package/dist/schemas/projects.d.ts +2 -2
- package/dist/tools/attendance.d.ts.map +1 -1
- package/dist/tools/attendance.js +325 -50
- package/dist/tools/attendance.js.map +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +6 -8
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/shared.d.ts +10 -1
- package/dist/tools/shared.d.ts.map +1 -1
- package/dist/tools/shared.js +33 -0
- package/dist/tools/shared.js.map +1 -1
- package/dist/tools/time-off.d.ts.map +1 -1
- package/dist/tools/time-off.js +9 -1
- package/dist/tools/time-off.js.map +1 -1
- package/dist/write-safety.d.ts +6 -0
- package/dist/write-safety.d.ts.map +1 -1
- package/dist/write-safety.js +7 -0
- package/dist/write-safety.js.map +1 -1
- package/llms.txt +11 -6
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ The MCP server uses a hierarchical tool structure for optimal context usage. Ins
|
|
|
39
39
|
| `factorial_locations` | Location management | list, get, create, update, delete |
|
|
40
40
|
| `factorial_contracts` | Contract/salary data | list, get_with_employee, by_job_role, by_job_level |
|
|
41
41
|
| `factorial_time_off` | Leave management | 10 actions |
|
|
42
|
-
| `factorial_attendance` | Shifts and registro horario |
|
|
42
|
+
| `factorial_attendance` | Shifts and registro horario | 14 actions incl. clock_in, audit, log_range |
|
|
43
43
|
| `factorial_documents` | Document management | 8 actions (downloads require OAuth2 - see below) |
|
|
44
44
|
| `factorial_job_catalog` | Job roles/levels | list_roles, get_role, list_levels |
|
|
45
45
|
| `factorial_projects` | Project management | 16 actions for projects, tasks, workers, time |
|
|
@@ -75,37 +75,40 @@ factorial_discover({ category: 'employees' });
|
|
|
75
75
|
|
|
76
76
|
### 124 Operations Across 14 Categories
|
|
77
77
|
|
|
78
|
-
| Category | Operations
|
|
79
|
-
| --------------- |
|
|
80
|
-
| **Employees** | list, get, search, create, update, terminate
|
|
81
|
-
| **Teams** | list, get, create, update, delete
|
|
82
|
-
| **Locations** | list, get, create, update, delete
|
|
83
|
-
| **Time Off** | list_leaves, get_leave, list_types, get_type, list_allowances, create, update, cancel, approve, reject
|
|
84
|
-
| **Attendance** | list, get, create, update, delete, clock_in, clock_out, status, gaps, audit, log_range, log_days
|
|
85
|
-
| **Projects** | 16 operations for projects, tasks, workers, time records
|
|
86
|
-
| **Training** | 12 operations for trainings, sessions, enrollments
|
|
87
|
-
| **Work Areas** | list, get, create, update, archive, unarchive
|
|
88
|
-
| **ATS** | 17 operations for job postings, candidates, applications, hiring stages
|
|
89
|
-
| **Payroll** | list/get supplements, tax identifiers, family situations (read-only)
|
|
90
|
-
| **Documents** | 8 operations for folders, documents, and downloads (⚠️ downloads require OAuth2)
|
|
91
|
-
| **Job Catalog** | list_roles, get_role, list_levels (read-only)
|
|
92
|
-
| **Contracts** | list, get_with_employee, by_job_role, by_job_level (read-only)
|
|
78
|
+
| Category | Operations |
|
|
79
|
+
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
|
80
|
+
| **Employees** | list, get, search, create, update, terminate |
|
|
81
|
+
| **Teams** | list, get, create, update, delete |
|
|
82
|
+
| **Locations** | list, get, create, update, delete |
|
|
83
|
+
| **Time Off** | list_leaves, get_leave, list_types, get_type, list_allowances, create, update, cancel, approve, reject |
|
|
84
|
+
| **Attendance** | list, get, create, update, delete, clock_in, clock_out, status, gaps, audit, log_range, log_days, list_edit_requests, create_edit_request |
|
|
85
|
+
| **Projects** | 16 operations for projects, tasks, workers, time records |
|
|
86
|
+
| **Training** | 12 operations for trainings, sessions, enrollments |
|
|
87
|
+
| **Work Areas** | list, get, create, update, archive, unarchive |
|
|
88
|
+
| **ATS** | 17 operations for job postings, candidates, applications, hiring stages |
|
|
89
|
+
| **Payroll** | list/get supplements, tax identifiers, family situations (read-only) |
|
|
90
|
+
| **Documents** | 8 operations for folders, documents, and downloads (⚠️ downloads require OAuth2) |
|
|
91
|
+
| **Job Catalog** | list_roles, get_role, list_levels (read-only) |
|
|
92
|
+
| **Contracts** | list, get_with_employee, by_job_role, by_job_level (read-only) |
|
|
93
93
|
|
|
94
94
|
### Attendance and Registro Horario
|
|
95
95
|
|
|
96
96
|
Factorial asks employees to record their working hours day by day. `factorial_attendance` lets Claude do that, for one day or for a whole month, and for any employee the API key can see.
|
|
97
97
|
|
|
98
|
-
Times are `HH:MM` in the company's local time, exactly as Factorial shows them. Records written by this server carry `source: "api"`, so they are distinguishable from live clocks in Factorial's own activity log.
|
|
98
|
+
Times are `HH:MM` in the company's local time, exactly as Factorial shows them; Factorial applies them in the company zone and the server never converts between zones. Records written by this server carry `source: "api"`, so they are distinguishable from live clocks in Factorial's own activity log.
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
|
103
|
-
|
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
| `
|
|
108
|
-
| `
|
|
100
|
+
A write's **declared working time** (`date`, `clock_in`, `clock_out`) is independent of its **entry metadata**: Factorial stamps `created_at`, `updated_at` and `in_source`/`out_source` with when and how the record was entered, and those cannot be set or changed through the API. Every create, update, `clock_in`, `clock_out`, and every bulk preview and result, states the declared working time and says this once.
|
|
101
|
+
|
|
102
|
+
| Action | What it does |
|
|
103
|
+
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
104
|
+
| `status` | Whether the employee is clocked in and since when. Always prints the configured identity. |
|
|
105
|
+
| `clock_in`, `clock_out` | Live clocking at the current time, or, given `date` and `time` (`HH:MM` company local), a declared moment for someone who forgot to clock. A declared moment in the future is refused before any request is sent. A declared `clock_out` is refused if nothing is open, or if the moment precedes the open shift's start. |
|
|
106
|
+
| `gaps` | Workdays in a date range where the contract expects more hours than were tracked. Weekends, bank holidays and full-day leave are excluded. |
|
|
107
|
+
| `audit` | One row per calendar day in a range: day type, expected and tracked hours, leave cover, the shifts on record and a status (`complete`, `missing`, `short`, `over`, `weekend`, `bank_holiday`, `on_leave`, `half_day_leave`, `no_contract_data`, `future`). `missing` is nothing on record; `short` is some hours tracked but under expected by more than the tolerance, shown with its delta. A signed-off date is marked separately and is closed for writing; `create_edit_request` is how it gets corrected. The header gives `expected` (bank holidays and leave at full contract minutes) alongside `workday expected` (what tracked hours should actually meet). `statuses` restricts the summary to a given set. `format` is `summary` (default, only the days needing attention), `table` (every day) or `json` (the ledger). The starting point for reconciling what was clocked against what should have been. |
|
|
108
|
+
| `log_range` | Apply a daily pattern (`segments`) to every workable day in a range. Skips weekends, bank holidays, days the contract expects 0 minutes, approved leave, future dates, signed-off dates, `exclude_dates`, and any segment overlapping an existing shift. |
|
|
109
|
+
| `log_days` | Write an explicit list of days with their segments, for migrating from another platform. Only refuses future dates, approved leave, signed-off dates and overlaps, so a Saturday someone worked can be written. |
|
|
110
|
+
| `list`, `get`, `create`, `update`, `delete` | Individual shift records. `list` needs `start_on` and `end_on` (or `ids`, or `updated_at`); Factorial ignores paging on this endpoint, so paging is client-side. `fields: "compact"` on `list` returns a smaller payload (date, clock_in, clock_out, minutes, in_source); `get` returns the complete record. |
|
|
111
|
+
| `list_edit_requests`, `create_edit_request` | Factorial's route for correcting a signed-off day, since hours cannot be written onto a reviewed date directly. Filing a request notifies whoever approves timesheets, so `create_edit_request` is previewed and token-gated even for the configured identity. |
|
|
109
112
|
|
|
110
113
|
```typescript
|
|
111
114
|
// Find the missing days first
|
|
@@ -132,38 +135,45 @@ factorial_attendance({ action: 'audit', start_on: '2026-03-01', end_on: '2026-03
|
|
|
132
135
|
|
|
133
136
|
"Today" for the future-date rule is the date in the zone of the machine running the server, so run it in the company's zone or accept that the boundary day may be off by one. Bank holidays come from the company's own calendar in Factorial (`worked_times.day_type`), so no holiday list is needed. Approved leave is read from `timeoff/leaves`; pass `skip_leave: false` when the source system is right and Factorial's leave record is stale. Half-day leave days are left out of `log_range` and named in the preview; write the worked half with `log_days`.
|
|
134
137
|
|
|
135
|
-
Nobody clocks in at exactly 09:00 every day, and a month of identical entries is the one pattern a real registro never shows. Pass `jitter_minutes` (5 to 10 is sensible) to `log_range` or `log_days` and each written time varies by up to that many minutes from your pattern.
|
|
138
|
+
Nobody clocks in at exactly 09:00 every day, and a month of identical entries is the one pattern a real registro never shows. Pass `jitter_minutes` (5 to 10 is sensible) to `log_range` or `log_days` and each written time varies by up to that many minutes from your pattern, within the day; segments never cross each other. Pass `variation_minutes` for a different kind of variation: it shifts a whole day by one deterministic offset so the start time drifts from day to day, which `jitter_minutes` cannot produce because it only varies segments within a day. Both are derived from the employee, the date and (for jitter) the segment, so the preview lists the exact times that will be written, the confirmation token binds to them, and a retry recognises its own earlier records. The records still carry `source: "api"`; these options make reconstructed hours realistic, they do not disguise where they came from.
|
|
136
139
|
|
|
137
140
|
Every `gaps`, `audit` and bulk-write preview starts with a `Data read` line: how many days of the window have contract data, and how many leave and shift records were read. Reads follow Factorial's pagination to the end, so a window of any length is complete; a date the API returned nothing for is reported as `no_contract_data` and never written, rather than passed off as a day that was not workable. Those dates normally precede the start of employment. If they do not, the read was incomplete and the result should not be trusted.
|
|
138
141
|
|
|
142
|
+
**Signed-off periods.** Once a date's timesheet has been reviewed in Factorial, it is closed for writing; a shift write on it is refused with a 403. `audit` reads `attendance/reviews` alongside the other facts and marks such dates signed off before anything is written; `log_range` and `log_days` skip them the same way they skip a weekend or an approved leave day. The way to correct a signed-off day is `create_edit_request`, which files a request that whoever approves timesheets then decides on; `list_edit_requests` reads what has been filed. Filing a request is previewed and token-gated even for the configured identity, because it notifies a person.
|
|
143
|
+
|
|
144
|
+
A date that does not exist, such as `2026-02-30`, is refused rather than silently rolled forward to the next valid date; a real leap day such as `2024-02-29` is accepted normally.
|
|
145
|
+
|
|
139
146
|
**Auditing a month.** Run `audit` for the range first. A day within `tolerance_minutes` (default 15) of its expected total counts as `complete`, so realistic clock-ins and jittered backfills do not read as shortfalls. Compare the ledger with what you know locally (your calendar, another time-tracking system, days you actually worked on a holiday), then fix the differences: `log_range` or `log_days` for missing days, `delete` or `update` for wrong records, and `audit` again to confirm every workday reads `complete`.
|
|
140
147
|
|
|
141
|
-
|
|
148
|
+
Five prompts wrap these workflows for the user, and a guide resource documents them for the model; see [5 MCP Prompts](#5-mcp-prompts) and `factorial://guides/registro-horario`. Some clients (Claude Code included) surface a prompt only as a slash command the human invokes, with no way for the model itself to read one, so each prompt's procedure is also published as a resource at `factorial://prompts/<name>`.
|
|
142
149
|
|
|
143
150
|
Set `FACTORIAL_EMPLOYEE_ID` to your own employee id so that `employee_id` can be omitted. Writes aimed at anyone else, and every bulk write, require a confirmation token; see [Safety & Security](#safety--security).
|
|
144
151
|
|
|
145
152
|
### 6 MCP Resources
|
|
146
153
|
|
|
147
|
-
| Resource URI | Description
|
|
148
|
-
| ------------------------------------- |
|
|
149
|
-
| `factorial://org-chart` | Complete organizational hierarchy (Markdown)
|
|
150
|
-
| `factorial://guides/registro-horario` | How to audit, fill and maintain a registro horario with this server (Markdown)
|
|
151
|
-
| `factorial://employees/directory` | Employee directory by team (Markdown)
|
|
152
|
-
| `factorial://locations/directory` | Location directory with employee counts (Markdown)
|
|
153
|
-
| `factorial://timeoff/policies` | All leave types and policies (JSON)
|
|
154
|
-
| `factorial://teams/{team_id}` | Team details with member list (JSON, templated)
|
|
154
|
+
| Resource URI | Description |
|
|
155
|
+
| ------------------------------------- | ----------------------------------------------------------------------------------- |
|
|
156
|
+
| `factorial://org-chart` | Complete organizational hierarchy (Markdown) |
|
|
157
|
+
| `factorial://guides/registro-horario` | How to audit, fill and maintain a registro horario with this server (Markdown) |
|
|
158
|
+
| `factorial://employees/directory` | Employee directory by team (Markdown) |
|
|
159
|
+
| `factorial://locations/directory` | Location directory with employee counts (Markdown) |
|
|
160
|
+
| `factorial://timeoff/policies` | All leave types and policies (JSON) |
|
|
161
|
+
| `factorial://teams/{team_id}` | Team details with member list (JSON, templated) |
|
|
162
|
+
| `factorial://prompts/{name}` | The procedure text of an attendance prompt, readable without invoking it (Markdown) |
|
|
155
163
|
|
|
156
164
|
### 5 MCP Prompts
|
|
157
165
|
|
|
158
166
|
Prompts are procedures the user invokes (in Claude Code they appear as `/mcp__factorial__<name>` slash commands). The attendance prompts pre-read the data the procedure starts from and state the exact tool calls that follow, so a small model can carry the workflow through. A prompt never writes anything itself; writes go through `factorial_attendance` and its confirmation gate.
|
|
159
167
|
|
|
160
|
-
| Prompt
|
|
161
|
-
|
|
|
162
|
-
| `attendance_audit`
|
|
163
|
-
| `attendance_fill`
|
|
164
|
-
| `attendance_today`
|
|
165
|
-
| `
|
|
166
|
-
| `
|
|
168
|
+
| Prompt | Arguments | What it does |
|
|
169
|
+
| ---------------------- | -------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
170
|
+
| `attendance_audit` | `start_on`, `end_on`, `employee_id` (all optional) | Runs the audit (default: this month to today, `FACTORIAL_EMPLOYEE_ID`) and asks for a read-only report: expected vs tracked, missing and over days by month, data-coverage warnings. |
|
|
171
|
+
| `attendance_fill` | `segments` (required), `start_on`, `end_on`, `employee_id`, `observations`, `jitter_minutes` | Reads the gaps and hands over the exact `log_range` call with the parsed pattern, then the preview, human confirmation, token, retry and verification steps. `segments` is `"09:00-14:00, 15:00-18:00"`. |
|
|
172
|
+
| `attendance_today` | `segments` (required), `employee_id`, `observations`, `jitter_minutes` | Reads today's status and decides: nothing on weekends, holidays, leave, open shifts or complete days; otherwise `log_days` for today, confirmed in the same session for the configured identity only. |
|
|
173
|
+
| `attendance_reconcile` | `known_absences` (required), `start_on`, `end_on`, `employee_id` | Runs the audit and reports only the days that disagree with a stated list of known absences (days off, sick days, trips). Read-only. |
|
|
174
|
+
| `attendance_fill_days` | `days` (required), `employee_id`, `observations`, `jitter_minutes` | Enters registro horario for a list of explicit dates, each with its own daily pattern, as one `log_days` call: preview, human confirmation, token, retry and verification. `days` is `[{"date":"2026-03-02","segments":"09:00-14:00, 15:00-18:00"}]`. |
|
|
175
|
+
| `summarize_team` | `team_id` | Team summary with members and roles. |
|
|
176
|
+
| `time_off_report` | `employee_id` | Time off report for an employee: allowances and recent leaves. |
|
|
167
177
|
|
|
168
178
|
**Running the daily record on a schedule.** MCP has no scheduler, so the schedule lives in the client. In Claude Code, `/schedule` creates a routine that invokes `attendance_today` with your pattern, and `/loop` repeats it while a session is open; any cron can run `claude -p` with the prompt as its input. The prompt writes only when today is a workday with nothing tracked, and only for the employee in `FACTORIAL_EMPLOYEE_ID`; it reports one line either way. The record it produces is a legal document of hours worked, so the pattern you schedule must be the hours you actually work, and the day you do not work needs a leave record or a manual correction.
|
|
169
179
|
|
|
@@ -400,6 +410,7 @@ Always gated, whatever the target, because volume is its own hazard:
|
|
|
400
410
|
|
|
401
411
|
- `factorial_attendance({ action: 'log_range' })` - Writes one or more shift records per workable day in a range
|
|
402
412
|
- `factorial_attendance({ action: 'log_days' })` - Writes an explicit list of days
|
|
413
|
+
- `factorial_attendance({ action: 'create_edit_request' })` - Files a request to change a timesheet, which notifies a person, so it is gated even for the configured identity
|
|
403
414
|
|
|
404
415
|
Re-running a bulk call after a partial failure is safe against its own earlier writes: the planner re-reads existing shifts and skips whatever overlaps. It does not protect against another writer between the read and the writes.
|
|
405
416
|
|
package/dist/api/attendance.d.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* - estimated_times and worked_times require employee_ids[] and start_on.
|
|
11
11
|
*/
|
|
12
12
|
import { type PaginatedResponse } from '../pagination.js';
|
|
13
|
-
import { type Shift, type OpenShift, type EstimatedTime, type WorkedTime, type CreateShiftInput, type UpdateShiftInput, type ClockInput } from '../schemas.js';
|
|
13
|
+
import { type Shift, type OpenShift, type EstimatedTime, type WorkedTime, type AttendanceReview, type EditTimesheetRequest, type CreateEditTimesheetRequestInput, type CreateShiftInput, type UpdateShiftInput, type ClockInput } from '../schemas.js';
|
|
14
14
|
import type { ListShiftsOptions, DailyTimesOptions } from '../types.js';
|
|
15
15
|
/**
|
|
16
16
|
* Format a Date as ISO 8601 with the offset of the machine running the server,
|
|
@@ -44,6 +44,22 @@ export declare function listOpenShifts(employeeId?: number): Promise<OpenShift[]
|
|
|
44
44
|
export declare function listEstimatedTimes(options: DailyTimesOptions): Promise<EstimatedTime[]>;
|
|
45
45
|
/** Tracked minutes and day type per day; the holiday calendar surfaces here */
|
|
46
46
|
export declare function listWorkedTimes(options: DailyTimesOptions): Promise<WorkedTime[]>;
|
|
47
|
+
/**
|
|
48
|
+
* Dates whose timesheet has been signed off, which are closed for writing.
|
|
49
|
+
*
|
|
50
|
+
* This is the only read that answers "can I write to this date". There is no
|
|
51
|
+
* period or lock resource in the 2026-07-01 API; a reviewed date is the lock.
|
|
52
|
+
*/
|
|
53
|
+
export declare function listReviews(options: DailyTimesOptions): Promise<AttendanceReview[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Edit timesheet requests, Factorial's route for changing a signed-off day.
|
|
56
|
+
*
|
|
57
|
+
* Hours cannot be written directly onto a reviewed date; a request is filed and
|
|
58
|
+
* whoever approves timesheets decides.
|
|
59
|
+
*/
|
|
60
|
+
export declare function listEditTimesheetRequests(employeeIds?: number[]): Promise<EditTimesheetRequest[]>;
|
|
61
|
+
/** File a request to change a timesheet. This notifies whoever approves them. */
|
|
62
|
+
export declare function createEditTimesheetRequest(input: CreateEditTimesheetRequestInput): Promise<EditTimesheetRequest>;
|
|
47
63
|
/** Clock an employee in now */
|
|
48
64
|
export declare function clockIn(input: ClockInput, now?: Date): Promise<Shift>;
|
|
49
65
|
/** Clock an employee out now */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attendance.d.ts","sourceRoot":"","sources":["../../src/api/attendance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,
|
|
1
|
+
{"version":3,"file":"attendance.d.ts","sourceRoot":"","sources":["../../src/api/attendance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAWL,KAAK,KAAK,EACV,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,+BAA+B,EACpC,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EAChB,MAAM,eAAe,CAAC;AAMvB,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAExE;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAUjD;AAED,8EAA8E;AAC9E,wBAAgB,UAAU,CAAC,GAAG,GAAE,IAAiB,GAAG,MAAM,CAEzD;AA+BD;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CA4BnC;AAED,+EAA+E;AAC/E,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EAAE,EACrB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,KAAK,EAAE,CAAC,CAKlB;AAED,iCAAiC;AACjC,wBAAsB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAIzD;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC,CAWzE;AAED,qBAAqB;AACrB,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC,CAQrF;AAED,qBAAqB;AACrB,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM3D;AAED,yDAAyD;AACzD,wBAAsB,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAM9E;AAED,gEAAgE;AAChE,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAS7F;AAED,+EAA+E;AAC/E,wBAAsB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CASvF;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CASzF;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,WAAW,CAAC,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAKjC;AAED,iFAAiF;AACjF,wBAAsB,0BAA0B,CAC9C,KAAK,EAAE,+BAA+B,GACrC,OAAO,CAAC,oBAAoB,CAAC,CAY/B;AAuBD,+BAA+B;AAC/B,wBAAsB,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,GAAE,IAAiB,GAAG,OAAO,CAAC,KAAK,CAAC,CAEvF;AAED,gCAAgC;AAChC,wBAAsB,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,GAAE,IAAiB,GAAG,OAAO,CAAC,KAAK,CAAC,CAExF"}
|
package/dist/api/attendance.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import { fetchList, fetchOne, postOne, patchOne, deleteOne, factorialRequest, } from '../http-client.js';
|
|
13
13
|
import { cache } from '../cache.js';
|
|
14
14
|
import { buildPaginationParams, sliceForPagination, } from '../pagination.js';
|
|
15
|
-
import { ShiftSchema, OpenShiftSchema, EstimatedTimeSchema, WorkedTimeSchema, CreateShiftInputSchema, UpdateShiftInputSchema, ClockInputSchema, } from '../schemas.js';
|
|
15
|
+
import { ShiftSchema, OpenShiftSchema, EstimatedTimeSchema, WorkedTimeSchema, AttendanceReviewSchema, EditTimesheetRequestSchema, CreateEditTimesheetRequestInputSchema, CreateShiftInputSchema, UpdateShiftInputSchema, ClockInputSchema, } from '../schemas.js';
|
|
16
16
|
import { parseData, parseArray } from '../schemas/shared.js';
|
|
17
17
|
import { AuditAction, auditedOperation } from '../audit.js';
|
|
18
18
|
import { validateId } from '../utils.js';
|
|
@@ -164,6 +164,43 @@ export async function listWorkedTimes(options) {
|
|
|
164
164
|
});
|
|
165
165
|
return parseArray('WorkedTime', WorkedTimeSchema, data);
|
|
166
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* Dates whose timesheet has been signed off, which are closed for writing.
|
|
169
|
+
*
|
|
170
|
+
* This is the only read that answers "can I write to this date". There is no
|
|
171
|
+
* period or lock resource in the 2026-07-01 API; a reviewed date is the lock.
|
|
172
|
+
*/
|
|
173
|
+
export async function listReviews(options) {
|
|
174
|
+
const data = await fetchList(ENDPOINTS.reviews, {
|
|
175
|
+
params: {
|
|
176
|
+
employee_ids: options.employee_ids,
|
|
177
|
+
start_on: options.start_on,
|
|
178
|
+
end_on: options.end_on,
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
return parseArray('AttendanceReview', AttendanceReviewSchema, data);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Edit timesheet requests, Factorial's route for changing a signed-off day.
|
|
185
|
+
*
|
|
186
|
+
* Hours cannot be written directly onto a reviewed date; a request is filed and
|
|
187
|
+
* whoever approves timesheets decides.
|
|
188
|
+
*/
|
|
189
|
+
export async function listEditTimesheetRequests(employeeIds) {
|
|
190
|
+
const data = await fetchList(ENDPOINTS.editTimesheetRequests, {
|
|
191
|
+
params: { employee_ids: employeeIds },
|
|
192
|
+
});
|
|
193
|
+
return parseArray('EditTimesheetRequest', EditTimesheetRequestSchema, data);
|
|
194
|
+
}
|
|
195
|
+
/** File a request to change a timesheet. This notifies whoever approves them. */
|
|
196
|
+
export async function createEditTimesheetRequest(input) {
|
|
197
|
+
const body = CreateEditTimesheetRequestInputSchema.parse(input);
|
|
198
|
+
return auditedOperation(AuditAction.CREATE, 'edit_timesheet_request', body.employee_id, async () => {
|
|
199
|
+
const created = await postOne(ENDPOINTS.editTimesheetRequests, body);
|
|
200
|
+
cache.invalidatePrefix('shifts');
|
|
201
|
+
return parseData('EditTimesheetRequest', EditTimesheetRequestSchema, created);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
167
204
|
async function clockAction(action, input, now) {
|
|
168
205
|
const body = ClockInputSchema.parse(input);
|
|
169
206
|
const endpoint = action === 'clock_in' ? ENDPOINTS.clockIn : ENDPOINTS.clockOut;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attendance.js","sourceRoot":"","sources":["../../src/api/attendance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,SAAS,EACT,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,SAAS,EACT,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EACL,qBAAqB,EACrB,kBAAkB,GAEnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,WAAW,EACX,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"attendance.js","sourceRoot":"","sources":["../../src/api/attendance.ts"],"names":[],"mappings":"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"}
|
package/dist/api/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export { listTeams, getTeam, createTeam, updateTeam, deleteTeam } from './teams.
|
|
|
11
11
|
export { listLocations, getLocation, createLocation, updateLocation, deleteLocation, } from './locations.js';
|
|
12
12
|
export { listContracts, getLatestContract, getEmployeeWithContract, listEmployeesByJobRole, listEmployeesByJobLevel, type EmployeeWithContract, } from './contracts.js';
|
|
13
13
|
export { listLeaves, listLeavesInRange, getLeave, listLeaveTypes, getLeaveType, listAllowances, createLeave, updateLeave, cancelLeave, approveLeave, rejectLeave, } from './time-off.js';
|
|
14
|
-
export { listShifts, listShiftsInRange, getShift, createShift, updateShift, deleteShift, listOpenShifts, listEstimatedTimes, listWorkedTimes, clockIn, clockOut, formatLocalIso, localToday, } from './attendance.js';
|
|
14
|
+
export { listShifts, listShiftsInRange, getShift, createShift, updateShift, deleteShift, listOpenShifts, listEstimatedTimes, listWorkedTimes, clockIn, clockOut, formatLocalIso, localToday, listEditTimesheetRequests, createEditTimesheetRequest, } from './attendance.js';
|
|
15
15
|
export { listFolders, getFolder, listDocuments, getDocument, getDocumentDownloadUrls, downloadDocument, downloadEmployeePayslips, downloadEmployeeDocument, } from './documents.js';
|
|
16
16
|
export { listJobRoles, getJobRole, listJobLevels, getJobLevel } from './job-catalog.js';
|
|
17
17
|
export { listProjects, getProject, listProjectTasks, getProjectTask, listProjectWorkers, getProjectWorker, listTimeRecords, getTimeRecord, createProject, updateProject, deleteProject, createProjectTask, updateProjectTask, deleteProjectTask, assignProjectWorker, removeProjectWorker, createTimeRecord, updateTimeRecord, deleteTimeRecord, } from './projects.js';
|
package/dist/api/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG1D,OAAO,EACL,aAAa,EACb,WAAW,EACX,eAAe,EACf,cAAc,EACd,cAAc,EACd,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGpF,OAAO,EACL,aAAa,EACb,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,GACf,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,KAAK,oBAAoB,GAC1B,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,cAAc,EACd,WAAW,EACX,WAAW,EACX,WAAW,EACX,YAAY,EACZ,WAAW,GACZ,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,QAAQ,EACR,WAAW,EACX,WAAW,EACX,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,OAAO,EACP,QAAQ,EACR,cAAc,EACd,UAAU,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG1D,OAAO,EACL,aAAa,EACb,WAAW,EACX,eAAe,EACf,cAAc,EACd,cAAc,EACd,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGpF,OAAO,EACL,aAAa,EACb,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,GACf,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,KAAK,oBAAoB,GAC1B,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,cAAc,EACd,WAAW,EACX,WAAW,EACX,WAAW,EACX,YAAY,EACZ,WAAW,GACZ,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,QAAQ,EACR,WAAW,EACX,WAAW,EACX,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,OAAO,EACP,QAAQ,EACR,cAAc,EACd,UAAU,EACV,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,WAAW,EACX,SAAS,EACT,aAAa,EACb,WAAW,EACX,uBAAuB,EACvB,gBAAgB,EAChB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGxF,OAAO,EACL,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,aAAa,EACb,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,aAAa,EACb,WAAW,EACX,cAAc,EACd,cAAc,EACd,eAAe,EACf,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,eAAe,EACf,aAAa,EACb,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,cAAc,CAAC"}
|
package/dist/api/index.js
CHANGED
|
@@ -18,7 +18,7 @@ export { listContracts, getLatestContract, getEmployeeWithContract, listEmployee
|
|
|
18
18
|
// Time Off
|
|
19
19
|
export { listLeaves, listLeavesInRange, getLeave, listLeaveTypes, getLeaveType, listAllowances, createLeave, updateLeave, cancelLeave, approveLeave, rejectLeave, } from './time-off.js';
|
|
20
20
|
// Attendance
|
|
21
|
-
export { listShifts, listShiftsInRange, getShift, createShift, updateShift, deleteShift, listOpenShifts, listEstimatedTimes, listWorkedTimes, clockIn, clockOut, formatLocalIso, localToday, } from './attendance.js';
|
|
21
|
+
export { listShifts, listShiftsInRange, getShift, createShift, updateShift, deleteShift, listOpenShifts, listEstimatedTimes, listWorkedTimes, clockIn, clockOut, formatLocalIso, localToday, listEditTimesheetRequests, createEditTimesheetRequest, } from './attendance.js';
|
|
22
22
|
// Documents
|
|
23
23
|
export { listFolders, getFolder, listDocuments, getDocument, getDocumentDownloadUrls, downloadDocument, downloadEmployeePayslips, downloadEmployeeDocument, } from './documents.js';
|
|
24
24
|
// Job Catalog
|
package/dist/api/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,mBAAmB;AACnB,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE1D,YAAY;AACZ,OAAO,EACL,aAAa,EACb,WAAW,EACX,eAAe,EACf,cAAc,EACd,cAAc,EACd,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAExB,QAAQ;AACR,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEpF,YAAY;AACZ,OAAO,EACL,aAAa,EACb,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,GACf,MAAM,gBAAgB,CAAC;AAExB,YAAY;AACZ,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,GAExB,MAAM,gBAAgB,CAAC;AAExB,WAAW;AACX,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,cAAc,EACd,WAAW,EACX,WAAW,EACX,WAAW,EACX,YAAY,EACZ,WAAW,GACZ,MAAM,eAAe,CAAC;AAEvB,aAAa;AACb,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,QAAQ,EACR,WAAW,EACX,WAAW,EACX,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,OAAO,EACP,QAAQ,EACR,cAAc,EACd,UAAU,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,mBAAmB;AACnB,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE1D,YAAY;AACZ,OAAO,EACL,aAAa,EACb,WAAW,EACX,eAAe,EACf,cAAc,EACd,cAAc,EACd,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAExB,QAAQ;AACR,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEpF,YAAY;AACZ,OAAO,EACL,aAAa,EACb,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,GACf,MAAM,gBAAgB,CAAC;AAExB,YAAY;AACZ,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,GAExB,MAAM,gBAAgB,CAAC;AAExB,WAAW;AACX,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,cAAc,EACd,WAAW,EACX,WAAW,EACX,WAAW,EACX,YAAY,EACZ,WAAW,GACZ,MAAM,eAAe,CAAC;AAEvB,aAAa;AACb,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,QAAQ,EACR,WAAW,EACX,WAAW,EACX,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,OAAO,EACP,QAAQ,EACR,cAAc,EACd,UAAU,EACV,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,iBAAiB,CAAC;AAEzB,YAAY;AACZ,OAAO,EACL,WAAW,EACX,SAAS,EACT,aAAa,EACb,WAAW,EACX,uBAAuB,EACvB,gBAAgB,EAChB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,gBAAgB,CAAC;AAExB,cAAc;AACd,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAExF,WAAW;AACX,OAAO,EACL,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,eAAe,CAAC;AAEvB,WAAW;AACX,OAAO,EACL,aAAa,EACb,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AAEvB,aAAa;AACb,OAAO,EACL,aAAa,EACb,WAAW,EACX,cAAc,EACd,cAAc,EACd,eAAe,EACf,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAEzB,mBAAmB;AACnB,OAAO,EACL,eAAe,EACf,aAAa,EACb,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAElB,UAAU;AACV,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,cAAc,CAAC"}
|
|
@@ -24,16 +24,31 @@ export declare function buildLedger(employeeId: number, startOn: string, endOn:
|
|
|
24
24
|
ledger: LedgerDay[];
|
|
25
25
|
coverage: FactsCoverage;
|
|
26
26
|
}>;
|
|
27
|
+
/**
|
|
28
|
+
* How many failures in a row mean the problem is the request rather than the
|
|
29
|
+
* record. A bad key or a revoked scope fails every write; grinding through
|
|
30
|
+
* hundreds of certain rejections helps nobody.
|
|
31
|
+
*/
|
|
32
|
+
export declare const CONSECUTIVE_FAILURE_ABORT = 10;
|
|
27
33
|
export interface BackfillResult {
|
|
28
34
|
written: PlannedWrite[];
|
|
29
35
|
failed: Array<PlannedWrite & {
|
|
30
36
|
error: string;
|
|
31
37
|
}>;
|
|
38
|
+
/** Records left unattempted because the run aborted */
|
|
39
|
+
notAttempted: PlannedWrite[];
|
|
40
|
+
abortedEarly: boolean;
|
|
32
41
|
}
|
|
33
42
|
/**
|
|
34
|
-
* Write the planned records sequentially
|
|
35
|
-
*
|
|
36
|
-
*
|
|
43
|
+
* Write the planned records sequentially, attempting every one.
|
|
44
|
+
*
|
|
45
|
+
* An earlier version stopped at the first failure, which turned a fill that
|
|
46
|
+
* touched one bad month into one pass per surviving stretch. A single refused
|
|
47
|
+
* record says nothing about the next one, so the run continues; only a run of
|
|
48
|
+
* consecutive failures is evidence of something systemic, and that aborts.
|
|
49
|
+
*
|
|
50
|
+
* Re-running the identical call stays safe: the planner re-reads shifts and
|
|
51
|
+
* skips whatever overlaps.
|
|
37
52
|
*/
|
|
38
53
|
export declare function executeBackfill(employeeId: number, writes: PlannedWrite[], observations?: string): Promise<BackfillResult>;
|
|
39
54
|
/** The dates a request spans, for the preview header */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backfill.d.ts","sourceRoot":"","sources":["../../src/attendance/backfill.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"backfill.d.ts","sourceRoot":"","sources":["../../src/attendance/backfill.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,OAAO,EAOL,KAAK,YAAY,EAEjB,KAAK,aAAa,EAClB,KAAK,GAAG,EACR,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,cAAc,CAAC;AAEtB,yEAAyE;AACzE,wBAAsB,WAAW,CAC/B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,GAAG,GAAE,IAAiB,GACrB,OAAO,CAAC,SAAS,CAAC,CA2EpB;AAOD,2BAA2B;AAC3B,wBAAsB,YAAY,CAChC,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC,CAGnD;AAED,gEAAgE;AAChE,wBAAsB,QAAQ,CAC5B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC;IAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,CAAC,CAGnD;AAED,uFAAuF;AACvF,wBAAsB,WAAW,CAC/B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC;IAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,CAAC,CAM3D;AAED;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAE5C,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,MAAM,EAAE,KAAK,CAAC,YAAY,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,uDAAuD;IACvD,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,YAAY,EAAE,EACtB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,cAAc,CAAC,CAqCzB;AAED,wDAAwD;AACxD,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAIlF"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* cache before planning and after writing whatever happened in between.
|
|
8
8
|
*/
|
|
9
9
|
import { cache } from '../cache.js';
|
|
10
|
-
import { createShift, listEstimatedTimes, listShiftsInRange, listWorkedTimes, localToday, } from '../api/attendance.js';
|
|
10
|
+
import { createShift, listEstimatedTimes, listReviews, listShiftsInRange, listWorkedTimes, localToday, } from '../api/attendance.js';
|
|
11
11
|
import { listLeavesInRange } from '../api/time-off.js';
|
|
12
12
|
import { buildBackfillPlan, computeGaps, computeLedger, enumerateDates, expandLeaves, measureCoverage, } from './planner.js';
|
|
13
13
|
/** Read everything the planner needs for one employee and date window */
|
|
@@ -19,13 +19,30 @@ export async function gatherFacts(employeeId, startOn, endOn, now = new Date())
|
|
|
19
19
|
// meta.has_next_page). estimated_times and worked_times page at 100 days,
|
|
20
20
|
// so a single-page read once made every window over 100 days go blind
|
|
21
21
|
// after day 100 and report the rest as not workable.
|
|
22
|
+
// listReviews is the only read this function isolates: it is a newer,
|
|
23
|
+
// less-verified signal (verified against one tenant on one day) than the
|
|
24
|
+
// others, and it fails closed for writing (daySkipReason treats a date not
|
|
25
|
+
// in facts.reviews as not signed off). Letting it reject the whole
|
|
26
|
+
// Promise.all would turn one tenant's 403 or schema mismatch on this one
|
|
27
|
+
// endpoint into a hard outage of every attendance read (audit, gaps,
|
|
28
|
+
// log_range, log_days and all five prompts), not just the signed-off
|
|
29
|
+
// signal it actually carries.
|
|
22
30
|
const range = { employee_ids: [employeeId], start_on: startOn, end_on: endOn };
|
|
23
|
-
const [worked, estimated, shifts, leaves] = await Promise.all([
|
|
31
|
+
const [worked, estimated, shifts, leaves, reviewsResult] = await Promise.all([
|
|
24
32
|
listWorkedTimes(range),
|
|
25
33
|
listEstimatedTimes(range),
|
|
26
34
|
listShiftsInRange([employeeId], startOn, endOn),
|
|
27
35
|
listLeavesInRange([employeeId], startOn, endOn),
|
|
36
|
+
listReviews(range).then((reviews) => ({
|
|
37
|
+
reviews,
|
|
38
|
+
error: null,
|
|
39
|
+
}), (error) => ({
|
|
40
|
+
reviews: [],
|
|
41
|
+
error: error instanceof Error ? error.message : String(error),
|
|
42
|
+
})),
|
|
28
43
|
]);
|
|
44
|
+
const reviews = reviewsResult.reviews;
|
|
45
|
+
const reviewsError = reviewsResult.error;
|
|
29
46
|
const days = new Map();
|
|
30
47
|
for (const day of worked) {
|
|
31
48
|
days.set(day.date, {
|
|
@@ -54,7 +71,8 @@ export async function gatherFacts(employeeId, startOn, endOn, now = new Date())
|
|
|
54
71
|
.filter(s => s.clock_in !== null)
|
|
55
72
|
.map(s => ({ date: s.date, clock_in: s.clock_in, clock_out: s.clock_out })),
|
|
56
73
|
leaves: expandLeaves(leaves),
|
|
57
|
-
|
|
74
|
+
reviews: new Set(reviews.map(review => review.date)),
|
|
75
|
+
coverage: measureCoverage(enumerateDates(startOn, endOn), days, leaves.length, shifts.length, reviews.length, reviewsError),
|
|
58
76
|
};
|
|
59
77
|
}
|
|
60
78
|
function coverageOf(facts) {
|
|
@@ -81,14 +99,37 @@ export async function buildLedger(employeeId, startOn, endOn, toleranceMinutes)
|
|
|
81
99
|
};
|
|
82
100
|
}
|
|
83
101
|
/**
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
102
|
+
* How many failures in a row mean the problem is the request rather than the
|
|
103
|
+
* record. A bad key or a revoked scope fails every write; grinding through
|
|
104
|
+
* hundreds of certain rejections helps nobody.
|
|
105
|
+
*/
|
|
106
|
+
export const CONSECUTIVE_FAILURE_ABORT = 10;
|
|
107
|
+
/**
|
|
108
|
+
* Write the planned records sequentially, attempting every one.
|
|
109
|
+
*
|
|
110
|
+
* An earlier version stopped at the first failure, which turned a fill that
|
|
111
|
+
* touched one bad month into one pass per surviving stretch. A single refused
|
|
112
|
+
* record says nothing about the next one, so the run continues; only a run of
|
|
113
|
+
* consecutive failures is evidence of something systemic, and that aborts.
|
|
114
|
+
*
|
|
115
|
+
* Re-running the identical call stays safe: the planner re-reads shifts and
|
|
116
|
+
* skips whatever overlaps.
|
|
87
117
|
*/
|
|
88
118
|
export async function executeBackfill(employeeId, writes, observations) {
|
|
89
|
-
const result = {
|
|
119
|
+
const result = {
|
|
120
|
+
written: [],
|
|
121
|
+
failed: [],
|
|
122
|
+
notAttempted: [],
|
|
123
|
+
abortedEarly: false,
|
|
124
|
+
};
|
|
125
|
+
let consecutiveFailures = 0;
|
|
90
126
|
try {
|
|
91
|
-
for (const write of writes) {
|
|
127
|
+
for (const [index, write] of writes.entries()) {
|
|
128
|
+
if (consecutiveFailures >= CONSECUTIVE_FAILURE_ABORT) {
|
|
129
|
+
result.notAttempted = writes.slice(index);
|
|
130
|
+
result.abortedEarly = true;
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
92
133
|
try {
|
|
93
134
|
await createShift({
|
|
94
135
|
employee_id: employeeId,
|
|
@@ -98,13 +139,14 @@ export async function executeBackfill(employeeId, writes, observations) {
|
|
|
98
139
|
observations,
|
|
99
140
|
});
|
|
100
141
|
result.written.push(write);
|
|
142
|
+
consecutiveFailures = 0;
|
|
101
143
|
}
|
|
102
144
|
catch (error) {
|
|
103
145
|
result.failed.push({
|
|
104
146
|
...write,
|
|
105
147
|
error: error instanceof Error ? error.message : String(error),
|
|
106
148
|
});
|
|
107
|
-
|
|
149
|
+
consecutiveFailures += 1;
|
|
108
150
|
}
|
|
109
151
|
}
|
|
110
152
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backfill.js","sourceRoot":"","sources":["../../src/attendance/backfill.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,UAAU,GACX,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"backfill.js","sourceRoot":"","sources":["../../src/attendance/backfill.ts"],"names":[],"mappings":"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"}
|