@venulog/phasing-engine-schemas 0.7.6-alpha.0 → 0.8.0-alpha.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/dist/camera.d.ts +219 -0
- package/dist/camera.js +227 -0
- package/dist/enums/accessEventType.d.ts +8 -0
- package/dist/enums/accessEventType.js +17 -0
- package/dist/enums/cameraTrigger.d.ts +7 -0
- package/dist/enums/cameraTrigger.js +15 -0
- package/dist/enums/index.d.ts +5 -0
- package/dist/enums/index.js +5 -0
- package/dist/enums/positionSource.d.ts +7 -0
- package/dist/enums/positionSource.js +15 -0
- package/dist/enums/simulationMode.d.ts +11 -0
- package/dist/enums/simulationMode.js +20 -0
- package/dist/enums/vehicleState.d.ts +13 -0
- package/dist/enums/vehicleState.js +37 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +12 -0
- package/dist/parkingArea.d.ts +31 -17
- package/dist/parkingArea.js +76 -26
- package/dist/parkingAreaAccess.d.ts +400 -0
- package/dist/parkingAreaAccess.js +466 -0
- package/dist/parkingAreaLayer.d.ts +354 -0
- package/dist/parkingAreaLayer.js +385 -0
- package/dist/parkingBooking.d.ts +148 -299
- package/dist/parkingBooking.js +83 -225
- package/dist/simulation.d.ts +171 -0
- package/dist/simulation.js +231 -0
- package/dist/vehiclePosition.d.ts +216 -0
- package/dist/vehiclePosition.js +237 -0
- package/package.json +21 -1
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
// packages/phasing-schemas/src/parkingAreaAccess.ts
|
|
2
|
+
import { z } from './zod.js';
|
|
3
|
+
import { createSuccessResponseSchema, createMessageDataResponseSchema } from './common.js';
|
|
4
|
+
// ------------------------------
|
|
5
|
+
// Access Point Geometry Schemas
|
|
6
|
+
// ------------------------------
|
|
7
|
+
/**
|
|
8
|
+
* A point in 2D space using percentage-based coordinates (0-100)
|
|
9
|
+
* relative to the site plan image dimensions
|
|
10
|
+
*/
|
|
11
|
+
export const accessPointSchema = z
|
|
12
|
+
.object({
|
|
13
|
+
x: z.number().min(0).max(100).openapi({
|
|
14
|
+
description: 'X coordinate as percentage of image width (0-100)',
|
|
15
|
+
example: 25.5
|
|
16
|
+
}),
|
|
17
|
+
y: z.number().min(0).max(100).openapi({
|
|
18
|
+
description: 'Y coordinate as percentage of image height (0-100)',
|
|
19
|
+
example: 30.2
|
|
20
|
+
})
|
|
21
|
+
})
|
|
22
|
+
.openapi('AccessPoint');
|
|
23
|
+
/**
|
|
24
|
+
* GeoJSON LineString for access point geometry
|
|
25
|
+
*/
|
|
26
|
+
export const geoJsonLineStringSchema = z
|
|
27
|
+
.object({
|
|
28
|
+
type: z.literal('LineString').openapi({
|
|
29
|
+
description: 'GeoJSON geometry type',
|
|
30
|
+
example: 'LineString'
|
|
31
|
+
}),
|
|
32
|
+
coordinates: z
|
|
33
|
+
.array(z.tuple([z.number(), z.number()]))
|
|
34
|
+
.min(2)
|
|
35
|
+
.openapi({
|
|
36
|
+
description: 'GeoJSON LineString coordinates (array of [x, y] points)',
|
|
37
|
+
example: [
|
|
38
|
+
[25.5, 30.2],
|
|
39
|
+
[35.5, 30.2]
|
|
40
|
+
]
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
.openapi('GeoJsonLineString');
|
|
44
|
+
// ------------------------------
|
|
45
|
+
// Parking Area Access Schemas
|
|
46
|
+
// ------------------------------
|
|
47
|
+
/**
|
|
48
|
+
* Core parking area access item schema matching database structure
|
|
49
|
+
*/
|
|
50
|
+
export const parkingAreaAccessItemSchema = z
|
|
51
|
+
.object({
|
|
52
|
+
id: z.number().int().positive().openapi({
|
|
53
|
+
description: 'Access point ID',
|
|
54
|
+
example: 1
|
|
55
|
+
}),
|
|
56
|
+
event_id: z.number().int().positive().openapi({
|
|
57
|
+
description: 'Event ID this access point belongs to',
|
|
58
|
+
example: 1
|
|
59
|
+
}),
|
|
60
|
+
name: z.string().openapi({
|
|
61
|
+
description: 'Name of the access point',
|
|
62
|
+
example: 'Main Entrance'
|
|
63
|
+
}),
|
|
64
|
+
geometry: geoJsonLineStringSchema.nullable().openapi({
|
|
65
|
+
description: 'GeoJSON LineString geometry for the access point'
|
|
66
|
+
}),
|
|
67
|
+
width_meters: z.number().positive().nullable().openapi({
|
|
68
|
+
description: 'Width of the access point in meters',
|
|
69
|
+
example: 6.5
|
|
70
|
+
}),
|
|
71
|
+
height_meters: z.number().positive().nullable().openapi({
|
|
72
|
+
description: 'Height of the access point in meters (for gates/barriers)',
|
|
73
|
+
example: 4.2
|
|
74
|
+
}),
|
|
75
|
+
is_active: z.boolean().openapi({
|
|
76
|
+
description: 'Whether the access point is active',
|
|
77
|
+
example: true
|
|
78
|
+
}),
|
|
79
|
+
created_at: z.string().openapi({
|
|
80
|
+
description: 'Creation timestamp (ISO 8601)',
|
|
81
|
+
example: '2026-01-06T10:30:00Z'
|
|
82
|
+
}),
|
|
83
|
+
updated_at: z.string().openapi({
|
|
84
|
+
description: 'Last update timestamp (ISO 8601)',
|
|
85
|
+
example: '2026-01-06T10:30:00Z'
|
|
86
|
+
}),
|
|
87
|
+
created_by: z.string().uuid().nullable().openapi({
|
|
88
|
+
description: 'UUID of user who created this access point',
|
|
89
|
+
example: '550e8400-e29b-41d4-a716-446655440000'
|
|
90
|
+
}),
|
|
91
|
+
updated_by: z.string().uuid().nullable().openapi({
|
|
92
|
+
description: 'UUID of user who last updated this access point',
|
|
93
|
+
example: '550e8400-e29b-41d4-a716-446655440000'
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
.openapi('ParkingAreaAccessItem');
|
|
97
|
+
/**
|
|
98
|
+
* Access point with linked parking areas
|
|
99
|
+
*/
|
|
100
|
+
export const parkingAreaAccessWithLinksSchema = parkingAreaAccessItemSchema
|
|
101
|
+
.extend({
|
|
102
|
+
linked_parking_areas: z
|
|
103
|
+
.array(z.object({
|
|
104
|
+
parking_area_id: z.number().int().positive(),
|
|
105
|
+
parking_area_name: z.string().nullable()
|
|
106
|
+
}))
|
|
107
|
+
.openapi({
|
|
108
|
+
description: 'List of parking areas linked to this access point'
|
|
109
|
+
})
|
|
110
|
+
})
|
|
111
|
+
.openapi('ParkingAreaAccessWithLinks');
|
|
112
|
+
// ------------------------------
|
|
113
|
+
// Query Schemas
|
|
114
|
+
// ------------------------------
|
|
115
|
+
export const getAccessesByEventIdParamsSchema = z
|
|
116
|
+
.object({
|
|
117
|
+
eventId: z
|
|
118
|
+
.string()
|
|
119
|
+
.min(1)
|
|
120
|
+
.transform(val => parseInt(val, 10))
|
|
121
|
+
.refine(val => !isNaN(val) && val > 0, {
|
|
122
|
+
message: 'Event ID must be a positive number'
|
|
123
|
+
})
|
|
124
|
+
.openapi({
|
|
125
|
+
description: 'The ID of the event',
|
|
126
|
+
example: '1'
|
|
127
|
+
})
|
|
128
|
+
})
|
|
129
|
+
.openapi('GetAccessesByEventIdParams');
|
|
130
|
+
export const getAccessByIdParamsSchema = z
|
|
131
|
+
.object({
|
|
132
|
+
accessId: z
|
|
133
|
+
.string()
|
|
134
|
+
.min(1)
|
|
135
|
+
.transform(val => parseInt(val, 10))
|
|
136
|
+
.refine(val => !isNaN(val) && val > 0, {
|
|
137
|
+
message: 'Access point ID must be a positive number'
|
|
138
|
+
})
|
|
139
|
+
.openapi({
|
|
140
|
+
description: 'The ID of the access point',
|
|
141
|
+
example: '1'
|
|
142
|
+
})
|
|
143
|
+
})
|
|
144
|
+
.openapi('GetAccessByIdParams');
|
|
145
|
+
// ------------------------------
|
|
146
|
+
// Create Access Point Schemas
|
|
147
|
+
// ------------------------------
|
|
148
|
+
export const createAccessBodySchema = z
|
|
149
|
+
.object({
|
|
150
|
+
event_id: z.number().int().positive().openapi({
|
|
151
|
+
description: 'ID of the event',
|
|
152
|
+
example: 1
|
|
153
|
+
}),
|
|
154
|
+
name: z.string().min(1).max(255).openapi({
|
|
155
|
+
description: 'Name of the access point',
|
|
156
|
+
example: 'Main Entrance'
|
|
157
|
+
}),
|
|
158
|
+
geometry: geoJsonLineStringSchema.optional().openapi({
|
|
159
|
+
description: 'GeoJSON LineString geometry for the access point'
|
|
160
|
+
}),
|
|
161
|
+
width_meters: z.number().positive().optional().openapi({
|
|
162
|
+
description: 'Width of the access point in meters',
|
|
163
|
+
example: 6.5
|
|
164
|
+
}),
|
|
165
|
+
height_meters: z.number().positive().optional().openapi({
|
|
166
|
+
description: 'Height of the access point in meters',
|
|
167
|
+
example: 4.2
|
|
168
|
+
}),
|
|
169
|
+
linked_parking_area_ids: z
|
|
170
|
+
.array(z.number().int().positive())
|
|
171
|
+
.optional()
|
|
172
|
+
.openapi({
|
|
173
|
+
description: 'IDs of parking areas to link to this access point',
|
|
174
|
+
example: [1, 2, 3]
|
|
175
|
+
})
|
|
176
|
+
})
|
|
177
|
+
.openapi('CreateAccessBody');
|
|
178
|
+
export const createAccessDataSchema = z
|
|
179
|
+
.object({
|
|
180
|
+
access_id: z.number().openapi({
|
|
181
|
+
description: 'ID of the created access point',
|
|
182
|
+
example: 1
|
|
183
|
+
}),
|
|
184
|
+
event_id: z.number().openapi({
|
|
185
|
+
description: 'ID of the event',
|
|
186
|
+
example: 1
|
|
187
|
+
}),
|
|
188
|
+
name: z.string().openapi({
|
|
189
|
+
description: 'Name of the access point',
|
|
190
|
+
example: 'Main Entrance'
|
|
191
|
+
}),
|
|
192
|
+
geometry: geoJsonLineStringSchema.nullable().openapi({
|
|
193
|
+
description: 'GeoJSON LineString geometry'
|
|
194
|
+
}),
|
|
195
|
+
width_meters: z.number().nullable().openapi({
|
|
196
|
+
description: 'Width in meters',
|
|
197
|
+
example: 6.5
|
|
198
|
+
}),
|
|
199
|
+
height_meters: z.number().nullable().openapi({
|
|
200
|
+
description: 'Height in meters',
|
|
201
|
+
example: 4.2
|
|
202
|
+
}),
|
|
203
|
+
linked_parking_areas: z
|
|
204
|
+
.array(z.object({
|
|
205
|
+
parking_area_id: z.number(),
|
|
206
|
+
parking_area_name: z.string().nullable()
|
|
207
|
+
}))
|
|
208
|
+
.openapi({
|
|
209
|
+
description: 'Linked parking areas'
|
|
210
|
+
}),
|
|
211
|
+
is_active: z.boolean().openapi({
|
|
212
|
+
description: 'Whether the access point is active',
|
|
213
|
+
example: true
|
|
214
|
+
}),
|
|
215
|
+
created_at: z.string().openapi({
|
|
216
|
+
description: 'Timestamp when access point was created'
|
|
217
|
+
}),
|
|
218
|
+
created_by: z.string().nullable().openapi({
|
|
219
|
+
description: 'ID of the user who created the access point'
|
|
220
|
+
})
|
|
221
|
+
})
|
|
222
|
+
.openapi('CreateAccessData');
|
|
223
|
+
export const createAccessResponseSchema = createMessageDataResponseSchema(createAccessDataSchema, 'CreateAccessResponse', 'Access point created successfully', 'Details of the created access point');
|
|
224
|
+
// ------------------------------
|
|
225
|
+
// Update Access Point Schemas
|
|
226
|
+
// ------------------------------
|
|
227
|
+
export const updateAccessParamsSchema = z
|
|
228
|
+
.object({
|
|
229
|
+
accessId: z
|
|
230
|
+
.string()
|
|
231
|
+
.min(1)
|
|
232
|
+
.transform(val => parseInt(val, 10))
|
|
233
|
+
.refine(val => !isNaN(val) && val > 0, {
|
|
234
|
+
message: 'Access point ID must be a positive number'
|
|
235
|
+
})
|
|
236
|
+
.openapi({
|
|
237
|
+
description: 'The ID of the access point to update',
|
|
238
|
+
example: '1'
|
|
239
|
+
})
|
|
240
|
+
})
|
|
241
|
+
.openapi('UpdateAccessParams');
|
|
242
|
+
export const updateAccessBodySchema = z
|
|
243
|
+
.object({
|
|
244
|
+
name: z.string().min(1).max(255).optional().openapi({
|
|
245
|
+
description: 'New name for the access point'
|
|
246
|
+
}),
|
|
247
|
+
geometry: geoJsonLineStringSchema.nullable().optional().openapi({
|
|
248
|
+
description: 'New geometry'
|
|
249
|
+
}),
|
|
250
|
+
width_meters: z.number().positive().nullable().optional().openapi({
|
|
251
|
+
description: 'New width in meters'
|
|
252
|
+
}),
|
|
253
|
+
height_meters: z.number().positive().nullable().optional().openapi({
|
|
254
|
+
description: 'New height in meters'
|
|
255
|
+
}),
|
|
256
|
+
is_active: z.boolean().optional().openapi({
|
|
257
|
+
description: 'Whether the access point is active'
|
|
258
|
+
})
|
|
259
|
+
})
|
|
260
|
+
.refine(data => Object.keys(data).length > 0, {
|
|
261
|
+
message: 'At least one field must be provided for update'
|
|
262
|
+
})
|
|
263
|
+
.openapi('UpdateAccessBody');
|
|
264
|
+
export const updateAccessDataSchema = createAccessDataSchema
|
|
265
|
+
.extend({
|
|
266
|
+
updated_at: z.string().openapi({
|
|
267
|
+
description: 'Timestamp when access point was updated'
|
|
268
|
+
}),
|
|
269
|
+
updated_by: z.string().nullable().openapi({
|
|
270
|
+
description: 'ID of the user who updated the access point'
|
|
271
|
+
})
|
|
272
|
+
})
|
|
273
|
+
.omit({ access_id: true })
|
|
274
|
+
.extend({
|
|
275
|
+
access_id: z.number().openapi({
|
|
276
|
+
description: 'ID of the updated access point'
|
|
277
|
+
})
|
|
278
|
+
})
|
|
279
|
+
.openapi('UpdateAccessData');
|
|
280
|
+
export const updateAccessResponseSchema = createMessageDataResponseSchema(updateAccessDataSchema, 'UpdateAccessResponse', 'Access point updated successfully', 'Details of the updated access point');
|
|
281
|
+
// ------------------------------
|
|
282
|
+
// Delete Access Point Schemas
|
|
283
|
+
// ------------------------------
|
|
284
|
+
export const deleteAccessParamsSchema = z
|
|
285
|
+
.object({
|
|
286
|
+
accessId: z
|
|
287
|
+
.string()
|
|
288
|
+
.min(1)
|
|
289
|
+
.transform(val => parseInt(val, 10))
|
|
290
|
+
.refine(val => !isNaN(val) && val > 0, {
|
|
291
|
+
message: 'Access point ID must be a positive number'
|
|
292
|
+
})
|
|
293
|
+
.openapi({
|
|
294
|
+
description: 'The ID of the access point to delete',
|
|
295
|
+
example: '1'
|
|
296
|
+
})
|
|
297
|
+
})
|
|
298
|
+
.openapi('DeleteAccessParams');
|
|
299
|
+
export const deleteAccessDataSchema = z
|
|
300
|
+
.object({
|
|
301
|
+
access_id: z.number().openapi({
|
|
302
|
+
description: 'ID of the deleted access point',
|
|
303
|
+
example: 1
|
|
304
|
+
}),
|
|
305
|
+
deleted_at: z.string().openapi({
|
|
306
|
+
description: 'Timestamp when access point was deleted'
|
|
307
|
+
})
|
|
308
|
+
})
|
|
309
|
+
.openapi('DeleteAccessData');
|
|
310
|
+
export const deleteAccessResponseSchema = createMessageDataResponseSchema(deleteAccessDataSchema, 'DeleteAccessResponse', 'Access point deleted successfully', 'Details of the deleted access point');
|
|
311
|
+
// ------------------------------
|
|
312
|
+
// Link/Unlink Parking Areas Schemas
|
|
313
|
+
// ------------------------------
|
|
314
|
+
export const linkAccessAreasParamsSchema = z
|
|
315
|
+
.object({
|
|
316
|
+
accessId: z
|
|
317
|
+
.string()
|
|
318
|
+
.min(1)
|
|
319
|
+
.transform(val => parseInt(val, 10))
|
|
320
|
+
.refine(val => !isNaN(val) && val > 0, {
|
|
321
|
+
message: 'Access point ID must be a positive number'
|
|
322
|
+
})
|
|
323
|
+
.openapi({
|
|
324
|
+
description: 'The ID of the access point',
|
|
325
|
+
example: '1'
|
|
326
|
+
})
|
|
327
|
+
})
|
|
328
|
+
.openapi('LinkAccessAreasParams');
|
|
329
|
+
export const linkAccessAreasBodySchema = z
|
|
330
|
+
.object({
|
|
331
|
+
parking_area_ids: z
|
|
332
|
+
.array(z.number().int().positive())
|
|
333
|
+
.min(1, 'At least one parking area ID must be provided')
|
|
334
|
+
.openapi({
|
|
335
|
+
description: 'IDs of parking areas to link',
|
|
336
|
+
example: [1, 2, 3]
|
|
337
|
+
})
|
|
338
|
+
})
|
|
339
|
+
.openapi('LinkAccessAreasBody');
|
|
340
|
+
export const linkAccessAreasDataSchema = z
|
|
341
|
+
.object({
|
|
342
|
+
access_id: z.number().openapi({
|
|
343
|
+
description: 'ID of the access point',
|
|
344
|
+
example: 1
|
|
345
|
+
}),
|
|
346
|
+
linked_count: z.number().openapi({
|
|
347
|
+
description: 'Number of parking areas linked',
|
|
348
|
+
example: 3
|
|
349
|
+
}),
|
|
350
|
+
linked_parking_areas: z
|
|
351
|
+
.array(z.object({
|
|
352
|
+
parking_area_id: z.number(),
|
|
353
|
+
parking_area_name: z.string().nullable()
|
|
354
|
+
}))
|
|
355
|
+
.openapi({
|
|
356
|
+
description: 'List of linked parking areas'
|
|
357
|
+
})
|
|
358
|
+
})
|
|
359
|
+
.openapi('LinkAccessAreasData');
|
|
360
|
+
export const linkAccessAreasResponseSchema = createMessageDataResponseSchema(linkAccessAreasDataSchema, 'LinkAccessAreasResponse', 'Parking areas linked successfully', 'Details of the linked parking areas');
|
|
361
|
+
export const unlinkAccessAreaParamsSchema = z
|
|
362
|
+
.object({
|
|
363
|
+
accessId: z
|
|
364
|
+
.string()
|
|
365
|
+
.min(1)
|
|
366
|
+
.transform(val => parseInt(val, 10))
|
|
367
|
+
.refine(val => !isNaN(val) && val > 0, {
|
|
368
|
+
message: 'Access point ID must be a positive number'
|
|
369
|
+
})
|
|
370
|
+
.openapi({
|
|
371
|
+
description: 'The ID of the access point',
|
|
372
|
+
example: '1'
|
|
373
|
+
}),
|
|
374
|
+
areaId: z
|
|
375
|
+
.string()
|
|
376
|
+
.min(1)
|
|
377
|
+
.transform(val => parseInt(val, 10))
|
|
378
|
+
.refine(val => !isNaN(val) && val > 0, {
|
|
379
|
+
message: 'Parking area ID must be a positive number'
|
|
380
|
+
})
|
|
381
|
+
.openapi({
|
|
382
|
+
description: 'The ID of the parking area to unlink',
|
|
383
|
+
example: '1'
|
|
384
|
+
})
|
|
385
|
+
})
|
|
386
|
+
.openapi('UnlinkAccessAreaParams');
|
|
387
|
+
export const unlinkAccessAreaDataSchema = z
|
|
388
|
+
.object({
|
|
389
|
+
access_id: z.number().openapi({
|
|
390
|
+
description: 'ID of the access point',
|
|
391
|
+
example: 1
|
|
392
|
+
}),
|
|
393
|
+
parking_area_id: z.number().openapi({
|
|
394
|
+
description: 'ID of the unlinked parking area',
|
|
395
|
+
example: 1
|
|
396
|
+
}),
|
|
397
|
+
unlinked_at: z.string().openapi({
|
|
398
|
+
description: 'Timestamp when the link was removed'
|
|
399
|
+
})
|
|
400
|
+
})
|
|
401
|
+
.openapi('UnlinkAccessAreaData');
|
|
402
|
+
export const unlinkAccessAreaResponseSchema = createMessageDataResponseSchema(unlinkAccessAreaDataSchema, 'UnlinkAccessAreaResponse', 'Parking area unlinked successfully', 'Details of the unlinked parking area');
|
|
403
|
+
// ------------------------------
|
|
404
|
+
// Get Access Points Response Schemas
|
|
405
|
+
// ------------------------------
|
|
406
|
+
export const getAccessesDataSchema = z
|
|
407
|
+
.object({
|
|
408
|
+
event_id: z.number().openapi({
|
|
409
|
+
description: 'ID of the event',
|
|
410
|
+
example: 1
|
|
411
|
+
}),
|
|
412
|
+
accesses: z.array(parkingAreaAccessWithLinksSchema).openapi({
|
|
413
|
+
description: 'List of access points for the event'
|
|
414
|
+
}),
|
|
415
|
+
total_count: z.number().openapi({
|
|
416
|
+
description: 'Total number of access points',
|
|
417
|
+
example: 4
|
|
418
|
+
})
|
|
419
|
+
})
|
|
420
|
+
.openapi('GetAccessesData');
|
|
421
|
+
export const getAccessesResponseSchema = createSuccessResponseSchema(getAccessesDataSchema, 'GetAccessesResponse', 'Access points for the event');
|
|
422
|
+
export const getAccessDetailResponseSchema = createSuccessResponseSchema(parkingAreaAccessWithLinksSchema, 'GetAccessDetailResponse', 'Access point details with linked parking areas');
|
|
423
|
+
// ------------------------------
|
|
424
|
+
// Bulk Upsert Access Points Schemas
|
|
425
|
+
// ------------------------------
|
|
426
|
+
export const bulkUpsertAccessesBodySchema = z
|
|
427
|
+
.object({
|
|
428
|
+
event_id: z.number().int().positive().openapi({
|
|
429
|
+
description: 'ID of the event',
|
|
430
|
+
example: 1
|
|
431
|
+
}),
|
|
432
|
+
accesses: z
|
|
433
|
+
.array(z.object({
|
|
434
|
+
id: z.number().int().positive().optional().openapi({
|
|
435
|
+
description: 'Access point ID (for updates). Omit for new access points.'
|
|
436
|
+
}),
|
|
437
|
+
name: z.string().min(1).max(255).openapi({
|
|
438
|
+
description: 'Name of the access point'
|
|
439
|
+
}),
|
|
440
|
+
geometry: geoJsonLineStringSchema.optional(),
|
|
441
|
+
width_meters: z.number().positive().optional(),
|
|
442
|
+
height_meters: z.number().positive().optional(),
|
|
443
|
+
linked_parking_area_ids: z.array(z.number().int().positive()).optional()
|
|
444
|
+
}))
|
|
445
|
+
.min(1, 'At least one access point must be provided')
|
|
446
|
+
.openapi({
|
|
447
|
+
description: 'Array of access points to create or update'
|
|
448
|
+
})
|
|
449
|
+
})
|
|
450
|
+
.openapi('BulkUpsertAccessesBody');
|
|
451
|
+
export const bulkUpsertAccessesDataSchema = z
|
|
452
|
+
.object({
|
|
453
|
+
event_id: z.number().openapi({
|
|
454
|
+
description: 'ID of the event',
|
|
455
|
+
example: 1
|
|
456
|
+
}),
|
|
457
|
+
total_upserted: z.number().openapi({
|
|
458
|
+
description: 'Total number of access points successfully upserted',
|
|
459
|
+
example: 4
|
|
460
|
+
}),
|
|
461
|
+
upserted_accesses: z.array(parkingAreaAccessWithLinksSchema).openapi({
|
|
462
|
+
description: 'Array of successfully upserted access points'
|
|
463
|
+
})
|
|
464
|
+
})
|
|
465
|
+
.openapi('BulkUpsertAccessesData');
|
|
466
|
+
export const bulkUpsertAccessesResponseSchema = createMessageDataResponseSchema(bulkUpsertAccessesDataSchema, 'BulkUpsertAccessesResponse', 'Access points upserted successfully', 'Details of the upserted access points');
|