@deepintel-ltd/farmpro-contracts 1.5.8 → 1.5.10
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/index.js +50 -92
- package/dist/routes/admin.routes.js +13 -16
- package/dist/routes/agent-workflows.routes.js +81 -84
- package/dist/routes/agents.routes.js +29 -32
- package/dist/routes/analytics.routes.js +11 -14
- package/dist/routes/auth.routes.js +55 -58
- package/dist/routes/categories.routes.js +23 -26
- package/dist/routes/documents.routes.js +67 -70
- package/dist/routes/equipment.routes.js +55 -58
- package/dist/routes/farms.routes.js +32 -35
- package/dist/routes/field-monitoring.routes.d.ts +8 -1
- package/dist/routes/field-monitoring.routes.d.ts.map +1 -1
- package/dist/routes/field-monitoring.routes.js +77 -74
- package/dist/routes/field-observations.routes.js +41 -44
- package/dist/routes/fields.routes.js +44 -47
- package/dist/routes/finance.routes.js +121 -124
- package/dist/routes/harvest.routes.js +46 -49
- package/dist/routes/health.routes.js +6 -9
- package/dist/routes/index.js +51 -54
- package/dist/routes/input-usage.routes.js +14 -17
- package/dist/routes/inventory.routes.js +57 -60
- package/dist/routes/seasonal-plans.routes.js +14 -17
- package/dist/routes/soil-tests.routes.js +45 -48
- package/dist/routes/suppliers.routes.js +70 -73
- package/dist/routes/tasks.routes.js +65 -68
- package/dist/routes/team.routes.d.ts +306 -0
- package/dist/routes/team.routes.d.ts.map +1 -1
- package/dist/routes/team.routes.js +79 -60
- package/dist/routes/users.routes.js +13 -16
- package/dist/routes/weather.routes.js +10 -13
- package/dist/schemas/admin.schemas.js +43 -46
- package/dist/schemas/agent-workflows.schemas.js +34 -37
- package/dist/schemas/agents.schemas.js +46 -49
- package/dist/schemas/analytics.schemas.js +51 -54
- package/dist/schemas/auth.schemas.js +96 -99
- package/dist/schemas/categories.schemas.js +27 -30
- package/dist/schemas/common.schemas.js +89 -95
- package/dist/schemas/documents.schemas.js +59 -62
- package/dist/schemas/equipment.schemas.js +86 -89
- package/dist/schemas/farms.schemas.js +40 -43
- package/dist/schemas/field-monitoring.schemas.js +207 -210
- package/dist/schemas/field-observations.schemas.js +93 -96
- package/dist/schemas/fields.schemas.js +82 -85
- package/dist/schemas/finance.schemas.js +134 -137
- package/dist/schemas/harvest.schemas.js +46 -49
- package/dist/schemas/health.schemas.js +14 -17
- package/dist/schemas/input-usage.schemas.js +21 -24
- package/dist/schemas/inventory.schemas.js +58 -61
- package/dist/schemas/recommendations.schemas.js +22 -25
- package/dist/schemas/seasonal-plans.schemas.js +21 -24
- package/dist/schemas/soil-tests.schemas.js +70 -73
- package/dist/schemas/suppliers.schemas.js +90 -93
- package/dist/schemas/tasks.schemas.js +93 -96
- package/dist/schemas/team.schemas.js +35 -38
- package/dist/schemas/users.schemas.js +19 -22
- package/dist/schemas/weather.schemas.js +32 -35
- package/package.json +9 -1
|
@@ -1,28 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const zod_1 = require("zod");
|
|
5
|
-
const common_schemas_1 = require("./common.schemas");
|
|
6
|
-
const recommendations_schemas_1 = require("./recommendations.schemas");
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { timestampsSchema, createJsonApiResourceSchema, jsonApiSingleResponseSchema, jsonApiCollectionResponseSchema, } from './common.schemas';
|
|
3
|
+
import { recommendationSchema } from './recommendations.schemas';
|
|
7
4
|
/**
|
|
8
5
|
* Field Observation schemas - JSON:API compliant
|
|
9
6
|
*/
|
|
10
7
|
// Observation attributes schema
|
|
11
|
-
|
|
12
|
-
fieldId:
|
|
13
|
-
farmId:
|
|
14
|
-
uploadedBy:
|
|
15
|
-
photoUrl:
|
|
16
|
-
photoThumbnail:
|
|
17
|
-
location:
|
|
8
|
+
export const observationAttributesSchema = z.object({
|
|
9
|
+
fieldId: z.string().uuid().nullable(),
|
|
10
|
+
farmId: z.string().uuid(),
|
|
11
|
+
uploadedBy: z.string().uuid(),
|
|
12
|
+
photoUrl: z.string().url(),
|
|
13
|
+
photoThumbnail: z.string().url().nullable(),
|
|
14
|
+
location: z
|
|
18
15
|
.object({
|
|
19
|
-
lat:
|
|
20
|
-
lng:
|
|
21
|
-
accuracy:
|
|
16
|
+
lat: z.number().min(-90).max(90),
|
|
17
|
+
lng: z.number().min(-180).max(180),
|
|
18
|
+
accuracy: z.number().positive().optional(),
|
|
22
19
|
})
|
|
23
20
|
.nullable(),
|
|
24
|
-
capturedAt:
|
|
25
|
-
observationType:
|
|
21
|
+
capturedAt: z.date(),
|
|
22
|
+
observationType: z.enum([
|
|
26
23
|
'disease',
|
|
27
24
|
'pest',
|
|
28
25
|
'nutrient',
|
|
@@ -30,8 +27,8 @@ exports.observationAttributesSchema = zod_1.z.object({
|
|
|
30
27
|
'general',
|
|
31
28
|
'health_check',
|
|
32
29
|
]),
|
|
33
|
-
userNotes:
|
|
34
|
-
cropStageAtTime:
|
|
30
|
+
userNotes: z.string().nullable(),
|
|
31
|
+
cropStageAtTime: z
|
|
35
32
|
.enum([
|
|
36
33
|
'planted',
|
|
37
34
|
'germination',
|
|
@@ -42,66 +39,66 @@ exports.observationAttributesSchema = zod_1.z.object({
|
|
|
42
39
|
'harvested',
|
|
43
40
|
])
|
|
44
41
|
.nullable(),
|
|
45
|
-
analysisStatus:
|
|
46
|
-
analysisCompletedAt:
|
|
47
|
-
identifiedCrop:
|
|
48
|
-
identifiedCropConfidence:
|
|
49
|
-
diagnosisType:
|
|
50
|
-
diagnosisConfidence:
|
|
51
|
-
severity:
|
|
52
|
-
affectedArea:
|
|
42
|
+
analysisStatus: z.enum(['pending', 'processing', 'completed', 'failed']),
|
|
43
|
+
analysisCompletedAt: z.date().nullable(),
|
|
44
|
+
identifiedCrop: z.string().nullable(),
|
|
45
|
+
identifiedCropConfidence: z.number().min(0).max(1).nullable(),
|
|
46
|
+
diagnosisType: z.string().nullable(),
|
|
47
|
+
diagnosisConfidence: z.number().min(0).max(1).nullable(),
|
|
48
|
+
severity: z.enum(['low', 'medium', 'high', 'critical']).nullable(),
|
|
49
|
+
affectedArea: z
|
|
53
50
|
.enum(['localized', 'widespread', 'entire_field'])
|
|
54
51
|
.nullable(),
|
|
55
|
-
healthScore:
|
|
56
|
-
analysisDetails:
|
|
52
|
+
healthScore: z.number().min(0).max(100).nullable(),
|
|
53
|
+
analysisDetails: z
|
|
57
54
|
.object({
|
|
58
|
-
plantIdentification:
|
|
55
|
+
plantIdentification: z
|
|
59
56
|
.object({
|
|
60
|
-
scientificName:
|
|
61
|
-
commonNames:
|
|
62
|
-
confidence:
|
|
63
|
-
provider:
|
|
57
|
+
scientificName: z.string(),
|
|
58
|
+
commonNames: z.array(z.string()),
|
|
59
|
+
confidence: z.number(),
|
|
60
|
+
provider: z.string(),
|
|
64
61
|
})
|
|
65
62
|
.optional(),
|
|
66
|
-
primaryIssue:
|
|
63
|
+
primaryIssue: z
|
|
67
64
|
.object({
|
|
68
|
-
name:
|
|
69
|
-
category:
|
|
70
|
-
confidence:
|
|
71
|
-
provider:
|
|
72
|
-
visualIndicators:
|
|
65
|
+
name: z.string(),
|
|
66
|
+
category: z.string(),
|
|
67
|
+
confidence: z.number(),
|
|
68
|
+
provider: z.string(),
|
|
69
|
+
visualIndicators: z.array(z.string()),
|
|
73
70
|
})
|
|
74
71
|
.optional(),
|
|
75
|
-
secondaryIssues:
|
|
76
|
-
.array(
|
|
77
|
-
name:
|
|
78
|
-
confidence:
|
|
79
|
-
reasoning:
|
|
72
|
+
secondaryIssues: z
|
|
73
|
+
.array(z.object({
|
|
74
|
+
name: z.string(),
|
|
75
|
+
confidence: z.number(),
|
|
76
|
+
reasoning: z.string(),
|
|
80
77
|
}))
|
|
81
78
|
.optional(),
|
|
82
|
-
environmentalFactors:
|
|
83
|
-
satelliteCorrelation:
|
|
84
|
-
historicalMatches:
|
|
79
|
+
environmentalFactors: z.record(z.string()).optional(),
|
|
80
|
+
satelliteCorrelation: z.record(z.any()).optional(),
|
|
81
|
+
historicalMatches: z.array(z.any()).optional(),
|
|
85
82
|
})
|
|
86
83
|
.nullable(),
|
|
87
|
-
recommendations:
|
|
88
|
-
estimatedCost:
|
|
89
|
-
urgencyScore:
|
|
90
|
-
similarCasesCount:
|
|
91
|
-
actionStatus:
|
|
92
|
-
actionTakenAt:
|
|
93
|
-
actionNotes:
|
|
94
|
-
generatedAlertId:
|
|
95
|
-
relatedTaskId:
|
|
96
|
-
analysisProvider:
|
|
97
|
-
processingTime:
|
|
98
|
-
modelVersion:
|
|
99
|
-
phase:
|
|
100
|
-
}).merge(
|
|
84
|
+
recommendations: z.array(recommendationSchema).nullable(),
|
|
85
|
+
estimatedCost: z.number().nullable(),
|
|
86
|
+
urgencyScore: z.number().min(1).max(10).nullable(),
|
|
87
|
+
similarCasesCount: z.number().nullable(),
|
|
88
|
+
actionStatus: z.enum(['pending', 'in_progress', 'completed', 'dismissed']),
|
|
89
|
+
actionTakenAt: z.date().nullable(),
|
|
90
|
+
actionNotes: z.string().nullable(),
|
|
91
|
+
generatedAlertId: z.string().uuid().nullable(),
|
|
92
|
+
relatedTaskId: z.string().uuid().nullable(),
|
|
93
|
+
analysisProvider: z.string().nullable(),
|
|
94
|
+
processingTime: z.number().nullable(),
|
|
95
|
+
modelVersion: z.string().nullable(),
|
|
96
|
+
phase: z.string().nullable(),
|
|
97
|
+
}).merge(timestampsSchema);
|
|
101
98
|
// Observation attributes for creation (input)
|
|
102
|
-
|
|
103
|
-
fieldId:
|
|
104
|
-
observationType:
|
|
99
|
+
export const createObservationAttributesSchema = z.object({
|
|
100
|
+
fieldId: z.string().uuid().optional(),
|
|
101
|
+
observationType: z.enum([
|
|
105
102
|
'disease',
|
|
106
103
|
'pest',
|
|
107
104
|
'nutrient',
|
|
@@ -109,8 +106,8 @@ exports.createObservationAttributesSchema = zod_1.z.object({
|
|
|
109
106
|
'general',
|
|
110
107
|
'health_check',
|
|
111
108
|
]),
|
|
112
|
-
userNotes:
|
|
113
|
-
cropStageAtTime:
|
|
109
|
+
userNotes: z.string().max(1000).optional(),
|
|
110
|
+
cropStageAtTime: z
|
|
114
111
|
.enum([
|
|
115
112
|
'planted',
|
|
116
113
|
'germination',
|
|
@@ -121,43 +118,43 @@ exports.createObservationAttributesSchema = zod_1.z.object({
|
|
|
121
118
|
'harvested',
|
|
122
119
|
])
|
|
123
120
|
.optional(),
|
|
124
|
-
location:
|
|
121
|
+
location: z
|
|
125
122
|
.object({
|
|
126
|
-
lat:
|
|
127
|
-
lng:
|
|
128
|
-
accuracy:
|
|
123
|
+
lat: z.number().min(-90).max(90),
|
|
124
|
+
lng: z.number().min(-180).max(180),
|
|
125
|
+
accuracy: z.number().positive().optional(),
|
|
129
126
|
})
|
|
130
127
|
.optional(),
|
|
131
|
-
capturedAt:
|
|
128
|
+
capturedAt: z.string().datetime().optional(),
|
|
132
129
|
});
|
|
133
130
|
// Observation attributes for update (input)
|
|
134
|
-
|
|
135
|
-
actionStatus:
|
|
136
|
-
actionNotes:
|
|
137
|
-
relatedTaskId:
|
|
131
|
+
export const updateObservationActionAttributesSchema = z.object({
|
|
132
|
+
actionStatus: z.enum(['in_progress', 'completed', 'dismissed']),
|
|
133
|
+
actionNotes: z.string().max(2000).optional(),
|
|
134
|
+
relatedTaskId: z.string().uuid().optional(),
|
|
138
135
|
});
|
|
139
136
|
// JSON:API resource schemas
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
photo:
|
|
137
|
+
export const observationResourceSchema = createJsonApiResourceSchema('observations', observationAttributesSchema);
|
|
138
|
+
export const createObservationInputSchema = createJsonApiResourceSchema('observations', createObservationAttributesSchema);
|
|
139
|
+
export const uploadObservationBodySchema = createObservationAttributesSchema.merge(z.object({
|
|
140
|
+
photo: z.any(),
|
|
144
141
|
}));
|
|
145
|
-
|
|
142
|
+
export const updateObservationActionInputSchema = createJsonApiResourceSchema('observations', updateObservationActionAttributesSchema);
|
|
146
143
|
// Response schemas
|
|
147
|
-
|
|
148
|
-
|
|
144
|
+
export const observationResponseSchema = jsonApiSingleResponseSchema(observationResourceSchema);
|
|
145
|
+
export const observationListResponseSchema = jsonApiCollectionResponseSchema(observationResourceSchema);
|
|
149
146
|
// Query schemas
|
|
150
|
-
|
|
151
|
-
fieldId:
|
|
152
|
-
status:
|
|
153
|
-
observationType:
|
|
154
|
-
severity:
|
|
155
|
-
startDate:
|
|
156
|
-
endDate:
|
|
157
|
-
page:
|
|
158
|
-
pageSize:
|
|
147
|
+
export const observationListQuerySchema = z.object({
|
|
148
|
+
fieldId: z.string().uuid().optional(),
|
|
149
|
+
status: z.enum(['pending', 'processing', 'completed', 'failed']).optional(),
|
|
150
|
+
observationType: z.string().optional(),
|
|
151
|
+
severity: z.enum(['low', 'medium', 'high', 'critical']).optional(),
|
|
152
|
+
startDate: z.string().datetime().optional(),
|
|
153
|
+
endDate: z.string().datetime().optional(),
|
|
154
|
+
page: z.string().default('1'),
|
|
155
|
+
pageSize: z.string().default('20'),
|
|
159
156
|
});
|
|
160
|
-
|
|
161
|
-
startDate:
|
|
162
|
-
endDate:
|
|
157
|
+
export const observationStatsQuerySchema = z.object({
|
|
158
|
+
startDate: z.string().datetime().optional(),
|
|
159
|
+
endDate: z.string().datetime().optional(),
|
|
163
160
|
});
|
|
@@ -1,125 +1,122 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.fieldListResponseSchema = exports.fieldDetailResponseSchema = exports.fieldResponseSchema = exports.fieldDetailResourceSchema = exports.fieldResourceSchema = exports.updateFieldSchema = exports.createFieldSchema = exports.updateFieldAttributesSchema = exports.createFieldAttributesSchema = exports.fieldAttributesSchema = exports.cropHistoryEntrySchema = exports.historicalDataPointSchema = exports.cropStageSchema = exports.fieldStatusSchema = void 0;
|
|
4
|
-
const zod_1 = require("zod");
|
|
5
|
-
const common_schemas_1 = require("./common.schemas");
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { geoJSONGeometrySchema, timestampsSchema, createJsonApiResourceSchema, jsonApiSingleResponseSchema, jsonApiCollectionResponseSchema } from './common.schemas';
|
|
6
3
|
/**
|
|
7
4
|
* Field schemas - JSON:API compliant
|
|
8
5
|
*/
|
|
9
6
|
// Field status enum
|
|
10
|
-
|
|
7
|
+
export const fieldStatusSchema = z.enum(['ok', 'alert', 'critical']);
|
|
11
8
|
// Crop stage enum
|
|
12
|
-
|
|
9
|
+
export const cropStageSchema = z.enum(['planted', 'growing', 'flowering', 'mature', 'harvested']);
|
|
13
10
|
// Historical data point (for NDVI, moisture trends)
|
|
14
|
-
|
|
15
|
-
date:
|
|
16
|
-
value:
|
|
11
|
+
export const historicalDataPointSchema = z.object({
|
|
12
|
+
date: z.string().datetime(),
|
|
13
|
+
value: z.number(),
|
|
17
14
|
});
|
|
18
15
|
// Crop history entry
|
|
19
|
-
|
|
20
|
-
id:
|
|
21
|
-
season:
|
|
22
|
-
crop:
|
|
23
|
-
plantingDate:
|
|
24
|
-
harvestDate:
|
|
25
|
-
yield:
|
|
26
|
-
yieldUnit:
|
|
16
|
+
export const cropHistoryEntrySchema = z.object({
|
|
17
|
+
id: z.string().uuid(),
|
|
18
|
+
season: z.string(), // e.g., "2024-2025"
|
|
19
|
+
crop: z.string(),
|
|
20
|
+
plantingDate: z.string().datetime(),
|
|
21
|
+
harvestDate: z.string().datetime().nullable(),
|
|
22
|
+
yield: z.number().nullable(),
|
|
23
|
+
yieldUnit: z.string().nullable(),
|
|
27
24
|
});
|
|
28
25
|
// Field attributes schema (for JSON:API attributes object)
|
|
29
|
-
|
|
30
|
-
name:
|
|
31
|
-
geometry:
|
|
32
|
-
ndvi:
|
|
33
|
-
moisture:
|
|
34
|
-
status:
|
|
35
|
-
area:
|
|
36
|
-
crop:
|
|
37
|
-
soilType:
|
|
26
|
+
export const fieldAttributesSchema = z.object({
|
|
27
|
+
name: z.string().min(1).max(200),
|
|
28
|
+
geometry: geoJSONGeometrySchema.nullable(),
|
|
29
|
+
ndvi: z.number().nullable(),
|
|
30
|
+
moisture: z.string().nullable(),
|
|
31
|
+
status: fieldStatusSchema,
|
|
32
|
+
area: z.string().nullable(), // Calculated from geometry, e.g., "50 Ha"
|
|
33
|
+
crop: z.string().nullable(),
|
|
34
|
+
soilType: z.string().nullable(),
|
|
38
35
|
// Crop lifecycle
|
|
39
|
-
currentCrop:
|
|
40
|
-
plantingDate:
|
|
41
|
-
expectedHarvestDate:
|
|
42
|
-
cropStage:
|
|
36
|
+
currentCrop: z.string().nullable(),
|
|
37
|
+
plantingDate: z.string().datetime().nullable(),
|
|
38
|
+
expectedHarvestDate: z.string().datetime().nullable(),
|
|
39
|
+
cropStage: cropStageSchema.nullable(),
|
|
43
40
|
// Historical data
|
|
44
|
-
historicalNdvi:
|
|
45
|
-
cropHistory:
|
|
46
|
-
}).merge(
|
|
41
|
+
historicalNdvi: z.array(historicalDataPointSchema).optional(),
|
|
42
|
+
cropHistory: z.array(cropHistoryEntrySchema).optional(),
|
|
43
|
+
}).merge(timestampsSchema);
|
|
47
44
|
// Field attributes for creation (input)
|
|
48
|
-
|
|
49
|
-
name:
|
|
50
|
-
geometry:
|
|
51
|
-
ndvi:
|
|
52
|
-
moisture:
|
|
53
|
-
crop:
|
|
54
|
-
soilType:
|
|
45
|
+
export const createFieldAttributesSchema = z.object({
|
|
46
|
+
name: z.string().min(1).max(200),
|
|
47
|
+
geometry: geoJSONGeometrySchema.optional(),
|
|
48
|
+
ndvi: z.number().min(0).max(1).optional(),
|
|
49
|
+
moisture: z.string().optional(),
|
|
50
|
+
crop: z.string().optional(),
|
|
51
|
+
soilType: z.string().optional(),
|
|
55
52
|
// Crop lifecycle fields
|
|
56
|
-
currentCrop:
|
|
57
|
-
plantingDate:
|
|
58
|
-
expectedHarvestDate:
|
|
59
|
-
cropStage:
|
|
53
|
+
currentCrop: z.string().optional(),
|
|
54
|
+
plantingDate: z.string().datetime().optional(),
|
|
55
|
+
expectedHarvestDate: z.string().datetime().optional(),
|
|
56
|
+
cropStage: cropStageSchema.optional(),
|
|
60
57
|
});
|
|
61
58
|
// Field attributes for update (input)
|
|
62
|
-
|
|
59
|
+
export const updateFieldAttributesSchema = createFieldAttributesSchema.partial();
|
|
63
60
|
// Create field input (JSON:API format)
|
|
64
|
-
|
|
65
|
-
type:
|
|
66
|
-
attributes:
|
|
67
|
-
relationships:
|
|
68
|
-
farm:
|
|
69
|
-
data:
|
|
70
|
-
type:
|
|
71
|
-
id:
|
|
61
|
+
export const createFieldSchema = z.object({
|
|
62
|
+
type: z.literal('fields'),
|
|
63
|
+
attributes: createFieldAttributesSchema,
|
|
64
|
+
relationships: z.object({
|
|
65
|
+
farm: z.object({
|
|
66
|
+
data: z.object({
|
|
67
|
+
type: z.literal('farms'),
|
|
68
|
+
id: z.string().uuid(),
|
|
72
69
|
}),
|
|
73
70
|
}),
|
|
74
71
|
}),
|
|
75
72
|
});
|
|
76
73
|
// Update field input (JSON:API format)
|
|
77
|
-
|
|
78
|
-
type:
|
|
79
|
-
id:
|
|
80
|
-
attributes:
|
|
74
|
+
export const updateFieldSchema = z.object({
|
|
75
|
+
type: z.literal('fields'),
|
|
76
|
+
id: z.string().uuid(),
|
|
77
|
+
attributes: updateFieldAttributesSchema,
|
|
81
78
|
});
|
|
82
79
|
// Field resource (JSON:API resource object)
|
|
83
|
-
|
|
80
|
+
export const fieldResourceSchema = createJsonApiResourceSchema('fields', fieldAttributesSchema);
|
|
84
81
|
// Field detail resource with relationships
|
|
85
|
-
|
|
86
|
-
relationships:
|
|
87
|
-
farm:
|
|
88
|
-
data:
|
|
89
|
-
type:
|
|
90
|
-
id:
|
|
82
|
+
export const fieldDetailResourceSchema = fieldResourceSchema.extend({
|
|
83
|
+
relationships: z.object({
|
|
84
|
+
farm: z.object({
|
|
85
|
+
data: z.object({
|
|
86
|
+
type: z.literal('farms'),
|
|
87
|
+
id: z.string().uuid(),
|
|
91
88
|
}),
|
|
92
|
-
links:
|
|
93
|
-
related:
|
|
89
|
+
links: z.object({
|
|
90
|
+
related: z.string(),
|
|
94
91
|
}),
|
|
95
92
|
}),
|
|
96
|
-
tasks:
|
|
97
|
-
meta:
|
|
98
|
-
count:
|
|
93
|
+
tasks: z.object({
|
|
94
|
+
meta: z.object({
|
|
95
|
+
count: z.number().int().nonnegative(),
|
|
99
96
|
}),
|
|
100
|
-
links:
|
|
101
|
-
related:
|
|
97
|
+
links: z.object({
|
|
98
|
+
related: z.string(),
|
|
102
99
|
}),
|
|
103
100
|
}).optional(),
|
|
104
|
-
harvests:
|
|
105
|
-
meta:
|
|
106
|
-
count:
|
|
101
|
+
harvests: z.object({
|
|
102
|
+
meta: z.object({
|
|
103
|
+
count: z.number().int().nonnegative(),
|
|
107
104
|
}),
|
|
108
|
-
links:
|
|
109
|
-
related:
|
|
105
|
+
links: z.object({
|
|
106
|
+
related: z.string(),
|
|
110
107
|
}),
|
|
111
108
|
}).optional(),
|
|
112
|
-
soilTests:
|
|
113
|
-
meta:
|
|
114
|
-
count:
|
|
109
|
+
soilTests: z.object({
|
|
110
|
+
meta: z.object({
|
|
111
|
+
count: z.number().int().nonnegative(),
|
|
115
112
|
}),
|
|
116
|
-
links:
|
|
117
|
-
related:
|
|
113
|
+
links: z.object({
|
|
114
|
+
related: z.string(),
|
|
118
115
|
}),
|
|
119
116
|
}).optional(),
|
|
120
117
|
}).optional(),
|
|
121
118
|
});
|
|
122
119
|
// Field responses (JSON:API format)
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
120
|
+
export const fieldResponseSchema = jsonApiSingleResponseSchema(fieldResourceSchema);
|
|
121
|
+
export const fieldDetailResponseSchema = jsonApiSingleResponseSchema(fieldDetailResourceSchema);
|
|
122
|
+
export const fieldListResponseSchema = jsonApiCollectionResponseSchema(fieldResourceSchema);
|