@deepintel-ltd/buildlink-api-contracts 0.2.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/README.md +27 -0
  2. package/contracts/auth.d.ts +3641 -0
  3. package/contracts/auth.d.ts.map +1 -0
  4. package/contracts/auth.js +266 -0
  5. package/contracts/auth.js.map +1 -0
  6. package/contracts/billing.d.ts +2167 -0
  7. package/contracts/billing.d.ts.map +1 -0
  8. package/contracts/billing.js +55 -0
  9. package/contracts/billing.js.map +1 -0
  10. package/contracts/boq.d.ts +1214 -0
  11. package/contracts/boq.d.ts.map +1 -0
  12. package/contracts/boq.js +31 -0
  13. package/contracts/boq.js.map +1 -0
  14. package/contracts/budget.d.ts +10677 -0
  15. package/contracts/budget.d.ts.map +1 -0
  16. package/contracts/budget.js +599 -0
  17. package/contracts/budget.js.map +1 -0
  18. package/contracts/commercial.d.ts +1475 -0
  19. package/contracts/commercial.d.ts.map +1 -0
  20. package/contracts/commercial.js +40 -0
  21. package/contracts/commercial.js.map +1 -0
  22. package/contracts/communication.d.ts +5389 -0
  23. package/contracts/communication.d.ts.map +1 -0
  24. package/contracts/communication.js +255 -0
  25. package/contracts/communication.js.map +1 -0
  26. package/contracts/contractor-ledger.d.ts +1293 -0
  27. package/contracts/contractor-ledger.d.ts.map +1 -0
  28. package/contracts/contractor-ledger.js +41 -0
  29. package/contracts/contractor-ledger.js.map +1 -0
  30. package/contracts/daily-logs.d.ts +9132 -0
  31. package/contracts/daily-logs.d.ts.map +1 -0
  32. package/contracts/daily-logs.js +188 -0
  33. package/contracts/daily-logs.js.map +1 -0
  34. package/contracts/deficiencies.d.ts +11786 -0
  35. package/contracts/deficiencies.d.ts.map +1 -0
  36. package/contracts/deficiencies.js +312 -0
  37. package/contracts/deficiencies.js.map +1 -0
  38. package/contracts/directory.d.ts +3116 -0
  39. package/contracts/directory.d.ts.map +1 -0
  40. package/contracts/directory.js +117 -0
  41. package/contracts/directory.js.map +1 -0
  42. package/contracts/documents.d.ts +4944 -0
  43. package/contracts/documents.d.ts.map +1 -0
  44. package/contracts/documents.js +251 -0
  45. package/contracts/documents.js.map +1 -0
  46. package/contracts/drawings.d.ts +10552 -0
  47. package/contracts/drawings.d.ts.map +1 -0
  48. package/contracts/drawings.js +321 -0
  49. package/contracts/drawings.js.map +1 -0
  50. package/contracts/hub.d.ts +1174 -0
  51. package/contracts/hub.d.ts.map +1 -0
  52. package/contracts/hub.js +42 -0
  53. package/contracts/hub.js.map +1 -0
  54. package/contracts/index.d.ts +128 -0
  55. package/contracts/index.d.ts.map +1 -0
  56. package/contracts/index.js +119 -0
  57. package/contracts/index.js.map +1 -0
  58. package/contracts/integrations.d.ts +4163 -0
  59. package/contracts/integrations.d.ts.map +1 -0
  60. package/contracts/integrations.js +326 -0
  61. package/contracts/integrations.js.map +1 -0
  62. package/contracts/maps.d.ts +4911 -0
  63. package/contracts/maps.d.ts.map +1 -0
  64. package/contracts/maps.js +276 -0
  65. package/contracts/maps.js.map +1 -0
  66. package/contracts/meetings.d.ts +4194 -0
  67. package/contracts/meetings.d.ts.map +1 -0
  68. package/contracts/meetings.js +115 -0
  69. package/contracts/meetings.js.map +1 -0
  70. package/contracts/monitoring.d.ts +2749 -0
  71. package/contracts/monitoring.d.ts.map +1 -0
  72. package/contracts/monitoring.js +289 -0
  73. package/contracts/monitoring.js.map +1 -0
  74. package/contracts/packages.d.ts +1470 -0
  75. package/contracts/packages.d.ts.map +1 -0
  76. package/contracts/packages.js +74 -0
  77. package/contracts/packages.js.map +1 -0
  78. package/contracts/projects.d.ts +6281 -0
  79. package/contracts/projects.d.ts.map +1 -0
  80. package/contracts/projects.js +448 -0
  81. package/contracts/projects.js.map +1 -0
  82. package/contracts/proof.d.ts +962 -0
  83. package/contracts/proof.d.ts.map +1 -0
  84. package/contracts/proof.js +34 -0
  85. package/contracts/proof.js.map +1 -0
  86. package/contracts/qaqc.d.ts +1184 -0
  87. package/contracts/qaqc.d.ts.map +1 -0
  88. package/contracts/qaqc.js +35 -0
  89. package/contracts/qaqc.js.map +1 -0
  90. package/contracts/rbac.d.ts +5227 -0
  91. package/contracts/rbac.d.ts.map +1 -0
  92. package/contracts/rbac.js +357 -0
  93. package/contracts/rbac.js.map +1 -0
  94. package/contracts/reports.d.ts +8468 -0
  95. package/contracts/reports.d.ts.map +1 -0
  96. package/contracts/reports.js +377 -0
  97. package/contracts/reports.js.map +1 -0
  98. package/contracts/resources.d.ts +15870 -0
  99. package/contracts/resources.d.ts.map +1 -0
  100. package/contracts/resources.js +869 -0
  101. package/contracts/resources.js.map +1 -0
  102. package/contracts/rfi-submittal.d.ts +2545 -0
  103. package/contracts/rfi-submittal.d.ts.map +1 -0
  104. package/contracts/rfi-submittal.js +159 -0
  105. package/contracts/rfi-submittal.js.map +1 -0
  106. package/contracts/safety.d.ts +7162 -0
  107. package/contracts/safety.d.ts.map +1 -0
  108. package/contracts/safety.js +519 -0
  109. package/contracts/safety.js.map +1 -0
  110. package/contracts/schedule.d.ts +9456 -0
  111. package/contracts/schedule.d.ts.map +1 -0
  112. package/contracts/schedule.js +460 -0
  113. package/contracts/schedule.js.map +1 -0
  114. package/contracts/spec-equal.d.ts +841 -0
  115. package/contracts/spec-equal.d.ts.map +1 -0
  116. package/contracts/spec-equal.js +28 -0
  117. package/contracts/spec-equal.js.map +1 -0
  118. package/contracts/specifications.d.ts +15478 -0
  119. package/contracts/specifications.d.ts.map +1 -0
  120. package/contracts/specifications.js +521 -0
  121. package/contracts/specifications.js.map +1 -0
  122. package/contracts/tasks.d.ts +11037 -0
  123. package/contracts/tasks.d.ts.map +1 -0
  124. package/contracts/tasks.js +693 -0
  125. package/contracts/tasks.js.map +1 -0
  126. package/contracts/timecards.d.ts +3130 -0
  127. package/contracts/timecards.d.ts.map +1 -0
  128. package/contracts/timecards.js +133 -0
  129. package/contracts/timecards.js.map +1 -0
  130. package/contracts/transmittals.d.ts +3921 -0
  131. package/contracts/transmittals.d.ts.map +1 -0
  132. package/contracts/transmittals.js +156 -0
  133. package/contracts/transmittals.js.map +1 -0
  134. package/contracts/valuations.d.ts +3266 -0
  135. package/contracts/valuations.d.ts.map +1 -0
  136. package/contracts/valuations.js +116 -0
  137. package/contracts/valuations.js.map +1 -0
  138. package/package.json +216 -0
  139. package/schemas/auth.d.ts +449 -0
  140. package/schemas/auth.d.ts.map +1 -0
  141. package/schemas/auth.js +103 -0
  142. package/schemas/auth.js.map +1 -0
  143. package/schemas/billing.d.ts +710 -0
  144. package/schemas/billing.d.ts.map +1 -0
  145. package/schemas/billing.js +82 -0
  146. package/schemas/billing.js.map +1 -0
  147. package/schemas/boq.d.ts +385 -0
  148. package/schemas/boq.d.ts.map +1 -0
  149. package/schemas/boq.js +49 -0
  150. package/schemas/boq.js.map +1 -0
  151. package/schemas/budget.d.ts +737 -0
  152. package/schemas/budget.d.ts.map +1 -0
  153. package/schemas/budget.js +272 -0
  154. package/schemas/budget.js.map +1 -0
  155. package/schemas/commercial.d.ts +358 -0
  156. package/schemas/commercial.d.ts.map +1 -0
  157. package/schemas/commercial.js +36 -0
  158. package/schemas/commercial.js.map +1 -0
  159. package/schemas/common.d.ts +865 -0
  160. package/schemas/common.d.ts.map +1 -0
  161. package/schemas/common.js +193 -0
  162. package/schemas/common.js.map +1 -0
  163. package/schemas/communication.d.ts +884 -0
  164. package/schemas/communication.d.ts.map +1 -0
  165. package/schemas/communication.js +245 -0
  166. package/schemas/communication.js.map +1 -0
  167. package/schemas/contractor-ledger.d.ts +364 -0
  168. package/schemas/contractor-ledger.d.ts.map +1 -0
  169. package/schemas/contractor-ledger.js +36 -0
  170. package/schemas/contractor-ledger.js.map +1 -0
  171. package/schemas/cursor-pagination.d.ts +258 -0
  172. package/schemas/cursor-pagination.d.ts.map +1 -0
  173. package/schemas/cursor-pagination.js +84 -0
  174. package/schemas/cursor-pagination.js.map +1 -0
  175. package/schemas/daily-logs.d.ts +2339 -0
  176. package/schemas/daily-logs.d.ts.map +1 -0
  177. package/schemas/daily-logs.js +235 -0
  178. package/schemas/daily-logs.js.map +1 -0
  179. package/schemas/deficiencies.d.ts +2496 -0
  180. package/schemas/deficiencies.d.ts.map +1 -0
  181. package/schemas/deficiencies.js +338 -0
  182. package/schemas/deficiencies.js.map +1 -0
  183. package/schemas/directory.d.ts +783 -0
  184. package/schemas/directory.d.ts.map +1 -0
  185. package/schemas/directory.js +122 -0
  186. package/schemas/directory.js.map +1 -0
  187. package/schemas/documents.d.ts +202 -0
  188. package/schemas/documents.d.ts.map +1 -0
  189. package/schemas/documents.js +76 -0
  190. package/schemas/documents.js.map +1 -0
  191. package/schemas/drawings.d.ts +2042 -0
  192. package/schemas/drawings.d.ts.map +1 -0
  193. package/schemas/drawings.js +350 -0
  194. package/schemas/drawings.js.map +1 -0
  195. package/schemas/hub.d.ts +288 -0
  196. package/schemas/hub.d.ts.map +1 -0
  197. package/schemas/hub.js +32 -0
  198. package/schemas/hub.js.map +1 -0
  199. package/schemas/integrations.d.ts +508 -0
  200. package/schemas/integrations.d.ts.map +1 -0
  201. package/schemas/integrations.js +119 -0
  202. package/schemas/integrations.js.map +1 -0
  203. package/schemas/maps.d.ts +793 -0
  204. package/schemas/maps.d.ts.map +1 -0
  205. package/schemas/maps.js +118 -0
  206. package/schemas/maps.js.map +1 -0
  207. package/schemas/meetings.d.ts +888 -0
  208. package/schemas/meetings.d.ts.map +1 -0
  209. package/schemas/meetings.js +138 -0
  210. package/schemas/meetings.js.map +1 -0
  211. package/schemas/packages.d.ts +236 -0
  212. package/schemas/packages.d.ts.map +1 -0
  213. package/schemas/packages.js +53 -0
  214. package/schemas/packages.js.map +1 -0
  215. package/schemas/projects.d.ts +306 -0
  216. package/schemas/projects.d.ts.map +1 -0
  217. package/schemas/projects.js +92 -0
  218. package/schemas/projects.js.map +1 -0
  219. package/schemas/proof.d.ts +210 -0
  220. package/schemas/proof.d.ts.map +1 -0
  221. package/schemas/proof.js +26 -0
  222. package/schemas/proof.js.map +1 -0
  223. package/schemas/qaqc.d.ts +235 -0
  224. package/schemas/qaqc.d.ts.map +1 -0
  225. package/schemas/qaqc.js +47 -0
  226. package/schemas/qaqc.js.map +1 -0
  227. package/schemas/rbac.d.ts +730 -0
  228. package/schemas/rbac.d.ts.map +1 -0
  229. package/schemas/rbac.js +230 -0
  230. package/schemas/rbac.js.map +1 -0
  231. package/schemas/reports.d.ts +5729 -0
  232. package/schemas/reports.d.ts.map +1 -0
  233. package/schemas/reports.js +589 -0
  234. package/schemas/reports.js.map +1 -0
  235. package/schemas/resources.d.ts +5190 -0
  236. package/schemas/resources.d.ts.map +1 -0
  237. package/schemas/resources.js +678 -0
  238. package/schemas/resources.js.map +1 -0
  239. package/schemas/rfi.d.ts +877 -0
  240. package/schemas/rfi.d.ts.map +1 -0
  241. package/schemas/rfi.js +84 -0
  242. package/schemas/rfi.js.map +1 -0
  243. package/schemas/safety.d.ts +1080 -0
  244. package/schemas/safety.d.ts.map +1 -0
  245. package/schemas/safety.js +237 -0
  246. package/schemas/safety.js.map +1 -0
  247. package/schemas/schedule.d.ts +4657 -0
  248. package/schemas/schedule.d.ts.map +1 -0
  249. package/schemas/schedule.js +441 -0
  250. package/schemas/schedule.js.map +1 -0
  251. package/schemas/spec-equal.d.ts +162 -0
  252. package/schemas/spec-equal.d.ts.map +1 -0
  253. package/schemas/spec-equal.js +29 -0
  254. package/schemas/spec-equal.js.map +1 -0
  255. package/schemas/specifications.d.ts +5241 -0
  256. package/schemas/specifications.d.ts.map +1 -0
  257. package/schemas/specifications.js +426 -0
  258. package/schemas/specifications.js.map +1 -0
  259. package/schemas/submittal.d.ts +867 -0
  260. package/schemas/submittal.d.ts.map +1 -0
  261. package/schemas/submittal.js +87 -0
  262. package/schemas/submittal.js.map +1 -0
  263. package/schemas/tasks.d.ts +610 -0
  264. package/schemas/tasks.d.ts.map +1 -0
  265. package/schemas/tasks.js +133 -0
  266. package/schemas/tasks.js.map +1 -0
  267. package/schemas/timecards.d.ts +618 -0
  268. package/schemas/timecards.d.ts.map +1 -0
  269. package/schemas/timecards.js +80 -0
  270. package/schemas/timecards.js.map +1 -0
  271. package/schemas/transmittals.d.ts +662 -0
  272. package/schemas/transmittals.d.ts.map +1 -0
  273. package/schemas/transmittals.js +132 -0
  274. package/schemas/transmittals.js.map +1 -0
  275. package/schemas/valuations.d.ts +713 -0
  276. package/schemas/valuations.d.ts.map +1 -0
  277. package/schemas/valuations.js +116 -0
  278. package/schemas/valuations.js.map +1 -0
@@ -0,0 +1,869 @@
1
+ import { initContract } from '@ts-rest/core';
2
+ import { z } from 'zod';
3
+ import { CuidSchema, JsonApiCollectionResponseSchema, JsonApiErrorResponseSchema, JsonApiResponseSchema, } from '../schemas/common';
4
+ import { BaseFiltersSchema, CreateEquipmentRequestSchema, CreateLaborResourceRequestSchema, CreateMaterialRequestSchema, CreateResourceAllocationRequestSchema, CreateResourceAssignmentRequestSchema, EquipmentFiltersSchema, EquipmentResourceSchema, LaborResourceFiltersSchema, LaborResourceResourceSchema, MaterialFiltersSchema, MaterialResourceSchema, MaterialStockAdjustmentSchema, ResourceAllocationSchema, ResourceAssignmentResourceSchema, ResourceAvailabilityRequestSchema, ResourceAvailabilityResponseSchema, ResourceInsightsQuerySchema, ResourceInsightsResponseSchema, ResourceOptimizationQuerySchema, ResourceOptimizationResponseSchema, ResourceSearchQuerySchema, ResourceSearchResourceSchema, ResourceStatusSchema, ResourceUtilizationQuerySchema, UpdateEquipmentRequestSchema, UpdateLaborResourceRequestSchema, UpdateMaterialRequestSchema, UpdateResourceAllocationRequestSchema, } from '../schemas/resources';
5
+ const c = initContract();
6
+ // Enhanced cursor pagination schema for production use
7
+ const CursorPaginationQuerySchema = z.object({
8
+ cursor: z.string().optional(),
9
+ limit: z.coerce.number().min(1).max(100).default(20),
10
+ direction: z.enum(['forward', 'backward']).default('forward'),
11
+ includeTotal: z.coerce.boolean().default(false),
12
+ });
13
+ // Standard query parameters for filtering
14
+ const StandardQuerySchema = z.object({
15
+ search: z.string().optional(),
16
+ status: ResourceStatusSchema.optional(),
17
+ location: z.string().optional(),
18
+ category: z.string().optional(),
19
+ sortBy: z.enum(['name', 'createdAt', 'updatedAt', 'status']).default('updatedAt'),
20
+ sortOrder: z.enum(['asc', 'desc']).default('desc'),
21
+ });
22
+ export const resourcesContract = c.router({
23
+ // ===== EQUIPMENT MANAGEMENT =====
24
+ getEquipmentList: {
25
+ method: 'GET',
26
+ path: '/resources/equipment',
27
+ query: EquipmentFiltersSchema.merge(CursorPaginationQuerySchema).merge(StandardQuerySchema),
28
+ responses: {
29
+ 200: JsonApiCollectionResponseSchema(EquipmentResourceSchema).extend({
30
+ meta: z.object({
31
+ pagination: z.object({
32
+ hasNextPage: z.boolean(),
33
+ hasPreviousPage: z.boolean(),
34
+ nextCursor: z.string().optional(),
35
+ previousCursor: z.string().optional(),
36
+ totalCount: z.number().optional(),
37
+ }),
38
+ filters: z.record(z.unknown()).optional(),
39
+ }),
40
+ included: z
41
+ .array(z.object({
42
+ type: z.string(),
43
+ id: z.string(),
44
+ attributes: z.record(z.unknown()),
45
+ }))
46
+ .optional(),
47
+ }),
48
+ 400: JsonApiErrorResponseSchema,
49
+ 401: JsonApiErrorResponseSchema,
50
+ 403: JsonApiErrorResponseSchema,
51
+ 500: JsonApiErrorResponseSchema,
52
+ },
53
+ summary: 'Get all equipment',
54
+ description: 'Retrieve all equipment with advanced filtering, sorting, and cursor-based pagination',
55
+ },
56
+ getEquipment: {
57
+ method: 'GET',
58
+ path: '/resources/equipment/:id',
59
+ pathParams: z.object({ id: CuidSchema }),
60
+ query: z.object({
61
+ include: z.array(z.enum(['allocations', 'maintenance', 'projects'])).optional(),
62
+ }),
63
+ responses: {
64
+ 200: JsonApiResponseSchema(EquipmentResourceSchema).extend({
65
+ included: z
66
+ .array(z.object({
67
+ type: z.string(),
68
+ id: z.string(),
69
+ attributes: z.record(z.unknown()),
70
+ }))
71
+ .optional(),
72
+ }),
73
+ 400: JsonApiErrorResponseSchema,
74
+ 401: JsonApiErrorResponseSchema,
75
+ 403: JsonApiErrorResponseSchema,
76
+ 404: JsonApiErrorResponseSchema,
77
+ 500: JsonApiErrorResponseSchema,
78
+ },
79
+ summary: 'Get equipment by ID',
80
+ description: 'Retrieve detailed information about a specific equipment item',
81
+ },
82
+ createEquipment: {
83
+ method: 'POST',
84
+ path: '/resources/equipment',
85
+ body: z.object({
86
+ data: z.object({
87
+ type: z.literal('equipment'),
88
+ attributes: CreateEquipmentRequestSchema,
89
+ }),
90
+ }),
91
+ responses: {
92
+ 201: JsonApiResponseSchema(EquipmentResourceSchema).extend({
93
+ included: z
94
+ .array(z.object({
95
+ type: z.string(),
96
+ id: z.string(),
97
+ attributes: z.record(z.unknown()),
98
+ }))
99
+ .optional(),
100
+ }),
101
+ 400: JsonApiErrorResponseSchema,
102
+ 401: JsonApiErrorResponseSchema,
103
+ 403: JsonApiErrorResponseSchema,
104
+ 422: JsonApiErrorResponseSchema,
105
+ 500: JsonApiErrorResponseSchema,
106
+ },
107
+ summary: 'Create equipment',
108
+ description: 'Add new equipment to the system with full validation',
109
+ },
110
+ updateEquipment: {
111
+ method: 'PATCH',
112
+ path: '/resources/equipment/:id',
113
+ pathParams: z.object({ id: CuidSchema }),
114
+ body: z.object({
115
+ data: z.object({
116
+ type: z.literal('equipment'),
117
+ id: CuidSchema,
118
+ attributes: UpdateEquipmentRequestSchema,
119
+ }),
120
+ }),
121
+ responses: {
122
+ 200: JsonApiResponseSchema(EquipmentResourceSchema),
123
+ 400: JsonApiErrorResponseSchema,
124
+ 401: JsonApiErrorResponseSchema,
125
+ 403: JsonApiErrorResponseSchema,
126
+ 404: JsonApiErrorResponseSchema,
127
+ 422: JsonApiErrorResponseSchema,
128
+ 500: JsonApiErrorResponseSchema,
129
+ },
130
+ summary: 'Update equipment',
131
+ description: 'Update existing equipment with validation and audit logging',
132
+ },
133
+ deleteEquipment: {
134
+ method: 'DELETE',
135
+ path: '/resources/equipment/:id',
136
+ pathParams: z.object({ id: CuidSchema }),
137
+ body: null,
138
+ responses: {
139
+ 204: z.null(),
140
+ 400: JsonApiErrorResponseSchema,
141
+ 401: JsonApiErrorResponseSchema,
142
+ 403: JsonApiErrorResponseSchema,
143
+ 404: JsonApiErrorResponseSchema,
144
+ 409: JsonApiErrorResponseSchema,
145
+ 500: JsonApiErrorResponseSchema,
146
+ },
147
+ summary: 'Delete equipment',
148
+ description: 'Safely remove equipment from the system with dependency checking',
149
+ },
150
+ // ===== MATERIAL MANAGEMENT =====
151
+ getMaterialsList: {
152
+ method: 'GET',
153
+ path: '/resources/materials',
154
+ query: MaterialFiltersSchema.merge(CursorPaginationQuerySchema)
155
+ .merge(StandardQuerySchema)
156
+ .extend({
157
+ lowStock: z.coerce.boolean().optional(),
158
+ expiringSoon: z.coerce.boolean().optional(),
159
+ }),
160
+ responses: {
161
+ 200: JsonApiCollectionResponseSchema(MaterialResourceSchema).extend({
162
+ meta: z.object({
163
+ pagination: z.object({
164
+ hasNextPage: z.boolean(),
165
+ hasPreviousPage: z.boolean(),
166
+ nextCursor: z.string().optional(),
167
+ previousCursor: z.string().optional(),
168
+ totalCount: z.number().optional(),
169
+ }),
170
+ summary: z
171
+ .object({
172
+ totalValue: z.number(),
173
+ lowStockItems: z.number(),
174
+ expiringSoonItems: z.number(),
175
+ })
176
+ .optional(),
177
+ }),
178
+ }),
179
+ 400: JsonApiErrorResponseSchema,
180
+ 401: JsonApiErrorResponseSchema,
181
+ 403: JsonApiErrorResponseSchema,
182
+ 500: JsonApiErrorResponseSchema,
183
+ },
184
+ summary: 'Get all materials',
185
+ description: 'Retrieve materials inventory with stock level monitoring',
186
+ },
187
+ getMaterial: {
188
+ method: 'GET',
189
+ path: '/resources/materials/:id',
190
+ pathParams: z.object({ id: CuidSchema }),
191
+ query: z.object({
192
+ include: z.array(z.enum(['stockHistory', 'allocations', 'suppliers'])).optional(),
193
+ }),
194
+ responses: {
195
+ 200: JsonApiResponseSchema(MaterialResourceSchema).extend({
196
+ included: z
197
+ .array(z.object({
198
+ type: z.string(),
199
+ id: z.string(),
200
+ attributes: z.record(z.unknown()),
201
+ }))
202
+ .optional(),
203
+ }),
204
+ 400: JsonApiErrorResponseSchema,
205
+ 401: JsonApiErrorResponseSchema,
206
+ 403: JsonApiErrorResponseSchema,
207
+ 404: JsonApiErrorResponseSchema,
208
+ 500: JsonApiErrorResponseSchema,
209
+ },
210
+ summary: 'Get material by ID',
211
+ description: 'Retrieve detailed material information including stock history',
212
+ },
213
+ createMaterial: {
214
+ method: 'POST',
215
+ path: '/resources/materials',
216
+ body: z.object({
217
+ data: z.object({
218
+ type: z.literal('materials'),
219
+ attributes: CreateMaterialRequestSchema,
220
+ }),
221
+ }),
222
+ responses: {
223
+ 201: JsonApiResponseSchema(MaterialResourceSchema),
224
+ 400: JsonApiErrorResponseSchema,
225
+ 401: JsonApiErrorResponseSchema,
226
+ 403: JsonApiErrorResponseSchema,
227
+ 422: JsonApiErrorResponseSchema,
228
+ 500: JsonApiErrorResponseSchema,
229
+ },
230
+ summary: 'Create material',
231
+ description: 'Add new material to inventory with automatic reorder point setup',
232
+ },
233
+ updateMaterial: {
234
+ method: 'PATCH',
235
+ path: '/resources/materials/:id',
236
+ pathParams: z.object({ id: CuidSchema }),
237
+ body: z.object({
238
+ data: z.object({
239
+ type: z.literal('materials'),
240
+ id: CuidSchema,
241
+ attributes: UpdateMaterialRequestSchema,
242
+ }),
243
+ }),
244
+ responses: {
245
+ 200: JsonApiResponseSchema(MaterialResourceSchema),
246
+ 400: JsonApiErrorResponseSchema,
247
+ 401: JsonApiErrorResponseSchema,
248
+ 403: JsonApiErrorResponseSchema,
249
+ 404: JsonApiErrorResponseSchema,
250
+ 422: JsonApiErrorResponseSchema,
251
+ 500: JsonApiErrorResponseSchema,
252
+ },
253
+ summary: 'Update material',
254
+ description: 'Update material information with validation',
255
+ },
256
+ deleteMaterial: {
257
+ method: 'DELETE',
258
+ path: '/resources/materials/:id',
259
+ pathParams: z.object({ id: CuidSchema }),
260
+ body: null,
261
+ responses: {
262
+ 204: z.null(),
263
+ 400: JsonApiErrorResponseSchema,
264
+ 401: JsonApiErrorResponseSchema,
265
+ 403: JsonApiErrorResponseSchema,
266
+ 404: JsonApiErrorResponseSchema,
267
+ 409: JsonApiErrorResponseSchema,
268
+ 500: JsonApiErrorResponseSchema,
269
+ },
270
+ summary: 'Delete material',
271
+ description: 'Remove material from inventory with safety checks',
272
+ },
273
+ adjustMaterialStock: {
274
+ method: 'POST',
275
+ path: '/resources/materials/:id/stock-adjustment',
276
+ pathParams: z.object({ id: CuidSchema }),
277
+ body: z.object({
278
+ data: z.object({
279
+ type: z.literal('material-stock-adjustments'),
280
+ attributes: MaterialStockAdjustmentSchema,
281
+ }),
282
+ }),
283
+ responses: {
284
+ 200: JsonApiResponseSchema(MaterialResourceSchema).extend({
285
+ meta: z.object({
286
+ adjustment: z.object({
287
+ previousQuantity: z.number(),
288
+ newQuantity: z.number(),
289
+ adjustmentAmount: z.number(),
290
+ reason: z.string(),
291
+ }),
292
+ }),
293
+ }),
294
+ 400: JsonApiErrorResponseSchema,
295
+ 401: JsonApiErrorResponseSchema,
296
+ 403: JsonApiErrorResponseSchema,
297
+ 404: JsonApiErrorResponseSchema,
298
+ 422: JsonApiErrorResponseSchema,
299
+ 500: JsonApiErrorResponseSchema,
300
+ },
301
+ summary: 'Adjust material stock',
302
+ description: 'Adjust material stock levels with audit trail',
303
+ },
304
+ // ===== LABOR RESOURCE MANAGEMENT =====
305
+ getLaborResourcesList: {
306
+ method: 'GET',
307
+ path: '/resources/labor',
308
+ query: LaborResourceFiltersSchema.merge(CursorPaginationQuerySchema)
309
+ .merge(StandardQuerySchema)
310
+ .extend({
311
+ skillLevel: z.enum(['JUNIOR', 'INTERMEDIATE', 'SENIOR', 'EXPERT']).optional(),
312
+ availability: z.enum(['FULL_TIME', 'PART_TIME', 'CONTRACT', 'ON_CALL']).optional(),
313
+ available: z.coerce.boolean().optional(),
314
+ }),
315
+ responses: {
316
+ 200: JsonApiCollectionResponseSchema(LaborResourceResourceSchema).extend({
317
+ meta: z.object({
318
+ pagination: z.object({
319
+ hasNextPage: z.boolean(),
320
+ hasPreviousPage: z.boolean(),
321
+ nextCursor: z.string().optional(),
322
+ previousCursor: z.string().optional(),
323
+ totalCount: z.number().optional(),
324
+ }),
325
+ summary: z
326
+ .object({
327
+ totalResources: z.number(),
328
+ availableResources: z.number(),
329
+ averageHourlyRate: z.number(),
330
+ })
331
+ .optional(),
332
+ }),
333
+ }),
334
+ 400: JsonApiErrorResponseSchema,
335
+ 401: JsonApiErrorResponseSchema,
336
+ 403: JsonApiErrorResponseSchema,
337
+ 500: JsonApiErrorResponseSchema,
338
+ },
339
+ summary: 'Get all labor resources',
340
+ description: 'Retrieve labor resources with availability and skill filtering',
341
+ },
342
+ getLaborResource: {
343
+ method: 'GET',
344
+ path: '/resources/labor/:id',
345
+ pathParams: z.object({ id: CuidSchema }),
346
+ query: z.object({
347
+ include: z.array(z.enum(['assignments', 'skills', 'performance'])).optional(),
348
+ }),
349
+ responses: {
350
+ 200: JsonApiResponseSchema(LaborResourceResourceSchema).extend({
351
+ included: z
352
+ .array(z.object({
353
+ type: z.string(),
354
+ id: z.string(),
355
+ attributes: z.record(z.unknown()),
356
+ }))
357
+ .optional(),
358
+ }),
359
+ 400: JsonApiErrorResponseSchema,
360
+ 401: JsonApiErrorResponseSchema,
361
+ 403: JsonApiErrorResponseSchema,
362
+ 404: JsonApiErrorResponseSchema,
363
+ 500: JsonApiErrorResponseSchema,
364
+ },
365
+ summary: 'Get labor resource by ID',
366
+ description: 'Retrieve detailed labor resource information',
367
+ },
368
+ createLaborResource: {
369
+ method: 'POST',
370
+ path: '/resources/labor',
371
+ body: z.object({
372
+ data: z.object({
373
+ type: z.literal('labor-resources'),
374
+ attributes: CreateLaborResourceRequestSchema,
375
+ }),
376
+ }),
377
+ responses: {
378
+ 201: JsonApiResponseSchema(LaborResourceResourceSchema),
379
+ 400: JsonApiErrorResponseSchema,
380
+ 401: JsonApiErrorResponseSchema,
381
+ 403: JsonApiErrorResponseSchema,
382
+ 422: JsonApiErrorResponseSchema,
383
+ 500: JsonApiErrorResponseSchema,
384
+ },
385
+ summary: 'Create labor resource',
386
+ description: 'Add new labor resource with skill and availability setup',
387
+ },
388
+ updateLaborResource: {
389
+ method: 'PATCH',
390
+ path: '/resources/labor/:id',
391
+ pathParams: z.object({ id: CuidSchema }),
392
+ body: z.object({
393
+ data: z.object({
394
+ type: z.literal('labor-resources'),
395
+ id: CuidSchema,
396
+ attributes: UpdateLaborResourceRequestSchema,
397
+ }),
398
+ }),
399
+ responses: {
400
+ 200: JsonApiResponseSchema(LaborResourceResourceSchema),
401
+ 400: JsonApiErrorResponseSchema,
402
+ 401: JsonApiErrorResponseSchema,
403
+ 403: JsonApiErrorResponseSchema,
404
+ 404: JsonApiErrorResponseSchema,
405
+ 422: JsonApiErrorResponseSchema,
406
+ 500: JsonApiErrorResponseSchema,
407
+ },
408
+ summary: 'Update labor resource',
409
+ description: 'Update labor resource information and availability',
410
+ },
411
+ deleteLaborResource: {
412
+ method: 'DELETE',
413
+ path: '/resources/labor/:id',
414
+ pathParams: z.object({ id: CuidSchema }),
415
+ body: null,
416
+ responses: {
417
+ 204: z.null(),
418
+ 400: JsonApiErrorResponseSchema,
419
+ 401: JsonApiErrorResponseSchema,
420
+ 403: JsonApiErrorResponseSchema,
421
+ 404: JsonApiErrorResponseSchema,
422
+ 409: JsonApiErrorResponseSchema,
423
+ 500: JsonApiErrorResponseSchema,
424
+ },
425
+ summary: 'Delete labor resource',
426
+ description: 'Remove labor resource with assignment safety checks',
427
+ },
428
+ // ===== RESOURCE ASSIGNMENTS =====
429
+ getResourceAssignments: {
430
+ method: 'GET',
431
+ path: '/projects/:projectId/resource-assignments',
432
+ pathParams: z.object({ projectId: CuidSchema }),
433
+ query: CursorPaginationQuerySchema.extend({
434
+ resourceType: z.enum(['EQUIPMENT', 'MATERIAL', 'LABOR']).optional(),
435
+ status: z.enum(['ACTIVE', 'COMPLETED', 'CANCELLED']).optional(),
436
+ startDate: z.string().date().optional(),
437
+ endDate: z.string().date().optional(),
438
+ }),
439
+ responses: {
440
+ 200: JsonApiCollectionResponseSchema(ResourceAssignmentResourceSchema).extend({
441
+ meta: z.object({
442
+ pagination: z.object({
443
+ hasNextPage: z.boolean(),
444
+ hasPreviousPage: z.boolean(),
445
+ nextCursor: z.string().optional(),
446
+ previousCursor: z.string().optional(),
447
+ totalCount: z.number().optional(),
448
+ }),
449
+ summary: z
450
+ .object({
451
+ totalAssignments: z.number(),
452
+ activeAssignments: z.number(),
453
+ totalCost: z.number(),
454
+ })
455
+ .optional(),
456
+ }),
457
+ included: z
458
+ .array(z.object({
459
+ type: z.string(),
460
+ id: z.string(),
461
+ attributes: z.record(z.unknown()),
462
+ }))
463
+ .optional(),
464
+ }),
465
+ 400: JsonApiErrorResponseSchema,
466
+ 401: JsonApiErrorResponseSchema,
467
+ 403: JsonApiErrorResponseSchema,
468
+ 404: JsonApiErrorResponseSchema,
469
+ 500: JsonApiErrorResponseSchema,
470
+ },
471
+ summary: 'Get project resource assignments',
472
+ description: 'Retrieve all resource assignments for a specific project',
473
+ },
474
+ createResourceAssignment: {
475
+ method: 'POST',
476
+ path: '/projects/:projectId/resource-assignments',
477
+ pathParams: z.object({ projectId: CuidSchema }),
478
+ body: z.object({
479
+ data: z.object({
480
+ type: z.literal('resource-assignments'),
481
+ attributes: CreateResourceAssignmentRequestSchema,
482
+ }),
483
+ }),
484
+ responses: {
485
+ 201: JsonApiResponseSchema(ResourceAssignmentResourceSchema).extend({
486
+ included: z
487
+ .array(z.object({
488
+ type: z.string(),
489
+ id: z.string(),
490
+ attributes: z.record(z.unknown()),
491
+ }))
492
+ .optional(),
493
+ }),
494
+ 400: JsonApiErrorResponseSchema,
495
+ 401: JsonApiErrorResponseSchema,
496
+ 403: JsonApiErrorResponseSchema,
497
+ 404: JsonApiErrorResponseSchema,
498
+ 409: JsonApiErrorResponseSchema,
499
+ 422: JsonApiErrorResponseSchema,
500
+ 500: JsonApiErrorResponseSchema,
501
+ },
502
+ summary: 'Create resource assignment',
503
+ description: 'Assign a resource to a project with availability validation',
504
+ },
505
+ updateResourceAssignment: {
506
+ method: 'PATCH',
507
+ path: '/projects/:projectId/resource-assignments/:assignmentId',
508
+ pathParams: z.object({
509
+ projectId: CuidSchema,
510
+ assignmentId: CuidSchema,
511
+ }),
512
+ body: z.object({
513
+ data: z.object({
514
+ type: z.literal('resource-assignments'),
515
+ id: CuidSchema,
516
+ attributes: z.object({
517
+ quantity: z.number().positive().optional(),
518
+ notes: z.string().optional(),
519
+ returnedAt: z.string().datetime().optional(),
520
+ }),
521
+ }),
522
+ }),
523
+ responses: {
524
+ 200: JsonApiResponseSchema(ResourceAssignmentResourceSchema),
525
+ 400: JsonApiErrorResponseSchema,
526
+ 401: JsonApiErrorResponseSchema,
527
+ 403: JsonApiErrorResponseSchema,
528
+ 404: JsonApiErrorResponseSchema,
529
+ 422: JsonApiErrorResponseSchema,
530
+ 500: JsonApiErrorResponseSchema,
531
+ },
532
+ summary: 'Update resource assignment',
533
+ description: 'Update resource assignment details or mark as returned',
534
+ },
535
+ deleteResourceAssignment: {
536
+ method: 'DELETE',
537
+ path: '/projects/:projectId/resource-assignments/:assignmentId',
538
+ pathParams: z.object({
539
+ projectId: CuidSchema,
540
+ assignmentId: CuidSchema,
541
+ }),
542
+ body: null,
543
+ responses: {
544
+ 204: z.null(),
545
+ 400: JsonApiErrorResponseSchema,
546
+ 401: JsonApiErrorResponseSchema,
547
+ 403: JsonApiErrorResponseSchema,
548
+ 404: JsonApiErrorResponseSchema,
549
+ 500: JsonApiErrorResponseSchema,
550
+ },
551
+ summary: 'Delete resource assignment',
552
+ description: 'Remove resource assignment and free up the resource',
553
+ },
554
+ // ===== ADVANCED RESOURCE OPERATIONS =====
555
+ searchResources: {
556
+ method: 'GET',
557
+ path: '/resources/search',
558
+ query: ResourceSearchQuerySchema,
559
+ responses: {
560
+ 200: JsonApiCollectionResponseSchema(ResourceSearchResourceSchema).extend({
561
+ meta: z.object({
562
+ searchQuery: z.string(),
563
+ totalResults: z.number(),
564
+ searchTime: z.number(),
565
+ filters: z.record(z.unknown()).optional(),
566
+ }),
567
+ }),
568
+ 400: JsonApiErrorResponseSchema,
569
+ 401: JsonApiErrorResponseSchema,
570
+ 403: JsonApiErrorResponseSchema,
571
+ 500: JsonApiErrorResponseSchema,
572
+ },
573
+ summary: 'Search resources',
574
+ description: 'Advanced search across all resource types with relevance scoring',
575
+ },
576
+ checkResourceAvailability: {
577
+ method: 'POST',
578
+ path: '/resources/availability-check',
579
+ body: ResourceAvailabilityRequestSchema,
580
+ responses: {
581
+ 200: ResourceAvailabilityResponseSchema,
582
+ 400: JsonApiErrorResponseSchema,
583
+ 401: JsonApiErrorResponseSchema,
584
+ 403: JsonApiErrorResponseSchema,
585
+ 422: JsonApiErrorResponseSchema,
586
+ 500: JsonApiErrorResponseSchema,
587
+ },
588
+ summary: 'Check resource availability',
589
+ description: 'Check resource availability with conflict detection and alternatives',
590
+ },
591
+ getResourceUtilization: {
592
+ method: 'GET',
593
+ path: '/resources/utilization',
594
+ query: ResourceUtilizationQuerySchema,
595
+ responses: {
596
+ 200: z.object({
597
+ data: z.object({
598
+ type: z.literal('resource-utilization'),
599
+ id: z.string(),
600
+ attributes: z.object({
601
+ period: z.object({
602
+ startDate: z.string().date(),
603
+ endDate: z.string().date(),
604
+ }),
605
+ summary: z.object({
606
+ totalResources: z.number(),
607
+ averageUtilization: z.number().min(0).max(1),
608
+ totalCost: z.number(),
609
+ efficiency: z.number().min(0).max(1),
610
+ }),
611
+ equipment: z.array(z.object({
612
+ id: CuidSchema,
613
+ name: z.string(),
614
+ utilizationRate: z.number().min(0).max(1),
615
+ totalHours: z.number().min(0),
616
+ downtime: z.number().min(0),
617
+ costEfficiency: z.number().min(0).max(1),
618
+ })),
619
+ materials: z.array(z.object({
620
+ id: CuidSchema,
621
+ name: z.string(),
622
+ consumptionRate: z.number().min(0),
623
+ wastePercentage: z.number().min(0).max(1),
624
+ totalUsed: z.number().min(0),
625
+ costPerUnit: z.number(),
626
+ })),
627
+ labor: z.array(z.object({
628
+ id: CuidSchema,
629
+ name: z.string(),
630
+ efficiencyScore: z.number().min(0).max(1),
631
+ hoursWorked: z.number().min(0),
632
+ overtimeHours: z.number().min(0),
633
+ productivityRate: z.number().min(0),
634
+ })),
635
+ }),
636
+ }),
637
+ meta: z.object({
638
+ generatedAt: z.string().datetime(),
639
+ reportPeriod: z.string(),
640
+ includeDowntime: z.boolean(),
641
+ }),
642
+ }),
643
+ 400: JsonApiErrorResponseSchema,
644
+ 401: JsonApiErrorResponseSchema,
645
+ 403: JsonApiErrorResponseSchema,
646
+ 500: JsonApiErrorResponseSchema,
647
+ },
648
+ summary: 'Get resource utilization report',
649
+ description: 'Comprehensive utilization analytics with performance metrics',
650
+ },
651
+ getResourceInsights: {
652
+ method: 'GET',
653
+ path: '/resources/insights',
654
+ query: ResourceInsightsQuerySchema,
655
+ responses: {
656
+ 200: ResourceInsightsResponseSchema,
657
+ 400: JsonApiErrorResponseSchema,
658
+ 401: JsonApiErrorResponseSchema,
659
+ 403: JsonApiErrorResponseSchema,
660
+ 500: JsonApiErrorResponseSchema,
661
+ },
662
+ summary: 'Get resource insights',
663
+ description: 'AI-powered insights and recommendations for resource optimization',
664
+ },
665
+ optimizeResourceAllocation: {
666
+ method: 'POST',
667
+ path: '/resources/optimization',
668
+ body: z.object({
669
+ data: z.object({
670
+ type: z.literal('resource-optimization-request'),
671
+ attributes: ResourceOptimizationQuerySchema,
672
+ }),
673
+ }),
674
+ responses: {
675
+ 200: ResourceOptimizationResponseSchema,
676
+ 400: JsonApiErrorResponseSchema,
677
+ 401: JsonApiErrorResponseSchema,
678
+ 403: JsonApiErrorResponseSchema,
679
+ 422: JsonApiErrorResponseSchema,
680
+ 500: JsonApiErrorResponseSchema,
681
+ },
682
+ summary: 'Optimize resource allocation',
683
+ description: 'Generate AI-powered optimization recommendations for resource allocation',
684
+ },
685
+ // ===== RESOURCE ALLOCATIONS =====
686
+ getResourceAllocations: {
687
+ method: 'GET',
688
+ path: '/projects/:projectId/resource-allocations',
689
+ pathParams: z.object({ projectId: CuidSchema }),
690
+ query: CursorPaginationQuerySchema.merge(z.object({
691
+ resourceId: CuidSchema.optional(),
692
+ startDate: z.string().datetime().optional(),
693
+ endDate: z.string().datetime().optional(),
694
+ status: z.enum(['IN_USE', 'COMPLETED']).optional(),
695
+ })),
696
+ responses: {
697
+ 200: JsonApiCollectionResponseSchema(z.object({
698
+ type: z.literal('resource-allocations'),
699
+ id: CuidSchema,
700
+ attributes: ResourceAllocationSchema,
701
+ })),
702
+ 400: JsonApiErrorResponseSchema,
703
+ 401: JsonApiErrorResponseSchema,
704
+ 403: JsonApiErrorResponseSchema,
705
+ 500: JsonApiErrorResponseSchema,
706
+ },
707
+ summary: 'Get project resource allocations',
708
+ description: 'Retrieve allocations for a single project',
709
+ },
710
+ getResourceAllocation: {
711
+ method: 'GET',
712
+ path: '/projects/:projectId/resource-allocations/:allocationId',
713
+ pathParams: z.object({ projectId: CuidSchema, allocationId: CuidSchema }),
714
+ responses: {
715
+ 200: JsonApiResponseSchema(z.object({
716
+ type: z.literal('resource-allocations'),
717
+ id: CuidSchema,
718
+ attributes: ResourceAllocationSchema,
719
+ })),
720
+ 400: JsonApiErrorResponseSchema,
721
+ 401: JsonApiErrorResponseSchema,
722
+ 403: JsonApiErrorResponseSchema,
723
+ 404: JsonApiErrorResponseSchema,
724
+ 500: JsonApiErrorResponseSchema,
725
+ },
726
+ summary: 'Get allocation by ID',
727
+ description: 'Retrieve a single resource allocation record',
728
+ },
729
+ createResourceAllocation: {
730
+ method: 'POST',
731
+ path: '/projects/:projectId/resource-allocations',
732
+ pathParams: z.object({ projectId: CuidSchema }),
733
+ body: z.object({
734
+ data: z.object({
735
+ type: z.literal('resource-allocations'),
736
+ attributes: CreateResourceAllocationRequestSchema,
737
+ }),
738
+ }),
739
+ responses: {
740
+ 201: JsonApiResponseSchema(z.object({
741
+ type: z.literal('resource-allocations'),
742
+ id: CuidSchema,
743
+ attributes: ResourceAllocationSchema,
744
+ })),
745
+ 400: JsonApiErrorResponseSchema,
746
+ 401: JsonApiErrorResponseSchema,
747
+ 403: JsonApiErrorResponseSchema,
748
+ 422: JsonApiErrorResponseSchema,
749
+ 500: JsonApiErrorResponseSchema,
750
+ },
751
+ summary: 'Create allocation',
752
+ description: 'Allocate a resource to a project',
753
+ },
754
+ updateResourceAllocation: {
755
+ method: 'PATCH',
756
+ path: '/projects/:projectId/resource-allocations/:allocationId',
757
+ pathParams: z.object({ projectId: CuidSchema, allocationId: CuidSchema }),
758
+ body: z.object({
759
+ data: z.object({
760
+ type: z.literal('resource-allocations'),
761
+ id: CuidSchema,
762
+ attributes: UpdateResourceAllocationRequestSchema,
763
+ }),
764
+ }),
765
+ responses: {
766
+ 200: JsonApiResponseSchema(z.object({
767
+ type: z.literal('resource-allocations'),
768
+ id: CuidSchema,
769
+ attributes: ResourceAllocationSchema,
770
+ })),
771
+ 400: JsonApiErrorResponseSchema,
772
+ 401: JsonApiErrorResponseSchema,
773
+ 403: JsonApiErrorResponseSchema,
774
+ 404: JsonApiErrorResponseSchema,
775
+ 422: JsonApiErrorResponseSchema,
776
+ 500: JsonApiErrorResponseSchema,
777
+ },
778
+ summary: 'Update allocation',
779
+ description: 'Patch an existing allocation',
780
+ },
781
+ deleteResourceAllocation: {
782
+ method: 'DELETE',
783
+ path: '/projects/:projectId/resource-allocations/:allocationId',
784
+ pathParams: z.object({ projectId: CuidSchema, allocationId: CuidSchema }),
785
+ body: null,
786
+ responses: {
787
+ 204: z.null(),
788
+ 400: JsonApiErrorResponseSchema,
789
+ 401: JsonApiErrorResponseSchema,
790
+ 403: JsonApiErrorResponseSchema,
791
+ 404: JsonApiErrorResponseSchema,
792
+ 500: JsonApiErrorResponseSchema,
793
+ },
794
+ summary: 'Delete allocation',
795
+ description: 'Remove allocation and restore resource availability',
796
+ },
797
+ // ===== BULK OPERATIONS =====
798
+ bulkUpdateResources: {
799
+ method: 'PATCH',
800
+ path: '/resources/bulk-update',
801
+ body: z.object({
802
+ data: z.array(z.object({
803
+ type: z.enum(['equipment', 'materials', 'labor-resources']),
804
+ id: CuidSchema,
805
+ attributes: z.record(z.unknown()),
806
+ })),
807
+ }),
808
+ responses: {
809
+ 200: z.object({
810
+ data: z.array(z.object({
811
+ type: z.string(),
812
+ id: CuidSchema,
813
+ attributes: z.object({
814
+ success: z.boolean(),
815
+ message: z.string().optional(),
816
+ }),
817
+ })),
818
+ meta: z.object({
819
+ totalProcessed: z.number(),
820
+ successful: z.number(),
821
+ failed: z.number(),
822
+ }),
823
+ }),
824
+ 400: JsonApiErrorResponseSchema,
825
+ 401: JsonApiErrorResponseSchema,
826
+ 403: JsonApiErrorResponseSchema,
827
+ 422: JsonApiErrorResponseSchema,
828
+ 500: JsonApiErrorResponseSchema,
829
+ },
830
+ summary: 'Bulk update resources',
831
+ description: 'Update multiple resources in a single operation with transaction safety',
832
+ },
833
+ exportResources: {
834
+ method: 'POST',
835
+ path: '/resources/export',
836
+ body: z.object({
837
+ data: z.object({
838
+ type: z.literal('resource-export-request'),
839
+ attributes: z.object({
840
+ resourceTypes: z.array(z.enum(['EQUIPMENT', 'MATERIAL', 'LABOR'])).optional(),
841
+ format: z.enum(['csv', 'xlsx', 'json']).default('csv'),
842
+ filters: BaseFiltersSchema.optional(),
843
+ includeRelations: z.boolean().default(false),
844
+ }),
845
+ }),
846
+ }),
847
+ responses: {
848
+ 202: z.object({
849
+ data: z.object({
850
+ type: z.literal('export-job'),
851
+ id: CuidSchema,
852
+ attributes: z.object({
853
+ status: z.literal('processing'),
854
+ downloadUrl: z.string().optional(),
855
+ expiresAt: z.string().datetime(),
856
+ }),
857
+ }),
858
+ }),
859
+ 400: JsonApiErrorResponseSchema,
860
+ 401: JsonApiErrorResponseSchema,
861
+ 403: JsonApiErrorResponseSchema,
862
+ 422: JsonApiErrorResponseSchema,
863
+ 500: JsonApiErrorResponseSchema,
864
+ },
865
+ summary: 'Export resources data',
866
+ description: 'Export resource data in various formats with async processing',
867
+ },
868
+ });
869
+ //# sourceMappingURL=resources.js.map