@dsptch-work/api-client 0.41.0 → 0.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,208 @@ All notable changes to `@dsptch-work/api-client` are documented here. The format
5
5
  [Semantic Versioning](https://semver.org) — currently `0.x`, so breaking changes may land in a
6
6
  minor bump until `1.0.0`. See [RELEASING.md](./RELEASING.md) for the release and versioning process.
7
7
 
8
+ ## [0.43.0] - 2026-10-22
9
+
10
+ ### Added
11
+
12
+ - `ProductionPlannedFeatureTasks` adds `listPlannedFeatureTasks()`, `getPlannedFeatureTask()`,
13
+ `createPlannedFeatureTask()`, `updatePlannedFeatureTask()`, and `updateArchive()`, with
14
+ `ProductionPlannedFeatureTaskParameters`, `ProductionPlannedFeatureTaskUpdateParameters`,
15
+ `ProductionPlannedFeatureTaskArchiveParameters`, `ProductionPlannedFeatureTaskResponseObject`,
16
+ operation types, and Zod schemas. Create requires `feature_id`; the response keeps stable
17
+ `id` and `task_id` plus nullable `production_completion_id`, `archived_at`, and `time_due`.
18
+ Intended `task_assignee_user_ids` and deadlines do not record actual crew or completed work.
19
+ Company keys must supply `performed_by_user_id` on every write, although it is optional in
20
+ the generated types; user keys may omit it or supply only their own ID. Omission preserves
21
+ existing metadata on update or re-add; null clears `description` / `time_due`, and `[]`
22
+ clears intended people. `updateArchive()` requires `body.archived` and
23
+ `path.planned_feature_task_id`; restoring or re-adding keeps the same identity. List returns
24
+ both current and archived entries by default; set `query['filter[archived]']` to `false` or
25
+ `true` to select one state. Grant `jobs.production.job_scope_prices.planned_feature_tasks:read|create|update`
26
+ and `jobs.production.job_scope_prices.planned_feature_tasks.archives:update` as needed.
27
+ - The new planning Zod input schemas validate `performed_by_user_id` as a UUID, but do not
28
+ enforce company-key actor requirements, distinct assignees, or valid `tz_name` values;
29
+ the API validates these. If using these schemas for `time_due`, normalize offset timestamps
30
+ to UTC `Z`: their `z.iso.datetime()` rejects numeric offsets even though the API accepts them.
31
+ - `ProductionDeliveryTargets` adds `listDeliveryTargets()`, `getDeliveryTarget()`,
32
+ `createDeliveryTarget()`, `updateDeliveryTarget()`, and `deleteDeliveryTarget()`, with
33
+ `ProductionDeliveryTargetParameters`, `ProductionDeliveryTargetUpdateParameters`,
34
+ `ProductionDeliveryTargetResponseObject`, operation types, and Zod schemas. All methods
35
+ take the owning `path.job_id` / `path.job_scope_price_id`; grant
36
+ `jobs.production.delivery_targets:read|create|update|delete` as needed. On Feature-tracked
37
+ jobs, create requires a Job-local calendar `due_date` and
38
+ `condition_attributes.requirement_kind: 'count' | 'all'`. For `'count'`, supply a positive
39
+ integer `required_count`; for `'all'`, omit it or send null. Updates preserve omitted fields:
40
+ switching count to all requires `required_count: null`, and switching all to count requires
41
+ a positive count. Exported Zod schemas validate dates, enum values, and positive integers,
42
+ while the API enforces these conditional rules. Company keys are supported; no
43
+ `performed_by_user_id`, condition identity, or condition type is accepted. Delete returns
44
+ `204` without a body and removes the target and its condition; planned work and completions remain.
45
+ - `ProductionDeliveryTargetResponseObject.assessment` distinguishes `required_total`,
46
+ `qualifying_count` (effective work dated on or before the inclusive Job-local deadline),
47
+ `current_achieved_count` (including later work), and `shortfall`. Handle all five `state`
48
+ values: `'unavailable'`, `'awaiting_named_scope'`, `'met_by_date'`,
49
+ `'remaining_before_deadline'`, and `'shortfall_after_deadline'`. Missing visibility of
50
+ named membership or its completion evidence returns `'unavailable'` with null
51
+ `qualifying_count`, `current_achieved_count`, and `shortfall`. A fixed count remains visible
52
+ in `condition.required_count` and `assessment.required_total`; an all requirement's
53
+ `required_total` is null. Do not treat null as zero or as a missed target; an empty all
54
+ requirement awaits named scope. List pagination limits
55
+ targets, while each assessment still uses the whole current named scope. Targets do not
56
+ create planned work or record completions.
57
+ - `ProductionCompletions` adds `listCompletionHistory()`, `getCompletionHistory()`, and
58
+ `setCompletionWithdrawal()`, with `ProductionCompletionWithdrawalParameters`, operation types,
59
+ and Zod schemas. History returns each retained record's current corrected facts, including
60
+ withdrawn Feature claims, rather than prior versions. It accepts job, scope-kind, Feature,
61
+ and inclusive `filter[work_date][gte]` / `filter[work_date][lte]` filters. Grant
62
+ `production.completions.history:read`. Withdrawal uses `path.completion_id` and required
63
+ `body.withdrawn`; `true` withdraws and `false` restores the same Feature completion ID,
64
+ idempotently. Grant `production.completions.withdrawals:update`. Quantity completions and
65
+ restoration over an effective replacement return `422`. The history query Zod schema
66
+ validates date strings but leaves inverted date ranges to API validation.
67
+ - `Jobs` adds `listCaEcprXmlExports()`, `getCaEcprXmlExport()`, and
68
+ `createCaEcprXmlExport()`, with `JobCaEcprXmlExportCreateParameters`,
69
+ `JobCaEcprXmlExportResponseObject`, `JobCaEcprXmlExportsResponseObject`, operation types,
70
+ and Zod schemas. Grant `jobs.pwa.certified_payrolls.ca_ecpr_xml_exports:read|create` as needed.
71
+ Create requires a user-scoped key with financial permission and calendar-day `start_date` /
72
+ `end_date` strings (`YYYY-MM-DD`), with `start_date <= end_date`. It returns `201` with the
73
+ pending export. Company keys receive `403` on create; missing dates return `400`.
74
+ A job without matching CA prevailing-wage eligibility returns `422 certified_payroll_format_unavailable`;
75
+ a window without reportable pay periods returns `422 nothing_exportable`. Inverted windows
76
+ return `422 validation_failed` pointing to `end_date`; the exported Zod input schema validates
77
+ individual dates but does not compare their order. Filename is server-owned; the create
78
+ parameters accept no filename, version, or signing inputs, and creation does not start signing.
79
+ List is paginated and accepts comma-separated statuses in `query['filter[status]']`. Poll
80
+ the member read for generation status and a nonnull `file`; `status: 'success'` alone does
81
+ not guarantee an attached XML or ZIP. Responses include required nullable `invalidated_at`
82
+ and `invalidation_reason`; this format has no form-version field.
83
+
84
+ ### Changed
85
+
86
+ - **Required response field:** `ProductionFeatureCompletionResponseObject` and
87
+ `ProductionQuantityCompletionResponseObject` add `withdrawn_at: string | null` through
88
+ `ProductionCompletionResponseObject`. Update typed fixtures and mock responses to supply it;
89
+ the corresponding Zod response schemas now reject omission. Effective Feature completions
90
+ and all Quantity completions return null. Ordinary completion reads continue to exclude
91
+ withdrawn Feature claims; use the new history methods to retrieve them.
92
+ - `Jobs.updateJob()` now returns `422` when changing `production_tracking_kind` away from
93
+ `'feature'` while active planned Feature tasks or delivery targets exist. Archive those tasks
94
+ and remove the targets first; the existing restriction on recorded completions still applies.
95
+ `ProductionJobScopePrices.deleteJobScopePrice()` now returns `422` while delivery targets or
96
+ any planned Feature tasks are retained, including archived tasks. Remove targets before
97
+ deleting their scope; archiving planned tasks does not enable scope deletion. Generated
98
+ signatures are unchanged.
99
+ - New WH-347 exports created through `Jobs.createWh347Export()` use a default
100
+ `JobWh347ExportResponseObject.file.filename` of
101
+ `wh347_<canonical-job-name>_<first-pay-period-start>_<last-pay-period-end>.zip`.
102
+ The interval covers the included pay periods; the filename no longer carries the form
103
+ version. Read `JobWh347ExportResponseObject.version` instead of parsing a filename.
104
+ - The runtime Zod dependency advances from `^4.4.3` to `^4.6.7`.
105
+
106
+ See the [October 22 API changelog](https://dsptch.app/support/docs/developers/api-changelog#2026-10-22)
107
+ for the complete REST contract details and error behavior.
108
+
109
+ ## [0.42.0] - 2026-10-21
110
+
111
+ ### Added
112
+
113
+ - `Jobs` adds `listWh347Exports()`, `createWh347Export()`, and `getWh347Export()`, with
114
+ `JobWh347ExportCreateParameters`, `JobWh347ExportResponseObject`,
115
+ `JobWh347ExportsResponseObject`, operation types, and Zod schemas. Create requires a
116
+ user-scoped key and calendar-day `start_date` / `end_date` for a job tracking federal
117
+ prevailing wage. Grant `jobs.pwa.certified_payrolls.wh347_exports:read|create`. Poll the
118
+ member read for generation status and a nonnull `file`; `status: 'success'` alone does not
119
+ guarantee an attached file. API creation does not start signing.
120
+ - `AssetsItems.deleteFormAssignmentTask()`, `Jobs.deleteJobFormAssignmentTask()`,
121
+ `OversiteFeatureFormAssignmentTasks.deleteFeatureFormAssignmentTask()`, and
122
+ `OversiteSiteFormAssignmentTasks.deleteSiteFormAssignmentTask()` add operation types and
123
+ Zod schemas. Supply the nested task's ID and the corresponding delete scope. Only the open,
124
+ incomplete permanent copy can be ended; success returns `204`, and an ineligible copy
125
+ returns `422 not_incomplete_permanent_copy`. Recurrence changes stay on update.
126
+ - `TimeEntryCreateParameters` and `TimeEntryUpdateParameters` accept optional nullable
127
+ `one_five_x_adder_rate_cents` and `two_x_adder_rate_cents` through `TimeEntries.createTimeEntry()`
128
+ and `updateTimeEntry()`. Each premium is added after applying that tier's overtime multiplier
129
+ to the base hourly rate: $30 × 1.5 + $3 pays $48 per hour. Send nonnegative decimal cents
130
+ strings, including fractional cents or zero. Omission derives
131
+ the automatic premium on create and preserves it on update; null resets that tier to automatic.
132
+ `TimeEntryResponseObject` adds the optional nullable amounts and read-only
133
+ `one_five_x_adder_rate_src_type` / `two_x_adder_rate_src_type`, each
134
+ `'position' | 'prevailing_wage' | 'custom' | null`. Company keys and company-admin user keys
135
+ can write and receive these fields; other user keys receive `403` when writing them,
136
+ including null. The Zod input schemas validate decimal strings.
137
+
138
+ ### Changed
139
+
140
+ - **Breaking:** `Billing.listPwaUserCountsByProjectByMonths()` now returns
141
+ `ListPwaUserCountsByProjectByMonthsResponse` as `{ meta, links, data }` instead of a bare
142
+ array. Read rows from `data` and follow pagination; the default page has 20 rows and
143
+ `query['page[limit]']` is capped at 100. `query['filter[year_month]']` must be `YYYY-MM`;
144
+ the generated Zod query schema now validates this format and positive integer limits.
145
+ - **Breaking response change:** `ProductionJobScopePriceResponseObject.unit_price_cents`
146
+ becomes optional nullable. Handle null as unknown and any decimal string numerically equal
147
+ to zero (for example, `"0.0"`) as a known zero, separately from omission for financial access.
148
+ `ProductionJobScopePriceParameters.unit_price_cents`
149
+ becomes optional nullable, and `ProductionJobScopePriceUpdateParameters.unit_price_cents`
150
+ becomes nullable. `ProductionJobScopePrices.createJobScopePrice()` accepts omission or null;
151
+ `updateJobScopePrice()` preserves omission and clears to unknown on null. The matching
152
+ Zod schemas accept these shapes.
153
+ - `ProductionCompletions.deleteCompletion()` now withdraws Feature completions while retaining
154
+ their ID and crew history; repeated deletes return `200`. Withdrawn reports disappear from
155
+ `listCompletions()` and `getCompletion()` returns `404`; updating one does not restore it.
156
+ Quantity-completion deletion and generated signatures are unchanged.
157
+
158
+ ### Removed
159
+
160
+ - **Breaking:** `RegionalWageDeterminationFieldsResponse`, returned in job and project
161
+ determination `regional_fields`, no longer includes `one_five_x_adder_rate_cents`,
162
+ `two_x_adder_rate_cents`, `one_five_x_fringe_adder_rate_cents`, or
163
+ `two_x_fringe_adder_rate_cents`. Read overtime wage and fringe premiums through
164
+ `JobWageDeterminationRateRules` or `ProjectWageDeterminationRateRules`. Its generated
165
+ dictionary type and Zod validator are unchanged, so they do not expose this removal;
166
+ categorized fringe fields remain available where the region requires them.
167
+
168
+ ### Fixed
169
+
170
+ - **Breaking runtime validation:** `Jobs.createGoodFaithEffortException()` and
171
+ `updateGoodFaithEffortException()` require `minutes_per_apprentice` to be a positive
172
+ integer multiple of 60, such as `480` for eight hours. The parameter types remain `number | null`,
173
+ and the generated Zod schemas do not enforce the multiple-of-60 rule; the API returns `422`
174
+ for other values.
175
+ - `Certifications.createCertification()` and `UserRoles.addUserRoles()` now return `201`.
176
+ `CreateCertificationResponses` and `AddUserRolesResponses` replace their `200` keys with
177
+ `201`; code inspecting status codes or those keyed types must change.
178
+ - `Jobs.createPosition()` / `updatePosition()` reject a position with only one schedule bound
179
+ with `422` and a field pointer, rather than silently leaving an unscheduled position unchanged.
180
+ Send both bounds to schedule an unscheduled position; existing request types are unchanged.
181
+ - Repeated members now return `422` in `CompetenciesCriteria.createCriterion()` /
182
+ `updateCriterion()` assessment methods, `AssetsProducts.seedServiceScheduleTemplate()` item IDs,
183
+ `syncServiceScheduleTemplate()` schedule IDs, and the four worker-demographic code arrays in
184
+ `Users.createCompanyUserDetail()`, `updateCompanyUserDetail()`, and
185
+ `createUser()`'s `company_user_pwa_info`. Deduplicate lists before submitting them; generated
186
+ array types and Zod validators are unchanged.
187
+ - `ProjectSites.listProjectSites()`, `ProjectWageDeterminations.listProjectWageDeterminations()`,
188
+ `ProjectWageDeterminationRateRules.listProjectWageDeterminationRateRules()`,
189
+ `ProjectDocuments.listProjectDocumentVersions()`, and `AssetsItems.listVersions()` now reject
190
+ `filter[...]` keys with `400`. Remove unsupported filters even though generated query types
191
+ expose hidden malformed-filter test parameters; these lists support no filters.
192
+
193
+ ### Security
194
+
195
+ - **Breaking runtime authorization:** `TimeCardResponseObject` and
196
+ `JobTimeCardDayResponseObject` now omit `pay_cents`, `base_wage_pay_cents`,
197
+ `one_five_x_adder_cents`, and `two_x_adder_cents` for non-admin user keys reading another
198
+ person's card, including managers. Day responses also omit the corresponding `cumulative_`
199
+ and `weekly_cumulative_` fields. Company keys, company admins, and the card's owner retain
200
+ wages; per diem rates are unchanged. These properties were already optional in the generated
201
+ types and Zod schemas; handle their absence on both list and member reads.
202
+ - **Breaking runtime authorization:** `PerDiems.listPerDiems()` now returns `403` for user keys
203
+ whose user is neither an admin nor a manager at the key's company. `getPerDiem()` now admits
204
+ managers; company-key access is unchanged and user-key writes remain admin-only. Signatures
205
+ are unchanged.
206
+
207
+ See the [October 21 API changelog](https://dsptch.app/support/docs/developers/api-changelog#2026-10-21)
208
+ for the complete REST contract details and error behavior.
209
+
8
210
  ## [0.41.0] - 2026-10-20
9
211
 
10
212
  ### Added