repzo 1.0.290 → 1.0.292

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.
@@ -0,0 +1,415 @@
1
+ openapi: 3.0.3
2
+ info:
3
+ title: Repzo API - Day Shift
4
+ version: 1.0.0
5
+ description: |
6
+ **Day shifts** are reusable weekly work schedules assigned to sales reps.
7
+ Each shift holds a `schedule[]` of per-weekday entries
8
+ (`{ day, work_time[] }`); every `work_time` range is a `HH:mm` wall-clock
9
+ interval in the company time zone, and a range whose `to <= from` crosses
10
+ midnight into the next calendar date (e.g. `18:00 → 02:00`).
11
+
12
+ **Why it matters.** Repzo keys all daily data on a **business-day string**
13
+ (`"2026-07-14"`), derived from a per-company `end_of_day` cut. A shift acts
14
+ as a **per-weekday override of that cut**: yesterday's overnight spill can
15
+ raise the boundary (so early-morning activity still belongs to the prior
16
+ working day) and today's early shift start can pull it down. When a rep has
17
+ **no shift assigned**, business-day resolution is byte-identical to the
18
+ legacy company `end_of_day` behaviour. See the shift-aware resolver in
19
+ `src/util.ts` (`resolveBusinessDay`, `findDay`, `findTimeFrame`).
20
+
21
+ **Assignment.** A rep is assigned a shift through the rep's own
22
+ `assigned_shift` field (see the Rep service). The resolved schedule is
23
+ snapshotted onto the rep's `day` document at day-open — together with the
24
+ business-day context it was stamped with (`EOD`, `timeZone`) — and every
25
+ business-day stamping site (visits, activities, day close/recalc,
26
+ transactional documents) resolves against that full snapshot while the
27
+ day is open: neither a mid-day shift reassignment / schedule edit nor an
28
+ owner changing the company `end_of_day` / `time_zone` moves an in-flight
29
+ day's boundaries or stamps new documents onto a different business day
30
+ than the open day. The rep's current shift and the namespace's current
31
+ settings only apply when no day is open (i.e. from the next day-open
32
+ onward).
33
+
34
+ **Who calls it.** Admins manage shifts from the back-office UI. Reps are
35
+ notified of changes via the `update-day-shift` command (real-time push).
36
+
37
+ **Multi-tenancy & lifecycle.** Records are scoped by `company_namespace[]`
38
+ (server-injected from session). Soft-delete via `disabled: true`; deletion
39
+ is rejected while any active rep's `assigned_shift` still points at the
40
+ shift. `designation` is an optional free-text label. `name` is unique per
41
+ namespace among active rows (compound unique index
42
+ `(company_namespace, name)`, partial on `disabled: false`).
43
+
44
+ **Validation.** On create/update the `schedule` is validated so business-day
45
+ resolution stays well-defined: each weekday appears at most once; every
46
+ range has a valid, non-equal `from`/`to`; per day, ranges are
47
+ non-overlapping and only the **last** range may cross midnight; a day's
48
+ overnight tail must not overlap the next weekday's earliest start; and,
49
+ against the namespace's `end_of_day`, no weekday's business day may be
50
+ eliminated — a shift whose end reaches or passes the FOLLOWING weekday's
51
+ end-of-day cut while that weekday has no ranges (e.g. `end_of_day` 12:00
52
+ with Monday 22:00→13:00 and Tuesday off) is rejected, since the label in
53
+ between could never own a single instant.
54
+
55
+ **Key relationships.** Referenced by `representatives` via the rep's
56
+ `assigned_shift` field.
57
+
58
+ **Events.** Create / update / remove emit `update-day-shift`, which notifies
59
+ reps in the namespace. Bulk `patch` is not supported.
60
+ servers:
61
+ - url: https://sv.api.repzo.me
62
+ security:
63
+ - ApiKeyAuth: []
64
+ - JwtAuth: []
65
+ paths:
66
+ /day-shift:
67
+ get:
68
+ summary: Find day shifts
69
+ operationId: findDayShifts
70
+ parameters:
71
+ - in: query
72
+ name: _id
73
+ description: |
74
+ "Filter by shift `_id`. Pass once for a single match, or as
75
+ `?_id[]=...&_id[]=...` for multiple."
76
+ schema:
77
+ oneOf:
78
+ - type: string
79
+ - type: array
80
+ items: { type: string }
81
+ - in: query
82
+ name: name
83
+ description: |
84
+ Exact-match on shift `name` **or** `designation` (the value is
85
+ expanded to match either field).
86
+ schema:
87
+ oneOf:
88
+ - type: string
89
+ - type: array
90
+ items: { type: string }
91
+ - in: query
92
+ name: designation
93
+ description: Exact-match on shift `designation`.
94
+ schema:
95
+ oneOf:
96
+ - type: string
97
+ - type: array
98
+ items: { type: string }
99
+ - in: query
100
+ name: disabled
101
+ description: Include disabled (soft-deleted) shifts. Defaults to `false`.
102
+ schema: { type: boolean, default: false }
103
+ - in: query
104
+ name: from_updatedAt
105
+ description: |
106
+ Cursor — return only shifts with `updatedAt` greater than this Unix
107
+ timestamp (ms). Used by sync clients.
108
+ schema: { type: number }
109
+ - in: query
110
+ name: inject_assigned_reps
111
+ description: |
112
+ When truthy, each returned shift is enriched with an
113
+ `assigned_reps[]` array (`_id`, `name`) of the active reps whose
114
+ `assigned_shift` points at it.
115
+ schema: { type: boolean, default: false }
116
+ - in: query
117
+ name: from__id
118
+ description: Cursor — return records with `_id` greater than this value.
119
+ schema: { type: string }
120
+ - in: query
121
+ name: to__id
122
+ description: Cursor — return records with `_id` less than this value.
123
+ schema: { type: string }
124
+ - in: query
125
+ name: per_page
126
+ description: Page size. Defaults to the server's configured pagination limit.
127
+ schema: { type: integer, minimum: 1, maximum: 500 }
128
+ example: 50
129
+ - in: query
130
+ name: page
131
+ description: 1-indexed page number.
132
+ schema: { type: integer, minimum: 1 }
133
+ example: 1
134
+ - in: query
135
+ name: sortBy
136
+ description: |
137
+ Sort directives. Encoded with `qs` bracket notation, e.g.
138
+ `?sortBy[0][field]=_id&sortBy[0][type]=desc`.
139
+ schema:
140
+ type: array
141
+ items:
142
+ type: object
143
+ properties:
144
+ field:
145
+ type: string
146
+ enum: [_id]
147
+ type:
148
+ type: string
149
+ enum: [asc, desc]
150
+ responses:
151
+ "200":
152
+ description: Paginated list of shifts.
153
+ content:
154
+ application/json:
155
+ schema:
156
+ $ref: "#/components/schemas/ShiftFindResult"
157
+ post:
158
+ summary: Create a day shift
159
+ description: |
160
+ Creates a shift. The `schedule` is validated (see the service
161
+ description). Emits `update-day-shift`.
162
+ operationId: createDayShift
163
+ requestBody:
164
+ required: true
165
+ content:
166
+ application/json:
167
+ schema:
168
+ $ref: "#/components/schemas/ShiftCreateBody"
169
+ responses:
170
+ "201":
171
+ description: The newly-created shift document.
172
+ content:
173
+ application/json:
174
+ schema:
175
+ $ref: "#/components/schemas/ShiftSchema"
176
+ /day-shift/{id}:
177
+ get:
178
+ summary: Get a day shift by id
179
+ operationId: getDayShift
180
+ parameters:
181
+ - in: path
182
+ name: id
183
+ required: true
184
+ schema: { type: string }
185
+ responses:
186
+ "200":
187
+ description: The shift document for the given `_id`.
188
+ content:
189
+ application/json:
190
+ schema:
191
+ $ref: "#/components/schemas/ShiftSchema"
192
+ put:
193
+ summary: Update a day shift
194
+ description: |
195
+ Standard put. When `schedule` is present it is validated. Setting
196
+ `disabled: true` soft-deletes the shift and — like DELETE — is
197
+ rejected with a `BadRequest` while any active rep's `assigned_shift`
198
+ still points at it. Emits `update-day-shift`.
199
+ operationId: updateDayShift
200
+ parameters:
201
+ - in: path
202
+ name: id
203
+ required: true
204
+ schema: { type: string }
205
+ requestBody:
206
+ required: true
207
+ content:
208
+ application/json:
209
+ schema:
210
+ $ref: "#/components/schemas/ShiftUpdateBody"
211
+ responses:
212
+ "200":
213
+ description: The shift document after the update is applied.
214
+ content:
215
+ application/json:
216
+ schema:
217
+ $ref: "#/components/schemas/ShiftSchema"
218
+ delete:
219
+ summary: Soft-delete a day shift
220
+ description: |
221
+ Soft-deletes the shift (`disabled: true`). Rejected with a
222
+ `BadRequest` while any active rep's `assigned_shift` still points at
223
+ it. Emits `update-day-shift`.
224
+ operationId: removeDayShift
225
+ parameters:
226
+ - in: path
227
+ name: id
228
+ required: true
229
+ schema: { type: string }
230
+ responses:
231
+ "200":
232
+ description: "The shift document after soft-deletion (`disabled: true`)."
233
+ content:
234
+ application/json:
235
+ schema:
236
+ $ref: "#/components/schemas/ShiftSchema"
237
+ components:
238
+ securitySchemes:
239
+ ApiKeyAuth:
240
+ type: apiKey
241
+ in: header
242
+ name: api-key
243
+ description: |
244
+ Server-issued API key. Also accepted via the `x-api-key` header or the
245
+ `?apiKey=` query parameter as fallbacks.
246
+ JwtAuth:
247
+ type: apiKey
248
+ in: header
249
+ name: Authorization
250
+ description: |
251
+ Raw JWT in the `Authorization` header — **no `Bearer ` prefix**.
252
+ Obtained from `POST /authenticate` (admin / rep / client login).
253
+ schemas:
254
+ ShiftRange:
255
+ type: object
256
+ description: |
257
+ A single work interval in `HH:mm` wall-clock time (company time zone).
258
+ A range whose `to <= from` crosses midnight into the next calendar date.
259
+ required:
260
+ - from
261
+ - to
262
+ properties:
263
+ from:
264
+ type: string
265
+ pattern: "^([01]\\d|2[0-3]):[0-5]\\d$"
266
+ example: "18:00"
267
+ to:
268
+ type: string
269
+ pattern: "^([01]\\d|2[0-3]):[0-5]\\d$"
270
+ example: "02:00"
271
+ ShiftEntry:
272
+ type: object
273
+ description: One weekday's work_time ranges.
274
+ required:
275
+ - day
276
+ - work_time
277
+ properties:
278
+ day:
279
+ type: string
280
+ enum: [sunday, monday, tuesday, wednesday, thursday, friday, saturday]
281
+ work_time:
282
+ type: array
283
+ minItems: 1
284
+ items:
285
+ $ref: "#/components/schemas/ShiftRange"
286
+ ShiftSchema:
287
+ type: object
288
+ description: Shift document.
289
+ properties:
290
+ _id:
291
+ type: string
292
+ description: Unique identifier for the shift.
293
+ name:
294
+ type: string
295
+ description: Display name.
296
+ designation:
297
+ type: string
298
+ description: Optional free-text label for the shift.
299
+ disabled:
300
+ type: boolean
301
+ description: Soft-delete flag.
302
+ schedule:
303
+ type: array
304
+ minItems: 1
305
+ items:
306
+ $ref: "#/components/schemas/ShiftEntry"
307
+ description: Weekly work schedule (per-weekday work_time ranges).
308
+ total_working_hours:
309
+ type: number
310
+ description: |
311
+ Server-computed total working hours across the schedule
312
+ (cross-midnight ranges counted correctly). Derived on write.
313
+ total_working_days:
314
+ type: number
315
+ description: |
316
+ Server-computed count of weekdays with at least one work_time
317
+ range. Derived on write.
318
+ company_namespace:
319
+ type: array
320
+ items: { type: string }
321
+ description: Tenant key. Server-injected — never accept from clients.
322
+ createdAt:
323
+ type: string
324
+ format: date-time
325
+ description: Creation timestamp.
326
+ updatedAt:
327
+ type: string
328
+ format: date-time
329
+ description: Last update timestamp.
330
+ ShiftCreateBody:
331
+ type: object
332
+ description: |
333
+ Body for creating a shift. The tenant key (`company_namespace`) is
334
+ optional for SDK callers and is otherwise injected from the caller's
335
+ session. `schedule` is validated on write.
336
+ required:
337
+ - name
338
+ - schedule
339
+ properties:
340
+ name:
341
+ type: string
342
+ description: Display name.
343
+ designation:
344
+ type: string
345
+ description: Optional free-text label for the shift.
346
+ schedule:
347
+ type: array
348
+ minItems: 1
349
+ items:
350
+ $ref: "#/components/schemas/ShiftEntry"
351
+ company_namespace:
352
+ type: array
353
+ items: { type: string }
354
+ description: Optional tenant namespace override for SDK callers.
355
+ ShiftUpdateBody:
356
+ type: object
357
+ description: |
358
+ Body for updating a shift. The tenant key (`company_namespace`) is
359
+ derived from the caller's session — do not send it. When `schedule` is
360
+ present it is validated. Set `disabled: true` to soft-delete.
361
+ properties:
362
+ name:
363
+ type: string
364
+ designation:
365
+ type: string
366
+ schedule:
367
+ type: array
368
+ minItems: 1
369
+ items:
370
+ $ref: "#/components/schemas/ShiftEntry"
371
+ disabled:
372
+ type: boolean
373
+ description: |
374
+ Soft-delete flag. Set to `true` to disable the shift — rejected
375
+ while any active rep is still assigned to it.
376
+ ShiftFindResult:
377
+ type: object
378
+ description: Standard paginated result envelope.
379
+ properties:
380
+ data:
381
+ type: array
382
+ items:
383
+ $ref: "#/components/schemas/ShiftSchema"
384
+ total_result:
385
+ type: number
386
+ description: Total number of shifts matching the filter.
387
+ current_count:
388
+ type: number
389
+ description: Count of shifts on the current page.
390
+ total_pages:
391
+ type: number
392
+ description: Total number of pages.
393
+ current_page:
394
+ type: number
395
+ description: Current page number.
396
+ per_page:
397
+ type: number
398
+ description: Number of shifts per page.
399
+ first_page_url:
400
+ type: string
401
+ description: URL for the first page.
402
+ last_page_url:
403
+ type: string
404
+ description: URL for the last page.
405
+ next_page_url:
406
+ type: string
407
+ nullable: true
408
+ description: URL for the next page.
409
+ prev_page_url:
410
+ type: string
411
+ nullable: true
412
+ description: URL for the previous page.
413
+ path:
414
+ type: string
415
+ description: Base URL path.
package/src/oas/day.yaml CHANGED
@@ -30,12 +30,20 @@ paths:
30
30
  items:
31
31
  type: string
32
32
  - type: string
33
+ reps:
34
+ oneOf:
35
+ - type: array
36
+ items:
37
+ type: string
38
+ - type: string
33
39
  date:
34
40
  type: string
35
41
  format: date
36
42
  status:
37
43
  type: string
38
44
  enum: [open, closed, submitted]
45
+ not_working_day:
46
+ type: boolean
39
47
  from_date:
40
48
  type: string
41
49
  format: date
@@ -151,6 +159,9 @@ components:
151
159
  type: string
152
160
  enum: [open, closed, submitted]
153
161
  description: Status of the day
162
+ not_working_day:
163
+ type: boolean
164
+ description: Server-set flag for days that fall on a scheduled day off of the rep's assigned shift.
154
165
  visits:
155
166
  type: array
156
167
  items:
package/src/oas/rep.yaml CHANGED
@@ -147,6 +147,12 @@ paths:
147
147
  items:
148
148
  type: string
149
149
  - type: string
150
+ assigned_shift:
151
+ oneOf:
152
+ - type: array
153
+ items:
154
+ type: string
155
+ - type: string
150
156
  media:
151
157
  oneOf:
152
158
  - type: array
@@ -172,6 +178,7 @@ paths:
172
178
  "assigned_plan",
173
179
  "assigned_retail_execution_templates",
174
180
  "assigned_geo_zones",
181
+ "assigned_shift",
175
182
  "warehouse",
176
183
  ]
177
184
  withProductLines:
@@ -329,6 +336,12 @@ paths:
329
336
  type: boolean
330
337
  "permissions.rep_must_end_day_after_specific_time":
331
338
  type: boolean
339
+ "permissions.rep_must_start_day_within_shift_window":
340
+ type: boolean
341
+ "permissions.rep_must_end_day_within_shift_window":
342
+ type: boolean
343
+ "permissions.rep_can_start_day_on_non_working_day":
344
+ type: boolean
332
345
  "permissions.rep_can_create_negative_invoice":
333
346
  type: boolean
334
347
  "settings.rep_must_end_day_after":
@@ -360,6 +373,12 @@ paths:
360
373
  type: boolean
361
374
  "settings.watermark_coordinates":
362
375
  type: boolean
376
+ "settings.start_day_minutes_before_shift_start":
377
+ type: number
378
+ "settings.start_day_minutes_after_shift_start":
379
+ type: number
380
+ "settings.end_day_minutes_before_shift_end":
381
+ type: number
363
382
  description: Query parameters for filtering reps
364
383
  responses:
365
384
  "200":
@@ -738,6 +757,15 @@ components:
738
757
  rep_must_end_day_after_specific_time:
739
758
  type: boolean
740
759
  description: Rep must end day after specific time
760
+ rep_must_start_day_within_shift_window:
761
+ type: boolean
762
+ description: When true, the rep may only open the day within the configured window around the assigned shift start.
763
+ rep_must_end_day_within_shift_window:
764
+ type: boolean
765
+ description: When true, the rep may only end the day from the configured offset before the assigned shift end.
766
+ rep_can_start_day_on_non_working_day:
767
+ type: boolean
768
+ description: When false, opening a day on an assigned-shift day off is rejected.
741
769
  rep_can_create_negative_invoice:
742
770
  type: boolean
743
771
  description: Rep can create negative invoice
@@ -861,6 +889,10 @@ components:
861
889
  items:
862
890
  type: string
863
891
  description: Assigned retail execution templates
892
+ assigned_shift:
893
+ type: string
894
+ nullable: true
895
+ description: "`_id` of the day-shift assigned to this rep (ref `day-shift`). `null` when unassigned."
864
896
  customFields:
865
897
  type: object
866
898
  additionalProperties:
@@ -926,6 +958,24 @@ components:
926
958
  type: string
927
959
  pattern: "^[0-9]{1,2}:[0-9]{2}$"
928
960
  description: Time rep must end day after (HH:MM format)
961
+ start_day_minutes_before_shift_start:
962
+ type: number
963
+ minimum: 0
964
+ maximum: 240
965
+ default: 0
966
+ description: Minutes before the assigned shift start from which the rep may open the day.
967
+ start_day_minutes_after_shift_start:
968
+ type: number
969
+ minimum: 0
970
+ maximum: 240
971
+ default: 0
972
+ description: Minutes after the assigned shift start until which the rep may open the day when shift-window enforcement is enabled.
973
+ end_day_minutes_before_shift_end:
974
+ type: number
975
+ minimum: 0
976
+ maximum: 240
977
+ default: 0
978
+ description: Minutes before the assigned shift end from which the rep may close the day when shift-window enforcement is enabled.
929
979
  integration_meta:
930
980
  type: object
931
981
  additionalProperties: true
@@ -1199,6 +1249,15 @@ components:
1199
1249
  rep_must_end_day_after_specific_time:
1200
1250
  type: boolean
1201
1251
  description: Rep must end day after specific time
1252
+ rep_must_start_day_within_shift_window:
1253
+ type: boolean
1254
+ description: When true, the rep may only open the day within the configured window around the assigned shift start.
1255
+ rep_must_end_day_within_shift_window:
1256
+ type: boolean
1257
+ description: When true, the rep may only end the day from the configured offset before the assigned shift end.
1258
+ rep_can_start_day_on_non_working_day:
1259
+ type: boolean
1260
+ description: When false, opening a day on an assigned-shift day off is rejected.
1202
1261
  rep_can_create_negative_invoice:
1203
1262
  type: boolean
1204
1263
  description: Rep can create negative invoice
@@ -1322,6 +1381,10 @@ components:
1322
1381
  items:
1323
1382
  type: string
1324
1383
  description: Assigned retail execution templates
1384
+ assigned_shift:
1385
+ type: string
1386
+ nullable: true
1387
+ description: "`_id` of the day-shift to assign to this rep (ref `day-shift`). Must reference an existing, active shift in the caller's namespace. Send `null` to clear the assignment."
1325
1388
  customFields:
1326
1389
  type: object
1327
1390
  additionalProperties:
@@ -1387,6 +1450,24 @@ components:
1387
1450
  type: string
1388
1451
  pattern: "^[0-9]{1,2}:[0-9]{2}$"
1389
1452
  description: Time rep must end day after (HH:MM format)
1453
+ start_day_minutes_before_shift_start:
1454
+ type: number
1455
+ minimum: 0
1456
+ maximum: 240
1457
+ default: 0
1458
+ description: Minutes before the assigned shift start from which the rep may open the day.
1459
+ start_day_minutes_after_shift_start:
1460
+ type: number
1461
+ minimum: 0
1462
+ maximum: 240
1463
+ default: 0
1464
+ description: Minutes after the assigned shift start until which the rep may open the day when shift-window enforcement is enabled.
1465
+ end_day_minutes_before_shift_end:
1466
+ type: number
1467
+ minimum: 0
1468
+ maximum: 240
1469
+ default: 0
1470
+ description: Minutes before the assigned shift end from which the rep may close the day when shift-window enforcement is enabled.
1390
1471
  integration_meta:
1391
1472
  type: object
1392
1473
  additionalProperties: true
@@ -1650,6 +1731,15 @@ components:
1650
1731
  rep_must_end_day_after_specific_time:
1651
1732
  type: boolean
1652
1733
  description: Rep must end day after specific time
1734
+ rep_must_start_day_within_shift_window:
1735
+ type: boolean
1736
+ description: When true, the rep may only open the day within the configured window around the assigned shift start.
1737
+ rep_must_end_day_within_shift_window:
1738
+ type: boolean
1739
+ description: When true, the rep may only end the day from the configured offset before the assigned shift end.
1740
+ rep_can_start_day_on_non_working_day:
1741
+ type: boolean
1742
+ description: When false, opening a day on an assigned-shift day off is rejected.
1653
1743
  rep_can_create_negative_invoice:
1654
1744
  type: boolean
1655
1745
  description: Rep can create negative invoice
@@ -1773,6 +1863,10 @@ components:
1773
1863
  items:
1774
1864
  type: string
1775
1865
  description: Assigned retail execution templates
1866
+ assigned_shift:
1867
+ type: string
1868
+ nullable: true
1869
+ description: "`_id` of the day-shift to assign to this rep (ref `day-shift`). Must reference an existing, active shift in the caller's namespace. Send `null` to clear the assignment."
1776
1870
  customFields:
1777
1871
  type: object
1778
1872
  additionalProperties:
@@ -1838,6 +1932,24 @@ components:
1838
1932
  type: string
1839
1933
  pattern: "^[0-9]{1,2}:[0-9]{2}$"
1840
1934
  description: Time rep must end day after (HH:MM format)
1935
+ start_day_minutes_before_shift_start:
1936
+ type: number
1937
+ minimum: 0
1938
+ maximum: 240
1939
+ default: 0
1940
+ description: Minutes before the assigned shift start from which the rep may open the day.
1941
+ start_day_minutes_after_shift_start:
1942
+ type: number
1943
+ minimum: 0
1944
+ maximum: 240
1945
+ default: 0
1946
+ description: Minutes after the assigned shift start until which the rep may open the day when shift-window enforcement is enabled.
1947
+ end_day_minutes_before_shift_end:
1948
+ type: number
1949
+ minimum: 0
1950
+ maximum: 240
1951
+ default: 0
1952
+ description: Minutes before the assigned shift end from which the rep may close the day when shift-window enforcement is enabled.
1841
1953
  integration_meta:
1842
1954
  type: object
1843
1955
  additionalProperties: true
@@ -93,6 +93,27 @@ components:
93
93
  type: string
94
94
  description:
95
95
  type: string
96
+ calculate_target_for_non_working_days:
97
+ type: boolean
98
+ default: false
99
+ description: "When true, system-created absent days that fall on a scheduled day off of the rep's assigned shift still trigger target calculation."
100
+ end_of_day:
101
+ type: string
102
+ description: "Per-namespace day-cutover time as HH:mm. Propagated to company-namespaces.end_of_day."
103
+ time_zone:
104
+ type: string
105
+ description: "Per-namespace IANA time zone. Propagated to company-namespaces.time_zone."
106
+ end_of_day_mode:
107
+ type: string
108
+ enum: [fixed_time, shift_based]
109
+ default: fixed_time
110
+ description: "How the namespace determines the end-of-day cutover: fixed_time uses the company end_of_day setting; shift_based derives it from assigned day shifts."
111
+ automatic_end_day_minutes_after_shift_end:
112
+ type: integer
113
+ minimum: 0
114
+ maximum: 240
115
+ default: 0
116
+ description: "Shift-based mode only: minutes after a shift-based day's shift end before the system auto-closes it."
96
117
  start_day_outside_active_zone_action:
97
118
  type: string
98
119
  enum: [monitor, warning, block]
@@ -145,6 +166,21 @@ components:
145
166
  type: string
146
167
  description:
147
168
  type: string
169
+ calculate_target_for_non_working_days:
170
+ type: boolean
171
+ default: false
172
+ description: "When true, system-created absent days that fall on a scheduled day off of the rep's assigned shift still trigger target calculation."
173
+ end_of_day_mode:
174
+ type: string
175
+ enum: [fixed_time, shift_based]
176
+ default: fixed_time
177
+ description: "How the namespace determines the end-of-day cutover: fixed_time uses the company end_of_day setting; shift_based derives it from assigned day shifts."
178
+ automatic_end_day_minutes_after_shift_end:
179
+ type: integer
180
+ minimum: 0
181
+ maximum: 240
182
+ default: 0
183
+ description: "Shift-based mode only: minutes after a shift-based day's shift end before the system auto-closes it."
148
184
  start_day_outside_active_zone_action:
149
185
  type: string
150
186
  enum: [monitor, warning, block]