@deepintel-ltd/farmpro-contracts 1.7.21 → 1.8.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-gateway-admin.routes.d.ts","sourceRoot":"","sources":["../../src/routes/device-gateway-admin.routes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiBxB,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyGnC,CAAC"}
@@ -0,0 +1,105 @@
1
+ import { initContract } from '@ts-rest/core';
2
+ import { z } from 'zod';
3
+ import { createDeviceRequestSchema, createDeviceResponseSchema, listDevicesResponseSchema, updateDeviceRequestSchema, updateDeviceResponseSchema, createActuatorRequestSchema, listActuatorsResponseSchema, actuatorSchema, actuatorCommandRequestSchema, actuatorCommandResponseSchema, deviceErrorSchema, } from '../schemas/device-gateway.schemas';
4
+ const c = initContract();
5
+ export const deviceGatewayAdminRouter = c.router({
6
+ createDevice: {
7
+ method: 'POST',
8
+ path: '/farms/:farmId/fields/:fieldId/devices',
9
+ pathParams: z.object({
10
+ farmId: z.string().uuid(),
11
+ fieldId: z.string().uuid(),
12
+ }),
13
+ body: createDeviceRequestSchema,
14
+ responses: {
15
+ 201: createDeviceResponseSchema,
16
+ 401: deviceErrorSchema,
17
+ 403: deviceErrorSchema,
18
+ 404: deviceErrorSchema,
19
+ },
20
+ summary: 'Register a greenhouse edge device and generate API key',
21
+ },
22
+ listDevices: {
23
+ method: 'GET',
24
+ path: '/farms/:farmId/fields/:fieldId/devices',
25
+ pathParams: z.object({
26
+ farmId: z.string().uuid(),
27
+ fieldId: z.string().uuid(),
28
+ }),
29
+ responses: {
30
+ 200: listDevicesResponseSchema,
31
+ 401: deviceErrorSchema,
32
+ 403: deviceErrorSchema,
33
+ 404: deviceErrorSchema,
34
+ },
35
+ summary: 'List greenhouse devices for a field',
36
+ },
37
+ updateDevice: {
38
+ method: 'PATCH',
39
+ path: '/farms/:farmId/fields/:fieldId/devices/:deviceId',
40
+ pathParams: z.object({
41
+ farmId: z.string().uuid(),
42
+ fieldId: z.string().uuid(),
43
+ deviceId: z.string().uuid(),
44
+ }),
45
+ body: updateDeviceRequestSchema,
46
+ responses: {
47
+ 200: updateDeviceResponseSchema,
48
+ 401: deviceErrorSchema,
49
+ 403: deviceErrorSchema,
50
+ 404: deviceErrorSchema,
51
+ },
52
+ summary: 'Update device config including pump calibration',
53
+ },
54
+ createActuator: {
55
+ method: 'POST',
56
+ path: '/farms/:farmId/fields/:fieldId/devices/:deviceId/actuators',
57
+ pathParams: z.object({
58
+ farmId: z.string().uuid(),
59
+ fieldId: z.string().uuid(),
60
+ deviceId: z.string().uuid(),
61
+ }),
62
+ body: createActuatorRequestSchema,
63
+ responses: {
64
+ 201: z.object({ actuator: actuatorSchema }),
65
+ 401: deviceErrorSchema,
66
+ 403: deviceErrorSchema,
67
+ 404: deviceErrorSchema,
68
+ },
69
+ summary: 'Register an actuator on a greenhouse device',
70
+ },
71
+ listActuators: {
72
+ method: 'GET',
73
+ path: '/farms/:farmId/fields/:fieldId/devices/:deviceId/actuators',
74
+ pathParams: z.object({
75
+ farmId: z.string().uuid(),
76
+ fieldId: z.string().uuid(),
77
+ deviceId: z.string().uuid(),
78
+ }),
79
+ responses: {
80
+ 200: listActuatorsResponseSchema,
81
+ 401: deviceErrorSchema,
82
+ 403: deviceErrorSchema,
83
+ 404: deviceErrorSchema,
84
+ },
85
+ summary: 'List actuators for a greenhouse device',
86
+ },
87
+ sendActuatorCommand: {
88
+ method: 'POST',
89
+ path: '/farms/:farmId/fields/:fieldId/actuators/:actuatorId/command',
90
+ pathParams: z.object({
91
+ farmId: z.string().uuid(),
92
+ fieldId: z.string().uuid(),
93
+ actuatorId: z.string().uuid(),
94
+ }),
95
+ body: actuatorCommandRequestSchema,
96
+ responses: {
97
+ 201: actuatorCommandResponseSchema,
98
+ 401: deviceErrorSchema,
99
+ 403: deviceErrorSchema,
100
+ 404: deviceErrorSchema,
101
+ 422: deviceErrorSchema,
102
+ },
103
+ summary: 'Queue a manual actuator command (Run now)',
104
+ },
105
+ });
@@ -0,0 +1,457 @@
1
+ import { z } from 'zod';
2
+ export declare const deviceGatewayRouter: {
3
+ heartbeat: {
4
+ summary: "Device heartbeat and config sync";
5
+ method: "POST";
6
+ body: z.ZodObject<{
7
+ deviceId: z.ZodString;
8
+ firmwareVersion: z.ZodOptional<z.ZodString>;
9
+ uptimeSec: z.ZodOptional<z.ZodNumber>;
10
+ wifiRssi: z.ZodOptional<z.ZodNumber>;
11
+ freeHeap: z.ZodOptional<z.ZodNumber>;
12
+ bufferedReadingsCount: z.ZodOptional<z.ZodNumber>;
13
+ bufferOverflow: z.ZodOptional<z.ZodBoolean>;
14
+ actuatorStates: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
15
+ }, "strip", z.ZodTypeAny, {
16
+ deviceId: string;
17
+ firmwareVersion?: string | undefined;
18
+ uptimeSec?: number | undefined;
19
+ wifiRssi?: number | undefined;
20
+ freeHeap?: number | undefined;
21
+ bufferedReadingsCount?: number | undefined;
22
+ bufferOverflow?: boolean | undefined;
23
+ actuatorStates?: Record<string, string> | undefined;
24
+ }, {
25
+ deviceId: string;
26
+ firmwareVersion?: string | undefined;
27
+ uptimeSec?: number | undefined;
28
+ wifiRssi?: number | undefined;
29
+ freeHeap?: number | undefined;
30
+ bufferedReadingsCount?: number | undefined;
31
+ bufferOverflow?: boolean | undefined;
32
+ actuatorStates?: Record<string, string> | undefined;
33
+ }>;
34
+ path: "/device/heartbeat";
35
+ responses: {
36
+ 200: z.ZodObject<{
37
+ serverTime: z.ZodString;
38
+ config: z.ZodObject<{
39
+ heartbeatIntervalSec: z.ZodOptional<z.ZodNumber>;
40
+ commandPollIntervalSec: z.ZodOptional<z.ZodNumber>;
41
+ sensorIntervals: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
42
+ pumpCalibration: z.ZodOptional<z.ZodObject<{
43
+ fert_pump_a: z.ZodOptional<z.ZodObject<{
44
+ mlPerSecond: z.ZodNumber;
45
+ calibratedAt: z.ZodOptional<z.ZodString>;
46
+ }, "strip", z.ZodTypeAny, {
47
+ mlPerSecond: number;
48
+ calibratedAt?: string | undefined;
49
+ }, {
50
+ mlPerSecond: number;
51
+ calibratedAt?: string | undefined;
52
+ }>>;
53
+ fert_pump_b: z.ZodOptional<z.ZodObject<{
54
+ mlPerSecond: z.ZodNumber;
55
+ calibratedAt: z.ZodOptional<z.ZodString>;
56
+ }, "strip", z.ZodTypeAny, {
57
+ mlPerSecond: number;
58
+ calibratedAt?: string | undefined;
59
+ }, {
60
+ mlPerSecond: number;
61
+ calibratedAt?: string | undefined;
62
+ }>>;
63
+ }, "strip", z.ZodTypeAny, {
64
+ fert_pump_a?: {
65
+ mlPerSecond: number;
66
+ calibratedAt?: string | undefined;
67
+ } | undefined;
68
+ fert_pump_b?: {
69
+ mlPerSecond: number;
70
+ calibratedAt?: string | undefined;
71
+ } | undefined;
72
+ }, {
73
+ fert_pump_a?: {
74
+ mlPerSecond: number;
75
+ calibratedAt?: string | undefined;
76
+ } | undefined;
77
+ fert_pump_b?: {
78
+ mlPerSecond: number;
79
+ calibratedAt?: string | undefined;
80
+ } | undefined;
81
+ }>>;
82
+ gpioMap: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
83
+ }, "strip", z.ZodTypeAny, {
84
+ heartbeatIntervalSec?: number | undefined;
85
+ commandPollIntervalSec?: number | undefined;
86
+ sensorIntervals?: Record<string, number> | undefined;
87
+ pumpCalibration?: {
88
+ fert_pump_a?: {
89
+ mlPerSecond: number;
90
+ calibratedAt?: string | undefined;
91
+ } | undefined;
92
+ fert_pump_b?: {
93
+ mlPerSecond: number;
94
+ calibratedAt?: string | undefined;
95
+ } | undefined;
96
+ } | undefined;
97
+ gpioMap?: Record<string, number> | undefined;
98
+ }, {
99
+ heartbeatIntervalSec?: number | undefined;
100
+ commandPollIntervalSec?: number | undefined;
101
+ sensorIntervals?: Record<string, number> | undefined;
102
+ pumpCalibration?: {
103
+ fert_pump_a?: {
104
+ mlPerSecond: number;
105
+ calibratedAt?: string | undefined;
106
+ } | undefined;
107
+ fert_pump_b?: {
108
+ mlPerSecond: number;
109
+ calibratedAt?: string | undefined;
110
+ } | undefined;
111
+ } | undefined;
112
+ gpioMap?: Record<string, number> | undefined;
113
+ }>;
114
+ }, "strip", z.ZodTypeAny, {
115
+ serverTime: string;
116
+ config: {
117
+ heartbeatIntervalSec?: number | undefined;
118
+ commandPollIntervalSec?: number | undefined;
119
+ sensorIntervals?: Record<string, number> | undefined;
120
+ pumpCalibration?: {
121
+ fert_pump_a?: {
122
+ mlPerSecond: number;
123
+ calibratedAt?: string | undefined;
124
+ } | undefined;
125
+ fert_pump_b?: {
126
+ mlPerSecond: number;
127
+ calibratedAt?: string | undefined;
128
+ } | undefined;
129
+ } | undefined;
130
+ gpioMap?: Record<string, number> | undefined;
131
+ };
132
+ }, {
133
+ serverTime: string;
134
+ config: {
135
+ heartbeatIntervalSec?: number | undefined;
136
+ commandPollIntervalSec?: number | undefined;
137
+ sensorIntervals?: Record<string, number> | undefined;
138
+ pumpCalibration?: {
139
+ fert_pump_a?: {
140
+ mlPerSecond: number;
141
+ calibratedAt?: string | undefined;
142
+ } | undefined;
143
+ fert_pump_b?: {
144
+ mlPerSecond: number;
145
+ calibratedAt?: string | undefined;
146
+ } | undefined;
147
+ } | undefined;
148
+ gpioMap?: Record<string, number> | undefined;
149
+ };
150
+ }>;
151
+ 401: z.ZodObject<{
152
+ message: z.ZodString;
153
+ code: z.ZodString;
154
+ }, "strip", z.ZodTypeAny, {
155
+ code: string;
156
+ message: string;
157
+ }, {
158
+ code: string;
159
+ message: string;
160
+ }>;
161
+ 404: z.ZodObject<{
162
+ message: z.ZodString;
163
+ code: z.ZodString;
164
+ }, "strip", z.ZodTypeAny, {
165
+ code: string;
166
+ message: string;
167
+ }, {
168
+ code: string;
169
+ message: string;
170
+ }>;
171
+ };
172
+ };
173
+ postSensorReading: {
174
+ pathParams: z.ZodObject<{
175
+ sensorId: z.ZodString;
176
+ }, "strip", z.ZodTypeAny, {
177
+ sensorId: string;
178
+ }, {
179
+ sensorId: string;
180
+ }>;
181
+ summary: "Ingest a single sensor reading from edge device";
182
+ method: "POST";
183
+ body: z.ZodObject<{
184
+ value: z.ZodNumber;
185
+ unit: z.ZodString;
186
+ quality: z.ZodOptional<z.ZodEnum<["good", "fair", "poor"]>>;
187
+ readAt: z.ZodString;
188
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
189
+ }, "strip", z.ZodTypeAny, {
190
+ value: number;
191
+ unit: string;
192
+ readAt: string;
193
+ metadata?: Record<string, unknown> | undefined;
194
+ quality?: "poor" | "fair" | "good" | undefined;
195
+ }, {
196
+ value: number;
197
+ unit: string;
198
+ readAt: string;
199
+ metadata?: Record<string, unknown> | undefined;
200
+ quality?: "poor" | "fair" | "good" | undefined;
201
+ }>;
202
+ path: "/device/sensors/:sensorId/readings";
203
+ responses: {
204
+ 201: z.ZodObject<{
205
+ readingId: z.ZodString;
206
+ alertTriggered: z.ZodBoolean;
207
+ }, "strip", z.ZodTypeAny, {
208
+ readingId: string;
209
+ alertTriggered: boolean;
210
+ }, {
211
+ readingId: string;
212
+ alertTriggered: boolean;
213
+ }>;
214
+ 401: z.ZodObject<{
215
+ message: z.ZodString;
216
+ code: z.ZodString;
217
+ }, "strip", z.ZodTypeAny, {
218
+ code: string;
219
+ message: string;
220
+ }, {
221
+ code: string;
222
+ message: string;
223
+ }>;
224
+ 404: z.ZodObject<{
225
+ message: z.ZodString;
226
+ code: z.ZodString;
227
+ }, "strip", z.ZodTypeAny, {
228
+ code: string;
229
+ message: string;
230
+ }, {
231
+ code: string;
232
+ message: string;
233
+ }>;
234
+ };
235
+ };
236
+ postBatchReadings: {
237
+ summary: "Bulk ingest offline-buffered sensor readings";
238
+ method: "POST";
239
+ body: z.ZodObject<{
240
+ readings: z.ZodArray<z.ZodObject<{
241
+ sensorId: z.ZodString;
242
+ value: z.ZodNumber;
243
+ unit: z.ZodString;
244
+ quality: z.ZodOptional<z.ZodEnum<["good", "fair", "poor"]>>;
245
+ readAt: z.ZodString;
246
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
247
+ }, "strip", z.ZodTypeAny, {
248
+ value: number;
249
+ unit: string;
250
+ readAt: string;
251
+ sensorId: string;
252
+ metadata?: Record<string, unknown> | undefined;
253
+ quality?: "poor" | "fair" | "good" | undefined;
254
+ }, {
255
+ value: number;
256
+ unit: string;
257
+ readAt: string;
258
+ sensorId: string;
259
+ metadata?: Record<string, unknown> | undefined;
260
+ quality?: "poor" | "fair" | "good" | undefined;
261
+ }>, "many">;
262
+ }, "strip", z.ZodTypeAny, {
263
+ readings: {
264
+ value: number;
265
+ unit: string;
266
+ readAt: string;
267
+ sensorId: string;
268
+ metadata?: Record<string, unknown> | undefined;
269
+ quality?: "poor" | "fair" | "good" | undefined;
270
+ }[];
271
+ }, {
272
+ readings: {
273
+ value: number;
274
+ unit: string;
275
+ readAt: string;
276
+ sensorId: string;
277
+ metadata?: Record<string, unknown> | undefined;
278
+ quality?: "poor" | "fair" | "good" | undefined;
279
+ }[];
280
+ }>;
281
+ path: "/device/sensors/readings/batch";
282
+ responses: {
283
+ 201: z.ZodObject<{
284
+ accepted: z.ZodNumber;
285
+ rejected: z.ZodNumber;
286
+ alertsTriggered: z.ZodNumber;
287
+ }, "strip", z.ZodTypeAny, {
288
+ accepted: number;
289
+ rejected: number;
290
+ alertsTriggered: number;
291
+ }, {
292
+ accepted: number;
293
+ rejected: number;
294
+ alertsTriggered: number;
295
+ }>;
296
+ 401: z.ZodObject<{
297
+ message: z.ZodString;
298
+ code: z.ZodString;
299
+ }, "strip", z.ZodTypeAny, {
300
+ code: string;
301
+ message: string;
302
+ }, {
303
+ code: string;
304
+ message: string;
305
+ }>;
306
+ 400: z.ZodObject<{
307
+ message: z.ZodString;
308
+ code: z.ZodString;
309
+ }, "strip", z.ZodTypeAny, {
310
+ code: string;
311
+ message: string;
312
+ }, {
313
+ code: string;
314
+ message: string;
315
+ }>;
316
+ };
317
+ };
318
+ listCommands: {
319
+ query: z.ZodObject<{
320
+ deviceId: z.ZodString;
321
+ }, "strip", z.ZodTypeAny, {
322
+ deviceId: string;
323
+ }, {
324
+ deviceId: string;
325
+ }>;
326
+ summary: "Poll pending actuator commands for device";
327
+ method: "GET";
328
+ path: "/device/commands";
329
+ responses: {
330
+ 200: z.ZodObject<{
331
+ commands: z.ZodArray<z.ZodObject<{
332
+ id: z.ZodString;
333
+ actuatorId: z.ZodString;
334
+ actuatorType: z.ZodEnum<["IRRIGATION_VALVE", "FERT_PUMP_A", "FERT_PUMP_B", "FAN"]>;
335
+ command: z.ZodEnum<["ON", "OFF", "PULSE"]>;
336
+ durationSec: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
337
+ source: z.ZodString;
338
+ createdAt: z.ZodString;
339
+ }, "strip", z.ZodTypeAny, {
340
+ id: string;
341
+ source: string;
342
+ createdAt: string;
343
+ actuatorId: string;
344
+ actuatorType: "IRRIGATION_VALVE" | "FERT_PUMP_A" | "FERT_PUMP_B" | "FAN";
345
+ command: "ON" | "OFF" | "PULSE";
346
+ durationSec?: number | null | undefined;
347
+ }, {
348
+ id: string;
349
+ source: string;
350
+ createdAt: string;
351
+ actuatorId: string;
352
+ actuatorType: "IRRIGATION_VALVE" | "FERT_PUMP_A" | "FERT_PUMP_B" | "FAN";
353
+ command: "ON" | "OFF" | "PULSE";
354
+ durationSec?: number | null | undefined;
355
+ }>, "many">;
356
+ }, "strip", z.ZodTypeAny, {
357
+ commands: {
358
+ id: string;
359
+ source: string;
360
+ createdAt: string;
361
+ actuatorId: string;
362
+ actuatorType: "IRRIGATION_VALVE" | "FERT_PUMP_A" | "FERT_PUMP_B" | "FAN";
363
+ command: "ON" | "OFF" | "PULSE";
364
+ durationSec?: number | null | undefined;
365
+ }[];
366
+ }, {
367
+ commands: {
368
+ id: string;
369
+ source: string;
370
+ createdAt: string;
371
+ actuatorId: string;
372
+ actuatorType: "IRRIGATION_VALVE" | "FERT_PUMP_A" | "FERT_PUMP_B" | "FAN";
373
+ command: "ON" | "OFF" | "PULSE";
374
+ durationSec?: number | null | undefined;
375
+ }[];
376
+ }>;
377
+ 401: z.ZodObject<{
378
+ message: z.ZodString;
379
+ code: z.ZodString;
380
+ }, "strip", z.ZodTypeAny, {
381
+ code: string;
382
+ message: string;
383
+ }, {
384
+ code: string;
385
+ message: string;
386
+ }>;
387
+ 404: z.ZodObject<{
388
+ message: z.ZodString;
389
+ code: z.ZodString;
390
+ }, "strip", z.ZodTypeAny, {
391
+ code: string;
392
+ message: string;
393
+ }, {
394
+ code: string;
395
+ message: string;
396
+ }>;
397
+ };
398
+ };
399
+ ackCommand: {
400
+ pathParams: z.ZodObject<{
401
+ commandId: z.ZodString;
402
+ }, "strip", z.ZodTypeAny, {
403
+ commandId: string;
404
+ }, {
405
+ commandId: string;
406
+ }>;
407
+ summary: "Acknowledge or fail an actuator command";
408
+ method: "POST";
409
+ body: z.ZodObject<{
410
+ status: z.ZodEnum<["acked", "failed"]>;
411
+ executedAt: z.ZodString;
412
+ error: z.ZodOptional<z.ZodString>;
413
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
414
+ }, "strip", z.ZodTypeAny, {
415
+ status: "failed" | "acked";
416
+ executedAt: string;
417
+ metadata?: Record<string, unknown> | undefined;
418
+ error?: string | undefined;
419
+ }, {
420
+ status: "failed" | "acked";
421
+ executedAt: string;
422
+ metadata?: Record<string, unknown> | undefined;
423
+ error?: string | undefined;
424
+ }>;
425
+ path: "/device/commands/:commandId/ack";
426
+ responses: {
427
+ 200: z.ZodObject<{
428
+ success: z.ZodBoolean;
429
+ }, "strip", z.ZodTypeAny, {
430
+ success: boolean;
431
+ }, {
432
+ success: boolean;
433
+ }>;
434
+ 401: z.ZodObject<{
435
+ message: z.ZodString;
436
+ code: z.ZodString;
437
+ }, "strip", z.ZodTypeAny, {
438
+ code: string;
439
+ message: string;
440
+ }, {
441
+ code: string;
442
+ message: string;
443
+ }>;
444
+ 404: z.ZodObject<{
445
+ message: z.ZodString;
446
+ code: z.ZodString;
447
+ }, "strip", z.ZodTypeAny, {
448
+ code: string;
449
+ message: string;
450
+ }, {
451
+ code: string;
452
+ message: string;
453
+ }>;
454
+ };
455
+ };
456
+ };
457
+ //# sourceMappingURL=device-gateway.routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-gateway.routes.d.ts","sourceRoot":"","sources":["../../src/routes/device-gateway.routes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiBxB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8D9B,CAAC"}
@@ -0,0 +1,63 @@
1
+ import { initContract } from '@ts-rest/core';
2
+ import { z } from 'zod';
3
+ import { heartbeatRequestSchema, heartbeatResponseSchema, sensorReadingRequestSchema, sensorReadingResponseSchema, batchReadingsRequestSchema, batchReadingsResponseSchema, listCommandsQuerySchema, listCommandsResponseSchema, commandAckRequestSchema, commandAckResponseSchema, deviceErrorSchema, } from '../schemas/device-gateway.schemas';
4
+ const c = initContract();
5
+ export const deviceGatewayRouter = c.router({
6
+ heartbeat: {
7
+ method: 'POST',
8
+ path: '/device/heartbeat',
9
+ body: heartbeatRequestSchema,
10
+ responses: {
11
+ 200: heartbeatResponseSchema,
12
+ 401: deviceErrorSchema,
13
+ 404: deviceErrorSchema,
14
+ },
15
+ summary: 'Device heartbeat and config sync',
16
+ },
17
+ postSensorReading: {
18
+ method: 'POST',
19
+ path: '/device/sensors/:sensorId/readings',
20
+ pathParams: z.object({ sensorId: z.string().uuid() }),
21
+ body: sensorReadingRequestSchema,
22
+ responses: {
23
+ 201: sensorReadingResponseSchema,
24
+ 401: deviceErrorSchema,
25
+ 404: deviceErrorSchema,
26
+ },
27
+ summary: 'Ingest a single sensor reading from edge device',
28
+ },
29
+ postBatchReadings: {
30
+ method: 'POST',
31
+ path: '/device/sensors/readings/batch',
32
+ body: batchReadingsRequestSchema,
33
+ responses: {
34
+ 201: batchReadingsResponseSchema,
35
+ 401: deviceErrorSchema,
36
+ 400: deviceErrorSchema,
37
+ },
38
+ summary: 'Bulk ingest offline-buffered sensor readings',
39
+ },
40
+ listCommands: {
41
+ method: 'GET',
42
+ path: '/device/commands',
43
+ query: listCommandsQuerySchema,
44
+ responses: {
45
+ 200: listCommandsResponseSchema,
46
+ 401: deviceErrorSchema,
47
+ 404: deviceErrorSchema,
48
+ },
49
+ summary: 'Poll pending actuator commands for device',
50
+ },
51
+ ackCommand: {
52
+ method: 'POST',
53
+ path: '/device/commands/:commandId/ack',
54
+ pathParams: z.object({ commandId: z.string().uuid() }),
55
+ body: commandAckRequestSchema,
56
+ responses: {
57
+ 200: commandAckResponseSchema,
58
+ 401: deviceErrorSchema,
59
+ 404: deviceErrorSchema,
60
+ },
61
+ summary: 'Acknowledge or fail an actuator command',
62
+ },
63
+ });
@@ -49,6 +49,8 @@ import { cooperativeRouter } from './cooperative.routes';
49
49
  import { extensionRouter } from './extension.routes';
50
50
  import { notificationsRouter } from './notifications.routes';
51
51
  import { commodityDealsRouter } from './commodity-deals.routes';
52
+ import { deviceGatewayRouter } from './device-gateway.routes';
53
+ import { deviceGatewayAdminRouter } from './device-gateway-admin.routes';
52
54
  /**
53
55
  * Explicit interface definition for the API contract.
54
56
  * This avoids TypeScript's type serialization limit when combining many routers
@@ -111,6 +113,8 @@ export interface ApiContractDefinition {
111
113
  extension: typeof extensionRouter;
112
114
  notifications: typeof notificationsRouter;
113
115
  commodityDeals: typeof commodityDealsRouter;
116
+ deviceGateway: typeof deviceGatewayRouter;
117
+ deviceGatewayAdmin: typeof deviceGatewayAdminRouter;
114
118
  }
115
119
  /**
116
120
  * Main API contract combining all routers
@@ -183,4 +187,6 @@ export type CooperativeEndpoints = ApiContractType['cooperative'];
183
187
  export type ExtensionEndpoints = ApiContractType['extension'];
184
188
  export type NotificationsEndpoints = ApiContractType['notifications'];
185
189
  export type CommodityDealsEndpoints = ApiContractType['commodityDeals'];
190
+ export type DeviceGatewayEndpoints = ApiContractType['deviceGateway'];
191
+ export type DeviceGatewayAdminEndpoints = ApiContractType['deviceGatewayAdmin'];
186
192
  //# sourceMappingURL=index.d.ts.map