@serviceai/api-spec 1.2.418 → 1.2.420
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/openapi.json +791 -41
- package/openapi.yaml +720 -39
- package/package.json +1 -1
- package/types.d.ts +382 -33
package/types.d.ts
CHANGED
|
@@ -1065,7 +1065,7 @@ export interface paths {
|
|
|
1065
1065
|
"application/json": ({
|
|
1066
1066
|
[key: string]: unknown;
|
|
1067
1067
|
} & {
|
|
1068
|
-
/** @description RoomPlan-classified doors. Distinct from `windows[]` and `openings[]`; append-room `entryDoorwayId` tokens of the form `…-door-<idx>` resolve into THIS array only. */
|
|
1068
|
+
/** @description RoomPlan-classified doors. Distinct from `windows[]` and `openings[]`; append-room `entryDoorwayId` tokens of the form `…-door-<idx>` resolve into THIS array only. A door carrying `duplicateOf` is the hidden copy of a shared doorway (one door per doorway, from the room scanned first). */
|
|
1069
1069
|
doors?: {
|
|
1070
1070
|
position: {
|
|
1071
1071
|
x: number;
|
|
@@ -1079,6 +1079,13 @@ export interface paths {
|
|
|
1079
1079
|
swingHand?: "left" | "right" | "none";
|
|
1080
1080
|
/** @enum {string} */
|
|
1081
1081
|
placementSource?: "auto" | "manual";
|
|
1082
|
+
/** @description Present only on the later-scanned room's copy of a doorway two rooms in this response share (the rooms are linked by a door link, or their doors coincide on one wall). Skip this door's glyph and keep its wall gap; the door it names is the one to draw. Absent on every other door. Read-time only: never send it back, it is never stored. */
|
|
1083
|
+
duplicateOf?: {
|
|
1084
|
+
/** @description Id of the room whose copy of this doorway is drawn. */
|
|
1085
|
+
roomId: number;
|
|
1086
|
+
/** @description Index into that room's `doors[]`. */
|
|
1087
|
+
doorIndex: number;
|
|
1088
|
+
};
|
|
1082
1089
|
}[];
|
|
1083
1090
|
/** @description RoomPlan-classified windows. Distinct from `doors[]` and `openings[]`; no append-room `entryDoorwayId` ever resolves into this array (windows are not traversable). */
|
|
1084
1091
|
windows?: {
|
|
@@ -1196,7 +1203,7 @@ export interface paths {
|
|
|
1196
1203
|
rooms: ({
|
|
1197
1204
|
[key: string]: unknown;
|
|
1198
1205
|
} & {
|
|
1199
|
-
/** @description RoomPlan-classified doors. Distinct from `windows[]` and `openings[]`; append-room `entryDoorwayId` tokens of the form `…-door-<idx>` resolve into THIS array only. */
|
|
1206
|
+
/** @description RoomPlan-classified doors. Distinct from `windows[]` and `openings[]`; append-room `entryDoorwayId` tokens of the form `…-door-<idx>` resolve into THIS array only. A door carrying `duplicateOf` is the hidden copy of a shared doorway (one door per doorway, from the room scanned first). */
|
|
1200
1207
|
doors?: {
|
|
1201
1208
|
position: {
|
|
1202
1209
|
x: number;
|
|
@@ -1210,6 +1217,13 @@ export interface paths {
|
|
|
1210
1217
|
swingHand?: "left" | "right" | "none";
|
|
1211
1218
|
/** @enum {string} */
|
|
1212
1219
|
placementSource?: "auto" | "manual";
|
|
1220
|
+
/** @description Present only on the later-scanned room's copy of a doorway two rooms in this response share (the rooms are linked by a door link, or their doors coincide on one wall). Skip this door's glyph and keep its wall gap; the door it names is the one to draw. Absent on every other door. Read-time only: never send it back, it is never stored. */
|
|
1221
|
+
duplicateOf?: {
|
|
1222
|
+
/** @description Id of the room whose copy of this doorway is drawn. */
|
|
1223
|
+
roomId: number;
|
|
1224
|
+
/** @description Index into that room's `doors[]`. */
|
|
1225
|
+
doorIndex: number;
|
|
1226
|
+
};
|
|
1213
1227
|
}[];
|
|
1214
1228
|
/** @description RoomPlan-classified windows. Distinct from `doors[]` and `openings[]`; no append-room `entryDoorwayId` ever resolves into this array (windows are not traversable). */
|
|
1215
1229
|
windows?: {
|
|
@@ -1929,9 +1943,15 @@ export interface paths {
|
|
|
1929
1943
|
device?: "ios" | "web" | "android" | null;
|
|
1930
1944
|
/**
|
|
1931
1945
|
* Format: date-time
|
|
1932
|
-
* @description When the tap happened. The server clamps it.
|
|
1946
|
+
* @description When the tap happened, by the phone's clock. The server checks it against its own (tapElapsedMs) and clamps it. From the web (device 'web') it is ignored: the server's receipt time is used.
|
|
1933
1947
|
*/
|
|
1934
1948
|
occurredAt?: string | null;
|
|
1949
|
+
/** @description Milliseconds from the tap to this send, from the phone's monotonic clock (a stopwatch the person can't change). An offline replay sends the time since the tap. The server's tap time is its own clock when the request arrives minus this. Within 2 minutes of the phone's time, the phone's time stands (never later than the tap); further apart, the server's tap time is recorded and the office is asked to look. A Clock Out or job time stop it proves this way keeps its real time however old; without it, a stop older than 12 hours is recorded at the 12-hour limit and flagged (T6). Send it with every queued tap, clock-outs included. */
|
|
1950
|
+
tapElapsedMs?: number | null;
|
|
1951
|
+
/** @description True when the phone restarted between the tap and this send, so there is no stopwatch reading (send no tapElapsedMs). A tap more than 2 minutes old keeps the phone's time and is flagged for the office. */
|
|
1952
|
+
tapTimeUnverified?: boolean | null;
|
|
1953
|
+
/** @description True when the phone's clock was changed by hand since the phone last synced. The tap is flagged for the office. */
|
|
1954
|
+
deviceClockChanged?: boolean | null;
|
|
1935
1955
|
notes?: string | null;
|
|
1936
1956
|
};
|
|
1937
1957
|
};
|
|
@@ -1964,7 +1984,7 @@ export interface paths {
|
|
|
1964
1984
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
1965
1985
|
};
|
|
1966
1986
|
};
|
|
1967
|
-
/** @description Time tracking access denied,
|
|
1987
|
+
/** @description Time tracking access denied, no organization on the session, or code PAYROLL_OFF: the company has the time tracking add-on off (GET /api/time-tracking/day says payrollAddon: false). Don't retry; hide Clock In/Out and the other payroll controls. */
|
|
1968
1988
|
403: {
|
|
1969
1989
|
headers: {
|
|
1970
1990
|
[name: string]: unknown;
|
|
@@ -2013,7 +2033,10 @@ export interface paths {
|
|
|
2013
2033
|
};
|
|
2014
2034
|
get?: never;
|
|
2015
2035
|
put?: never;
|
|
2016
|
-
/**
|
|
2036
|
+
/**
|
|
2037
|
+
* End my day: the paid day only. Job time (fence or job timer) runs until it is stopped or the phone reports leaving, and is never paid past Clock Out.
|
|
2038
|
+
* @description A late Clock Out (T6): with tapElapsedMs proving its time, it keeps its real time however old. When the safety net already closed the day (the automatic close), a proven Clock Out earlier than that close replaces it (replacedAutoClose, flagged for the office); anything else about that day is flagged for the office and changes nothing. A proven Clock Out from before the running day started never ends the running day.
|
|
2039
|
+
*/
|
|
2017
2040
|
post: {
|
|
2018
2041
|
parameters: {
|
|
2019
2042
|
query?: never;
|
|
@@ -2036,15 +2059,21 @@ export interface paths {
|
|
|
2036
2059
|
device?: "ios" | "web" | "android" | null;
|
|
2037
2060
|
/**
|
|
2038
2061
|
* Format: date-time
|
|
2039
|
-
* @description When the tap happened. The server clamps it.
|
|
2062
|
+
* @description When the tap happened, by the phone's clock. The server checks it against its own (tapElapsedMs) and clamps it. From the web (device 'web') it is ignored: the server's receipt time is used.
|
|
2040
2063
|
*/
|
|
2041
2064
|
occurredAt?: string | null;
|
|
2065
|
+
/** @description Milliseconds from the tap to this send, from the phone's monotonic clock (a stopwatch the person can't change). An offline replay sends the time since the tap. The server's tap time is its own clock when the request arrives minus this. Within 2 minutes of the phone's time, the phone's time stands (never later than the tap); further apart, the server's tap time is recorded and the office is asked to look. A Clock Out or job time stop it proves this way keeps its real time however old; without it, a stop older than 12 hours is recorded at the 12-hour limit and flagged (T6). Send it with every queued tap, clock-outs included. */
|
|
2066
|
+
tapElapsedMs?: number | null;
|
|
2067
|
+
/** @description True when the phone restarted between the tap and this send, so there is no stopwatch reading (send no tapElapsedMs). A tap more than 2 minutes old keeps the phone's time and is flagged for the office. */
|
|
2068
|
+
tapTimeUnverified?: boolean | null;
|
|
2069
|
+
/** @description True when the phone's clock was changed by hand since the phone last synced. The tap is flagged for the office. */
|
|
2070
|
+
deviceClockChanged?: boolean | null;
|
|
2042
2071
|
note?: string | null;
|
|
2043
2072
|
};
|
|
2044
2073
|
};
|
|
2045
2074
|
};
|
|
2046
2075
|
responses: {
|
|
2047
|
-
/** @description Day ended. */
|
|
2076
|
+
/** @description Day ended, or the automatic close of the day this tap belongs to replaced (replacedAutoClose). */
|
|
2048
2077
|
200: {
|
|
2049
2078
|
headers: {
|
|
2050
2079
|
[name: string]: unknown;
|
|
@@ -2052,7 +2081,7 @@ export interface paths {
|
|
|
2052
2081
|
content: {
|
|
2053
2082
|
"application/json": {
|
|
2054
2083
|
day: components["schemas"]["WorkDay"] & (Record<string, never> | null);
|
|
2055
|
-
|
|
2084
|
+
replacedAutoClose?: boolean;
|
|
2056
2085
|
};
|
|
2057
2086
|
};
|
|
2058
2087
|
};
|
|
@@ -2065,7 +2094,7 @@ export interface paths {
|
|
|
2065
2094
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2066
2095
|
};
|
|
2067
2096
|
};
|
|
2068
|
-
/** @description Time tracking access denied,
|
|
2097
|
+
/** @description Time tracking access denied, no organization on the session, or code PAYROLL_OFF: the company has the time tracking add-on off (GET /api/time-tracking/day says payrollAddon: false). Don't retry; hide Clock In/Out and the other payroll controls. */
|
|
2069
2098
|
403: {
|
|
2070
2099
|
headers: {
|
|
2071
2100
|
[name: string]: unknown;
|
|
@@ -2074,7 +2103,7 @@ export interface paths {
|
|
|
2074
2103
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2075
2104
|
};
|
|
2076
2105
|
};
|
|
2077
|
-
/** @description No day is running (code NO_OPEN_DAY). */
|
|
2106
|
+
/** @description No day is running (code NO_OPEN_DAY). Also when the tap was only flagged for the office. */
|
|
2078
2107
|
404: {
|
|
2079
2108
|
headers: {
|
|
2080
2109
|
[name: string]: unknown;
|
|
@@ -2083,7 +2112,7 @@ export interface paths {
|
|
|
2083
2112
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2084
2113
|
};
|
|
2085
2114
|
};
|
|
2086
|
-
/** @description The day was already closed. */
|
|
2115
|
+
/** @description The day was already closed; or code DAY_CLOSED_AUTOMATICALLY: the tap belongs to an earlier day the safety net closed, and was flagged for the office. */
|
|
2087
2116
|
409: {
|
|
2088
2117
|
headers: {
|
|
2089
2118
|
[name: string]: unknown;
|
|
@@ -2306,7 +2335,7 @@ export interface paths {
|
|
|
2306
2335
|
};
|
|
2307
2336
|
requestBody?: never;
|
|
2308
2337
|
responses: {
|
|
2309
|
-
/** @description Fences, office first when requested. */
|
|
2338
|
+
/** @description Fences, office first when requested. No job fences for someone the office turned job-site tracking off for (clock-config jobSiteTracking false), except with includeClosed for the manual picker. */
|
|
2310
2339
|
200: {
|
|
2311
2340
|
headers: {
|
|
2312
2341
|
[name: string]: unknown;
|
|
@@ -2359,12 +2388,12 @@ export interface paths {
|
|
|
2359
2388
|
path?: never;
|
|
2360
2389
|
cookie?: never;
|
|
2361
2390
|
};
|
|
2362
|
-
/** My open entries right now
|
|
2391
|
+
/** My open entries right now, or who is on the clock. */
|
|
2363
2392
|
get: {
|
|
2364
2393
|
parameters: {
|
|
2365
2394
|
query?: {
|
|
2366
|
-
/** @description
|
|
2367
|
-
scope?: "team";
|
|
2395
|
+
/** @description `team`: everyone on the clock, one OnTheClockRow per person; requires time_tracking.view_all. `me`: the caller's own row while on the clock. Without scope: the caller's open entries. */
|
|
2396
|
+
scope?: "team" | "me";
|
|
2368
2397
|
};
|
|
2369
2398
|
header?: {
|
|
2370
2399
|
/** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
|
|
@@ -2377,13 +2406,13 @@ export interface paths {
|
|
|
2377
2406
|
};
|
|
2378
2407
|
requestBody?: never;
|
|
2379
2408
|
responses: {
|
|
2380
|
-
/** @description
|
|
2409
|
+
/** @description Without scope: open entries, normally zero or one. With scope: one OnTheClockRow per person on the clock. */
|
|
2381
2410
|
200: {
|
|
2382
2411
|
headers: {
|
|
2383
2412
|
[name: string]: unknown;
|
|
2384
2413
|
};
|
|
2385
2414
|
content: {
|
|
2386
|
-
"application/json": components["schemas"]["TimeEntry"][];
|
|
2415
|
+
"application/json": components["schemas"]["TimeEntry"][] | components["schemas"]["OnTheClockRow"][];
|
|
2387
2416
|
};
|
|
2388
2417
|
};
|
|
2389
2418
|
/** @description Not signed in. */
|
|
@@ -2509,8 +2538,8 @@ export interface paths {
|
|
|
2509
2538
|
get?: never;
|
|
2510
2539
|
put?: never;
|
|
2511
2540
|
/**
|
|
2512
|
-
*
|
|
2513
|
-
* @description A deliberate button press.
|
|
2541
|
+
* Start time on a job or at the office by hand.
|
|
2542
|
+
* @description A deliberate button press. The entry joins the person's work day when one is running. With none running: a job timer press (startDay: false) records job time only and never starts the paid day; a Clock In press (startDay omitted: older iPhones' job picker, the office's "Clock X in") starts the day at that moment; an automatic clock-in is refused with NO_OPEN_DAY, because the fence crossing already records the arrival. A person starting their own job time away from the job's site, or with no usable location, is asked first (send canConfirmAway: 409 JOB_TIME_AWAY carries the question; resend with confirmAway once they say yes) and the entry is flagged (startCheck) for the office to approve, move or not count. Older apps start straight away, flagged the same.
|
|
2514
2543
|
*/
|
|
2515
2544
|
post: {
|
|
2516
2545
|
parameters: {
|
|
@@ -2535,20 +2564,34 @@ export interface paths {
|
|
|
2535
2564
|
siteType?: "job" | "office";
|
|
2536
2565
|
/** @description Clock someone else in. Requires time_tracking.edit_all. */
|
|
2537
2566
|
userId?: string;
|
|
2567
|
+
/** @description Why, when clocking someone else in. Required with userId. */
|
|
2568
|
+
note?: string;
|
|
2538
2569
|
lat?: number;
|
|
2539
2570
|
lng?: number;
|
|
2540
2571
|
/** @enum {string} */
|
|
2541
2572
|
source?: "manual" | "auto";
|
|
2573
|
+
/** @description false: a job timer press, job time only; it never starts the paid day. Omitted: a Clock In press starts the day when none is running. */
|
|
2574
|
+
startDay?: boolean;
|
|
2542
2575
|
notes?: string;
|
|
2543
2576
|
budgetItemId?: number | null;
|
|
2544
2577
|
/**
|
|
2545
2578
|
* Format: date-time
|
|
2546
|
-
* @description When the tech actually arrived. The server clamps it.
|
|
2579
|
+
* @description When the tech actually arrived, by the phone's clock. The server checks it against its own (tapElapsedMs) and clamps it. From the web (device 'web') it is ignored: the server's receipt time is used.
|
|
2547
2580
|
*/
|
|
2548
2581
|
occurredAt?: string;
|
|
2549
2582
|
accuracyM?: number | null;
|
|
2550
2583
|
/** @enum {string|null} */
|
|
2551
2584
|
device?: "ios" | "web" | "android" | null;
|
|
2585
|
+
/** @description This app can ask the person before starting job time away from the job (it handles 409 JOB_TIME_AWAY). */
|
|
2586
|
+
canConfirmAway?: boolean;
|
|
2587
|
+
/** @description The person said yes to starting away from the job. */
|
|
2588
|
+
confirmAway?: boolean;
|
|
2589
|
+
/** @description Milliseconds from the tap to this send, from the phone's monotonic clock (a stopwatch the person can't change). An offline replay sends the time since the tap. The server's tap time is its own clock when the request arrives minus this. Within 2 minutes of the phone's time, the phone's time stands (never later than the tap); further apart, the server's tap time is recorded and the office is asked to look. A Clock Out or job time stop it proves this way keeps its real time however old; without it, a stop older than 12 hours is recorded at the 12-hour limit and flagged (T6). Send it with every queued tap, clock-outs included. */
|
|
2590
|
+
tapElapsedMs?: number | null;
|
|
2591
|
+
/** @description True when the phone restarted between the tap and this send, so there is no stopwatch reading (send no tapElapsedMs). A tap more than 2 minutes old keeps the phone's time and is flagged for the office. */
|
|
2592
|
+
tapTimeUnverified?: boolean | null;
|
|
2593
|
+
/** @description True when the phone's clock was changed by hand since the phone last synced. The tap is flagged for the office. */
|
|
2594
|
+
deviceClockChanged?: boolean | null;
|
|
2552
2595
|
};
|
|
2553
2596
|
};
|
|
2554
2597
|
};
|
|
@@ -2562,7 +2605,7 @@ export interface paths {
|
|
|
2562
2605
|
"application/json": components["schemas"]["TimeEntry"];
|
|
2563
2606
|
};
|
|
2564
2607
|
};
|
|
2565
|
-
/** @description Validation failure,
|
|
2608
|
+
/** @description Validation failure, jobId missing on a job clock-in, or no note when clocking someone else in. */
|
|
2566
2609
|
400: {
|
|
2567
2610
|
headers: {
|
|
2568
2611
|
[name: string]: unknown;
|
|
@@ -2580,7 +2623,7 @@ export interface paths {
|
|
|
2580
2623
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2581
2624
|
};
|
|
2582
2625
|
};
|
|
2583
|
-
/** @description Time tracking access denied, or no organization on the session. */
|
|
2626
|
+
/** @description Time tracking access denied, or no organization on the session. PAYROLL_OFF: a Clock In press that would start the day at a company with the time tracking add-on off. JOB_TIME_OFF: the company has both the time tracking add-on and location tracking off, so job time isn't used; stopping running job time still works. */
|
|
2584
2627
|
403: {
|
|
2585
2628
|
headers: {
|
|
2586
2629
|
[name: string]: unknown;
|
|
@@ -2598,7 +2641,7 @@ export interface paths {
|
|
|
2598
2641
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2599
2642
|
};
|
|
2600
2643
|
};
|
|
2601
|
-
/** @description
|
|
2644
|
+
/** @description ALREADY_CLOCKED_IN_SAME_JOB: already at this site; the body carries the existing entry — adopt it. ALREADY_CLOCKED_IN_OTHER_JOB: an automatic clock-in while another entry is open; the body carries it. NO_OPEN_DAY: an automatic clock-in with no work day running; the fence crossing records the arrival. JOB_SITE_TRACKING_OFF: an automatic clock-in for someone the office turned job-site tracking off for; start job time by hand. PERIOD_LOCKED: an admin clock-in inside a locked pay period. JOB_TIME_AWAY: starting job time away from the job (reason 'away', with distanceM) or with no usable location (reason 'no_location'); show message as the question and resend with confirmAway: true. */
|
|
2602
2645
|
409: {
|
|
2603
2646
|
headers: {
|
|
2604
2647
|
[name: string]: unknown;
|
|
@@ -2607,7 +2650,11 @@ export interface paths {
|
|
|
2607
2650
|
"application/json": {
|
|
2608
2651
|
message: string;
|
|
2609
2652
|
code: string;
|
|
2610
|
-
entry
|
|
2653
|
+
entry?: components["schemas"]["TimeEntry"];
|
|
2654
|
+
/** @enum {string} */
|
|
2655
|
+
reason?: "away" | "no_location";
|
|
2656
|
+
distanceM?: number | null;
|
|
2657
|
+
jobName?: string | null;
|
|
2611
2658
|
};
|
|
2612
2659
|
};
|
|
2613
2660
|
};
|
|
@@ -2667,17 +2714,23 @@ export interface paths {
|
|
|
2667
2714
|
notes?: string;
|
|
2668
2715
|
/**
|
|
2669
2716
|
* Format: date-time
|
|
2670
|
-
* @description When the tech actually left.
|
|
2717
|
+
* @description When the tech actually left, by the phone's clock. Checked against the server's (tapElapsedMs) and clamped to [entry.clockIn, now], and to the last 12 hours unless tapElapsedMs proves it (T6). From the web (device 'web') it is ignored: the server's receipt time is used.
|
|
2671
2718
|
*/
|
|
2672
2719
|
occurredAt?: string;
|
|
2673
2720
|
accuracyM?: number | null;
|
|
2674
2721
|
/** @enum {string|null} */
|
|
2675
2722
|
device?: "ios" | "web" | "android" | null;
|
|
2723
|
+
/** @description Milliseconds from the tap to this send, from the phone's monotonic clock (a stopwatch the person can't change). An offline replay sends the time since the tap. The server's tap time is its own clock when the request arrives minus this. Within 2 minutes of the phone's time, the phone's time stands (never later than the tap); further apart, the server's tap time is recorded and the office is asked to look. A Clock Out or job time stop it proves this way keeps its real time however old; without it, a stop older than 12 hours is recorded at the 12-hour limit and flagged (T6). Send it with every queued tap, clock-outs included. */
|
|
2724
|
+
tapElapsedMs?: number | null;
|
|
2725
|
+
/** @description True when the phone restarted between the tap and this send, so there is no stopwatch reading (send no tapElapsedMs). A tap more than 2 minutes old keeps the phone's time and is flagged for the office. */
|
|
2726
|
+
tapTimeUnverified?: boolean | null;
|
|
2727
|
+
/** @description True when the phone's clock was changed by hand since the phone last synced. The tap is flagged for the office. */
|
|
2728
|
+
deviceClockChanged?: boolean | null;
|
|
2676
2729
|
};
|
|
2677
2730
|
};
|
|
2678
2731
|
};
|
|
2679
2732
|
responses: {
|
|
2680
|
-
/** @description Entry closed. */
|
|
2733
|
+
/** @description Entry closed; or, for a stop tapElapsedMs proves that is earlier than the automatic close of the job time there, that close replaced (T6). */
|
|
2681
2734
|
200: {
|
|
2682
2735
|
headers: {
|
|
2683
2736
|
[name: string]: unknown;
|
|
@@ -2713,7 +2766,7 @@ export interface paths {
|
|
|
2713
2766
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2714
2767
|
};
|
|
2715
2768
|
};
|
|
2716
|
-
/** @description No open entry at that site. */
|
|
2769
|
+
/** @description No open entry at that site. Also when the stop belongs to job time the safety net closed and was only flagged for the office. */
|
|
2717
2770
|
404: {
|
|
2718
2771
|
headers: {
|
|
2719
2772
|
[name: string]: unknown;
|
|
@@ -2750,7 +2803,7 @@ export interface paths {
|
|
|
2750
2803
|
put?: never;
|
|
2751
2804
|
/**
|
|
2752
2805
|
* Move my clock to another job in one atomic call.
|
|
2753
|
-
* @description Closes the caller's open entry and opens one on the target. One request instead of clock-out + clock-in, so an offline drop between the two cannot strand the tech clocked out. Own entry only.
|
|
2806
|
+
* @description Closes the caller's open entry and opens one on the target. One request instead of clock-out + clock-in, so an offline drop between the two cannot strand the tech clocked out. Own entry only. Moving job time to a job the person isn't at, or with no usable location, is asked first (send canConfirmAway: 409 JOB_TIME_AWAY carries the question; resend with confirmAway once they say yes) and the new entry is flagged (startCheck) for the office. Older apps move straight away, flagged the same. switchAt is a time the person picked, so earlier than the tap is normal. With tapElapsedMs it is never later than the tap by the server's clock, and more than 2 minutes later is replaced by the tap time and flagged (opened.clockInCheck). tapTimeUnverified doesn't apply; deviceClockChanged flags it.
|
|
2754
2807
|
*/
|
|
2755
2808
|
post: {
|
|
2756
2809
|
parameters: {
|
|
@@ -2773,6 +2826,17 @@ export interface paths {
|
|
|
2773
2826
|
switchAt?: string;
|
|
2774
2827
|
lat?: number;
|
|
2775
2828
|
lng?: number;
|
|
2829
|
+
accuracyM?: number | null;
|
|
2830
|
+
/** @description This app can ask the person before moving job time to a job they aren't at (it handles 409 JOB_TIME_AWAY). */
|
|
2831
|
+
canConfirmAway?: boolean;
|
|
2832
|
+
/** @description The person said yes to moving it anyway. */
|
|
2833
|
+
confirmAway?: boolean;
|
|
2834
|
+
/** @description Milliseconds from the tap to this send, from the phone's monotonic clock (a stopwatch the person can't change). An offline replay sends the time since the tap. The server's tap time is its own clock when the request arrives minus this. Within 2 minutes of the phone's time, the phone's time stands (never later than the tap); further apart, the server's tap time is recorded and the office is asked to look. A Clock Out or job time stop it proves this way keeps its real time however old; without it, a stop older than 12 hours is recorded at the 12-hour limit and flagged (T6). Send it with every queued tap, clock-outs included. */
|
|
2835
|
+
tapElapsedMs?: number | null;
|
|
2836
|
+
/** @description True when the phone restarted between the tap and this send, so there is no stopwatch reading (send no tapElapsedMs). A tap more than 2 minutes old keeps the phone's time and is flagged for the office. */
|
|
2837
|
+
tapTimeUnverified?: boolean | null;
|
|
2838
|
+
/** @description True when the phone's clock was changed by hand since the phone last synced. The tap is flagged for the office. */
|
|
2839
|
+
deviceClockChanged?: boolean | null;
|
|
2776
2840
|
};
|
|
2777
2841
|
};
|
|
2778
2842
|
};
|
|
@@ -2808,7 +2872,7 @@ export interface paths {
|
|
|
2808
2872
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2809
2873
|
};
|
|
2810
2874
|
};
|
|
2811
|
-
/** @description Time tracking access denied, or no organization on the session. */
|
|
2875
|
+
/** @description Time tracking access denied, or no organization on the session. JOB_TIME_OFF: the company has both the time tracking add-on and location tracking off, so job time isn't used; stopping running job time still works. */
|
|
2812
2876
|
403: {
|
|
2813
2877
|
headers: {
|
|
2814
2878
|
[name: string]: unknown;
|
|
@@ -2826,6 +2890,22 @@ export interface paths {
|
|
|
2826
2890
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
2827
2891
|
};
|
|
2828
2892
|
};
|
|
2893
|
+
/** @description PERIOD_LOCKED: the switch time is inside a locked pay period. JOB_TIME_AWAY: the person isn't at the target job (reason 'away', with distanceM) or has no usable location (reason 'no_location'); nothing moved. Show message as the question and resend with confirmAway: true. */
|
|
2894
|
+
409: {
|
|
2895
|
+
headers: {
|
|
2896
|
+
[name: string]: unknown;
|
|
2897
|
+
};
|
|
2898
|
+
content: {
|
|
2899
|
+
"application/json": {
|
|
2900
|
+
message: string;
|
|
2901
|
+
code: string;
|
|
2902
|
+
/** @enum {string} */
|
|
2903
|
+
reason?: "away" | "no_location";
|
|
2904
|
+
distanceM?: number | null;
|
|
2905
|
+
jobName?: string | null;
|
|
2906
|
+
};
|
|
2907
|
+
};
|
|
2908
|
+
};
|
|
2829
2909
|
/** @description Client major below minClientVersion. */
|
|
2830
2910
|
426: {
|
|
2831
2911
|
headers: {
|
|
@@ -3127,7 +3207,7 @@ export interface paths {
|
|
|
3127
3207
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3128
3208
|
};
|
|
3129
3209
|
};
|
|
3130
|
-
/** @description Time tracking access denied,
|
|
3210
|
+
/** @description Time tracking access denied, no organization on the session, or code PAYROLL_OFF: the company has the time tracking add-on off (GET /api/time-tracking/day says payrollAddon: false). Don't retry; hide Clock In/Out and the other payroll controls. */
|
|
3131
3211
|
403: {
|
|
3132
3212
|
headers: {
|
|
3133
3213
|
[name: string]: unknown;
|
|
@@ -3369,6 +3449,15 @@ export interface paths {
|
|
|
3369
3449
|
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3370
3450
|
};
|
|
3371
3451
|
};
|
|
3452
|
+
/** @description Time tracking access denied, no organization on the session, or code PAYROLL_OFF: the company has the time tracking add-on off (GET /api/time-tracking/day says payrollAddon: false). Don't retry; hide Clock In/Out and the other payroll controls. */
|
|
3453
|
+
403: {
|
|
3454
|
+
headers: {
|
|
3455
|
+
[name: string]: unknown;
|
|
3456
|
+
};
|
|
3457
|
+
content: {
|
|
3458
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3459
|
+
};
|
|
3460
|
+
};
|
|
3372
3461
|
/** @description A request for those dates is already waiting. */
|
|
3373
3462
|
409: {
|
|
3374
3463
|
headers: {
|
|
@@ -3395,6 +3484,171 @@ export interface paths {
|
|
|
3395
3484
|
patch?: never;
|
|
3396
3485
|
trace?: never;
|
|
3397
3486
|
};
|
|
3487
|
+
"/api/account/deletion-request": {
|
|
3488
|
+
parameters: {
|
|
3489
|
+
query?: never;
|
|
3490
|
+
header?: never;
|
|
3491
|
+
path?: never;
|
|
3492
|
+
cookie?: never;
|
|
3493
|
+
};
|
|
3494
|
+
/** My newest account deletion request. */
|
|
3495
|
+
get: {
|
|
3496
|
+
parameters: {
|
|
3497
|
+
query?: never;
|
|
3498
|
+
header?: {
|
|
3499
|
+
/** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
|
|
3500
|
+
"X-Client-Version"?: string;
|
|
3501
|
+
};
|
|
3502
|
+
path?: never;
|
|
3503
|
+
cookie?: never;
|
|
3504
|
+
};
|
|
3505
|
+
requestBody?: never;
|
|
3506
|
+
responses: {
|
|
3507
|
+
/** @description The newest request, whatever its status. */
|
|
3508
|
+
200: {
|
|
3509
|
+
headers: {
|
|
3510
|
+
[name: string]: unknown;
|
|
3511
|
+
};
|
|
3512
|
+
content: {
|
|
3513
|
+
"application/json": components["schemas"]["AccountDeletionRequest"];
|
|
3514
|
+
};
|
|
3515
|
+
};
|
|
3516
|
+
/** @description Not signed in. */
|
|
3517
|
+
401: {
|
|
3518
|
+
headers: {
|
|
3519
|
+
[name: string]: unknown;
|
|
3520
|
+
};
|
|
3521
|
+
content: {
|
|
3522
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3523
|
+
};
|
|
3524
|
+
};
|
|
3525
|
+
/** @description No organization on the session. */
|
|
3526
|
+
403: {
|
|
3527
|
+
headers: {
|
|
3528
|
+
[name: string]: unknown;
|
|
3529
|
+
};
|
|
3530
|
+
content: {
|
|
3531
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3532
|
+
};
|
|
3533
|
+
};
|
|
3534
|
+
/** @description No request yet. */
|
|
3535
|
+
404: {
|
|
3536
|
+
headers: {
|
|
3537
|
+
[name: string]: unknown;
|
|
3538
|
+
};
|
|
3539
|
+
content: {
|
|
3540
|
+
"application/json": {
|
|
3541
|
+
/** @example No deletion request */
|
|
3542
|
+
message: string;
|
|
3543
|
+
};
|
|
3544
|
+
};
|
|
3545
|
+
};
|
|
3546
|
+
/** @description Client major below minClientVersion. */
|
|
3547
|
+
426: {
|
|
3548
|
+
headers: {
|
|
3549
|
+
[name: string]: unknown;
|
|
3550
|
+
};
|
|
3551
|
+
content: {
|
|
3552
|
+
"application/json": components["schemas"]["UpgradeRequiredEnvelope"];
|
|
3553
|
+
};
|
|
3554
|
+
};
|
|
3555
|
+
};
|
|
3556
|
+
};
|
|
3557
|
+
put?: never;
|
|
3558
|
+
/**
|
|
3559
|
+
* Ask for my account to be deleted.
|
|
3560
|
+
* @description Nothing is deleted by this call. The request goes to the company's owner and Team admins (bell, push and email) and to ServiceAi support (email); the company removes the account. Asking again while a request is pending answers that request with 200 and creates nothing; everyone is reminded at most once a day. The reason is never put in a push.
|
|
3561
|
+
*/
|
|
3562
|
+
post: {
|
|
3563
|
+
parameters: {
|
|
3564
|
+
query?: never;
|
|
3565
|
+
header?: {
|
|
3566
|
+
/** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
|
|
3567
|
+
"X-Client-Version"?: string;
|
|
3568
|
+
};
|
|
3569
|
+
path?: never;
|
|
3570
|
+
cookie?: never;
|
|
3571
|
+
};
|
|
3572
|
+
requestBody?: {
|
|
3573
|
+
content: {
|
|
3574
|
+
"application/json": {
|
|
3575
|
+
/** @description Optional. Trimmed; at most 1000 characters after trimming. */
|
|
3576
|
+
reason?: string | null;
|
|
3577
|
+
};
|
|
3578
|
+
};
|
|
3579
|
+
};
|
|
3580
|
+
responses: {
|
|
3581
|
+
/** @description A request was already pending: this is that request. */
|
|
3582
|
+
200: {
|
|
3583
|
+
headers: {
|
|
3584
|
+
[name: string]: unknown;
|
|
3585
|
+
};
|
|
3586
|
+
content: {
|
|
3587
|
+
"application/json": components["schemas"]["AccountDeletionRequest"];
|
|
3588
|
+
};
|
|
3589
|
+
};
|
|
3590
|
+
/** @description Request created. */
|
|
3591
|
+
202: {
|
|
3592
|
+
headers: {
|
|
3593
|
+
[name: string]: unknown;
|
|
3594
|
+
};
|
|
3595
|
+
content: {
|
|
3596
|
+
"application/json": components["schemas"]["AccountDeletionRequest"];
|
|
3597
|
+
};
|
|
3598
|
+
};
|
|
3599
|
+
/** @description Validation failure (a reason longer than 1000 characters). */
|
|
3600
|
+
400: {
|
|
3601
|
+
headers: {
|
|
3602
|
+
[name: string]: unknown;
|
|
3603
|
+
};
|
|
3604
|
+
content: {
|
|
3605
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3606
|
+
};
|
|
3607
|
+
};
|
|
3608
|
+
/** @description Not signed in. */
|
|
3609
|
+
401: {
|
|
3610
|
+
headers: {
|
|
3611
|
+
[name: string]: unknown;
|
|
3612
|
+
};
|
|
3613
|
+
content: {
|
|
3614
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3615
|
+
};
|
|
3616
|
+
};
|
|
3617
|
+
/** @description No organization on the session, or viewing the app as someone else. */
|
|
3618
|
+
403: {
|
|
3619
|
+
headers: {
|
|
3620
|
+
[name: string]: unknown;
|
|
3621
|
+
};
|
|
3622
|
+
content: {
|
|
3623
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3624
|
+
};
|
|
3625
|
+
};
|
|
3626
|
+
/** @description Client major below minClientVersion. */
|
|
3627
|
+
426: {
|
|
3628
|
+
headers: {
|
|
3629
|
+
[name: string]: unknown;
|
|
3630
|
+
};
|
|
3631
|
+
content: {
|
|
3632
|
+
"application/json": components["schemas"]["UpgradeRequiredEnvelope"];
|
|
3633
|
+
};
|
|
3634
|
+
};
|
|
3635
|
+
/** @description Too many requests from this person; try again later. */
|
|
3636
|
+
429: {
|
|
3637
|
+
headers: {
|
|
3638
|
+
[name: string]: unknown;
|
|
3639
|
+
};
|
|
3640
|
+
content: {
|
|
3641
|
+
"application/json": components["schemas"]["ErrorEnvelope"];
|
|
3642
|
+
};
|
|
3643
|
+
};
|
|
3644
|
+
};
|
|
3645
|
+
};
|
|
3646
|
+
delete?: never;
|
|
3647
|
+
options?: never;
|
|
3648
|
+
head?: never;
|
|
3649
|
+
patch?: never;
|
|
3650
|
+
trace?: never;
|
|
3651
|
+
};
|
|
3398
3652
|
}
|
|
3399
3653
|
export type webhooks = Record<string, never>;
|
|
3400
3654
|
export interface components {
|
|
@@ -3419,7 +3673,7 @@ export interface components {
|
|
|
3419
3673
|
};
|
|
3420
3674
|
/** @description Cross-platform version handshake manifest. See docs/api-versioning.md. */
|
|
3421
3675
|
VersionManifest: {
|
|
3422
|
-
/** @example 1.2.
|
|
3676
|
+
/** @example 1.2.420 */
|
|
3423
3677
|
apiVersion: string;
|
|
3424
3678
|
/** @example 1.0.0 */
|
|
3425
3679
|
minClientVersion: string;
|
|
@@ -4019,6 +4273,39 @@ export interface components {
|
|
|
4019
4273
|
RealtimeWebrtcRequest: {
|
|
4020
4274
|
sdp: string;
|
|
4021
4275
|
};
|
|
4276
|
+
/** @description A tap whose time the office is asked to look at, with both times. It waits in Team › Needs attention. */
|
|
4277
|
+
PunchTimeCheck: {
|
|
4278
|
+
/** @description server_time: the phone's time was more than 2 minutes from the server's, and the server's was recorded. unverified: the phone restarted before sending, so the time couldn't be checked; the phone's was kept. clock_changed: the phone's clock was changed by hand. Late stops (T6): too_old: a stop more than 12 hours old that couldn't be proven was recorded at the 12-hour limit. replaced_auto_close: a proven stop replaced the automatic close (autoAt). after_auto_close: a stop later than the automatic close; the automatic close was kept. auto_close_kept: a stop earlier than the automatic close that wasn't applied (keptBecause). */
|
|
4279
|
+
reasons: ("server_time" | "unverified" | "clock_changed" | "too_old" | "replaced_auto_close" | "after_auto_close" | "auto_close_kept")[];
|
|
4280
|
+
/**
|
|
4281
|
+
* Format: date-time
|
|
4282
|
+
* @description The phone's own time for the tap.
|
|
4283
|
+
*/
|
|
4284
|
+
phoneAt: string | null;
|
|
4285
|
+
/**
|
|
4286
|
+
* Format: date-time
|
|
4287
|
+
* @description The tap by the server's clock (arrival minus tapElapsedMs); null when the phone couldn't say.
|
|
4288
|
+
*/
|
|
4289
|
+
serverAt: string | null;
|
|
4290
|
+
/**
|
|
4291
|
+
* Format: date-time
|
|
4292
|
+
* @description When the request reached the server.
|
|
4293
|
+
*/
|
|
4294
|
+
receivedAt: string;
|
|
4295
|
+
tapElapsedMs: number | null;
|
|
4296
|
+
/** @description True when the phone's stopwatch proved the tap's time. */
|
|
4297
|
+
verified?: boolean;
|
|
4298
|
+
/**
|
|
4299
|
+
* Format: date-time
|
|
4300
|
+
* @description The automatic close a late stop replaced or was held against.
|
|
4301
|
+
*/
|
|
4302
|
+
autoAt?: string;
|
|
4303
|
+
/**
|
|
4304
|
+
* @description Why a late stop wasn't applied: its time couldn't be proven, the office had already changed or approved the time, or the pay period is locked.
|
|
4305
|
+
* @enum {string}
|
|
4306
|
+
*/
|
|
4307
|
+
keptBecause?: "unverified" | "office" | "locked";
|
|
4308
|
+
};
|
|
4022
4309
|
/** @description One stretch of time at one site, inside a work day. durationMinutes stays gross; paid time is gross minus breakMinutes. */
|
|
4023
4310
|
TimeEntry: {
|
|
4024
4311
|
id: number;
|
|
@@ -4063,11 +4350,25 @@ export interface components {
|
|
|
4063
4350
|
staleWarnedAt: string | null;
|
|
4064
4351
|
/** @description Unpaid break minutes recorded against this entry. */
|
|
4065
4352
|
breakMinutes: number;
|
|
4353
|
+
/**
|
|
4354
|
+
* @description Job time started by hand away from the job ('away') or with no usable location ('no_location'); null for a normal start. The office decides it.
|
|
4355
|
+
* @enum {string|null}
|
|
4356
|
+
*/
|
|
4357
|
+
startCheck?: "away" | "no_location" | null;
|
|
4358
|
+
/** @description How far from the job's site center the start was, when startCheck is 'away'. */
|
|
4359
|
+
startDistanceM?: number | null;
|
|
4360
|
+
/**
|
|
4361
|
+
* @description The office's decision on a flagged start; null while it waits. 'not_approved' stays on the timesheet but off the job's costing.
|
|
4362
|
+
* @enum {string|null}
|
|
4363
|
+
*/
|
|
4364
|
+
startReview?: "approved" | "not_approved" | "moved" | null;
|
|
4365
|
+
clockInCheck?: components["schemas"]["PunchTimeCheck"] & (Record<string, never> | null);
|
|
4366
|
+
clockOutCheck?: components["schemas"]["PunchTimeCheck"] & (Record<string, never> | null);
|
|
4066
4367
|
/** Format: date-time */
|
|
4067
4368
|
createdAt: string | null;
|
|
4068
4369
|
/** @description Enrichment on /active and /entries. 'Office' for an office entry. */
|
|
4069
4370
|
jobName?: string;
|
|
4070
|
-
/** @description Enrichment on /entries
|
|
4371
|
+
/** @description Enrichment on /entries. */
|
|
4071
4372
|
userName?: string;
|
|
4072
4373
|
};
|
|
4073
4374
|
/** @description Where a day's minutes went (shared/workDays.ts splitDayMinutes). */
|
|
@@ -4125,6 +4426,8 @@ export interface components {
|
|
|
4125
4426
|
nearestJob?: unknown;
|
|
4126
4427
|
} | null;
|
|
4127
4428
|
notes: string | null;
|
|
4429
|
+
clockInCheck?: components["schemas"]["PunchTimeCheck"] & (Record<string, never> | null);
|
|
4430
|
+
clockOutCheck?: components["schemas"]["PunchTimeCheck"] & (Record<string, never> | null);
|
|
4128
4431
|
editedBy: string | null;
|
|
4129
4432
|
/** Format: date-time */
|
|
4130
4433
|
editedAt: string | null;
|
|
@@ -4156,6 +4459,16 @@ export interface components {
|
|
|
4156
4459
|
};
|
|
4157
4460
|
/** @description Everything the phone needs to draw the day card and decide what it may record. */
|
|
4158
4461
|
MyDayResponse: {
|
|
4462
|
+
/** @description The company's time tracking (payroll) add-on. False: no Clock In/Out, no work days, schedules, time cards or pay; job time still runs. Then open is null, today is empty, shiftEnd is null, payroll.breakButton and locationTrail are false, and the payroll routes answer 403 PAYROLL_OFF. Not the same as payroll.enabled. */
|
|
4463
|
+
payrollAddon: boolean;
|
|
4464
|
+
/** @description The company's pay rules as they touch this person. */
|
|
4465
|
+
payroll: {
|
|
4466
|
+
/** @description A pay period is set (the company's pay rules are on). */
|
|
4467
|
+
enabled: boolean;
|
|
4468
|
+
/** @description Show the break button (false when this person's lunch comes off automatically). */
|
|
4469
|
+
breakButton: boolean;
|
|
4470
|
+
breaksPaid: boolean;
|
|
4471
|
+
};
|
|
4159
4472
|
/** @description True once this person is on the day model. */
|
|
4160
4473
|
dayModel: boolean;
|
|
4161
4474
|
open: components["schemas"]["WorkDay"] & (Record<string, never> | null);
|
|
@@ -4203,7 +4516,7 @@ export interface components {
|
|
|
4203
4516
|
/** Format: date-time */
|
|
4204
4517
|
stageChangedAt: string | null;
|
|
4205
4518
|
};
|
|
4206
|
-
/** @description One fence crossing as the device saw it. */
|
|
4519
|
+
/** @description One fence crossing as the device saw it. With tapElapsedMs (the time since the crossing), the server checks occurredAt against its own clock before the resolver uses it, and the entry the crossing opens or closes carries the check. A departure it proves isn't held to the 12-hour limit (T6). */
|
|
4207
4520
|
ClockCrossing: {
|
|
4208
4521
|
/** @description Client-generated UUID. Re-delivery is a no-op (unique index), so retry freely. */
|
|
4209
4522
|
clientEventId: string;
|
|
@@ -4227,6 +4540,12 @@ export interface components {
|
|
|
4227
4540
|
device?: "ios" | "web" | "android" | null;
|
|
4228
4541
|
/** @description The user's auto-clock toggle at crossing time. False → the crossing is logged but never acted on. */
|
|
4229
4542
|
autoClockEnabled?: boolean;
|
|
4543
|
+
/** @description Milliseconds from the tap to this send, from the phone's monotonic clock (a stopwatch the person can't change). An offline replay sends the time since the tap. The server's tap time is its own clock when the request arrives minus this. Within 2 minutes of the phone's time, the phone's time stands (never later than the tap); further apart, the server's tap time is recorded and the office is asked to look. A Clock Out or job time stop it proves this way keeps its real time however old; without it, a stop older than 12 hours is recorded at the 12-hour limit and flagged (T6). Send it with every queued tap, clock-outs included. */
|
|
4544
|
+
tapElapsedMs?: number | null;
|
|
4545
|
+
/** @description True when the phone restarted between the tap and this send, so there is no stopwatch reading (send no tapElapsedMs). A tap more than 2 minutes old keeps the phone's time and is flagged for the office. */
|
|
4546
|
+
tapTimeUnverified?: boolean | null;
|
|
4547
|
+
/** @description True when the phone's clock was changed by hand since the phone last synced. The tap is flagged for the office. */
|
|
4548
|
+
deviceClockChanged?: boolean | null;
|
|
4230
4549
|
};
|
|
4231
4550
|
/** @description Always 202. The clock state to trust is `openEntries`, not the client's own guess. */
|
|
4232
4551
|
CrossingsAck: {
|
|
@@ -4296,6 +4615,8 @@ export interface components {
|
|
|
4296
4615
|
};
|
|
4297
4616
|
/** @description True only for the primary account. */
|
|
4298
4617
|
canEdit: boolean;
|
|
4618
|
+
/** @description The caller's own switch, set by the office (owner's O9). False: watch no job-site fences and use no location for job time; job time comes only from Start/Stop job time. The office fence, Clock In/Out and the company switches are unaffected. Absent (an older server): treat as true. */
|
|
4619
|
+
jobSiteTracking?: boolean;
|
|
4299
4620
|
};
|
|
4300
4621
|
/** @description Always 202. */
|
|
4301
4622
|
TrailPingResponse: {
|
|
@@ -4374,6 +4695,8 @@ export interface components {
|
|
|
4374
4695
|
* @description The org-local date, which is not necessarily the device's.
|
|
4375
4696
|
*/
|
|
4376
4697
|
today: string;
|
|
4698
|
+
/** @description False when the company has the time tracking add-on off: no shifts, hours or time off come back, and nothing covers now. */
|
|
4699
|
+
payrollAddon: boolean;
|
|
4377
4700
|
/** @description Keyed by org-local ISO date. */
|
|
4378
4701
|
hours: {
|
|
4379
4702
|
[key: string]: {
|
|
@@ -4410,6 +4733,32 @@ export interface components {
|
|
|
4410
4733
|
/** @description The last few decided ones, newest first. */
|
|
4411
4734
|
recentTimeOff: components["schemas"]["TimeOffRequestSummary"][];
|
|
4412
4735
|
};
|
|
4736
|
+
/** @description One person on the clock (server/onTheClock.ts). Job time with no paid day behind it is left out: that person is at a job, not on the clock. */
|
|
4737
|
+
OnTheClockRow: {
|
|
4738
|
+
userId: string;
|
|
4739
|
+
userName: string;
|
|
4740
|
+
/** @description The open site entry; null between sites (a day with nothing open). */
|
|
4741
|
+
entryId: number | null;
|
|
4742
|
+
jobId: number | null;
|
|
4743
|
+
/**
|
|
4744
|
+
* @description 'none' between sites.
|
|
4745
|
+
* @enum {string}
|
|
4746
|
+
*/
|
|
4747
|
+
siteType: "job" | "office" | "none";
|
|
4748
|
+
jobName: string | null;
|
|
4749
|
+
/**
|
|
4750
|
+
* Format: date-time
|
|
4751
|
+
* @description When the work day began, else when the entry did.
|
|
4752
|
+
*/
|
|
4753
|
+
since: string;
|
|
4754
|
+
};
|
|
4755
|
+
/** @description The signed-in person's request to have their account deleted. pending: waiting for the company; completed: the company marked it done; cancelled: the company cancelled it (asking again starts a new one). */
|
|
4756
|
+
AccountDeletionRequest: {
|
|
4757
|
+
/** @enum {string} */
|
|
4758
|
+
status: "pending" | "completed" | "cancelled";
|
|
4759
|
+
/** Format: date-time */
|
|
4760
|
+
requestedAt: string;
|
|
4761
|
+
};
|
|
4413
4762
|
};
|
|
4414
4763
|
responses: never;
|
|
4415
4764
|
parameters: never;
|