@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,278 +1,275 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.intelligentSoilProfileSchema = exports.longTermRecommendationSchema = exports.intelligentFertilizerRecommendationSchema = exports.seasonalRecommendationSchema = exports.soilRecommendationSchema = exports.completenessAssessmentSchema = exports.qualityAssessmentSchema = exports.dataSourceInfoSchema = exports.nutrientValueSchema = exports.historicalNDVIDataPointSchema = exports.soilTrendSchema = exports.soilReadingSchema = exports.fieldMonitoringErrorResponseSchema = exports.triggerAnalysisResponseSchema = exports.alertsQuerySchema = exports.ndviTrendQuerySchema = exports.farmMonitoringStatsSchema = exports.fieldComparisonSchema = exports.fieldAlertSchema = exports.weeklyNDVIStatsSchema = exports.ndviTrendDataPointSchema = exports.fieldMonitoringSummarySchema = void 0;
|
|
4
|
-
const zod_1 = require("zod");
|
|
5
|
-
const recommendations_schemas_1 = require("./recommendations.schemas");
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { recommendationSchema } from './recommendations.schemas';
|
|
6
3
|
// Field Monitoring Summary Schema
|
|
7
|
-
|
|
8
|
-
id:
|
|
9
|
-
fieldId:
|
|
10
|
-
fieldName:
|
|
11
|
-
latestDate:
|
|
12
|
-
currentNDVI:
|
|
13
|
-
currentNDWI:
|
|
14
|
-
currentEVI:
|
|
15
|
-
currentCropHealth:
|
|
4
|
+
export const fieldMonitoringSummarySchema = z.object({
|
|
5
|
+
id: z.string().uuid(),
|
|
6
|
+
fieldId: z.string().uuid(),
|
|
7
|
+
fieldName: z.string(),
|
|
8
|
+
latestDate: z.string().datetime(),
|
|
9
|
+
currentNDVI: z.number().min(-1).max(1).nullable(),
|
|
10
|
+
currentNDWI: z.number().min(-1).max(1).nullable(),
|
|
11
|
+
currentEVI: z.number().nullable(),
|
|
12
|
+
currentCropHealth: z
|
|
16
13
|
.enum(['poor', 'fair', 'good', 'excellent'])
|
|
17
14
|
.nullable(),
|
|
18
|
-
currentWaterStress:
|
|
15
|
+
currentWaterStress: z
|
|
19
16
|
.enum(['none', 'low', 'medium', 'high'])
|
|
20
17
|
.nullable(),
|
|
21
|
-
overallStatus:
|
|
22
|
-
activeAlertCount:
|
|
23
|
-
lastAlertDate:
|
|
24
|
-
dataQuality:
|
|
25
|
-
cloudCover:
|
|
26
|
-
lastProcessedAt:
|
|
18
|
+
overallStatus: z.enum(['ok', 'warning', 'critical']),
|
|
19
|
+
activeAlertCount: z.number(),
|
|
20
|
+
lastAlertDate: z.string().datetime().nullable(),
|
|
21
|
+
dataQuality: z.enum(['excellent', 'good', 'fair', 'poor']).nullable(),
|
|
22
|
+
cloudCover: z.number().nullable(),
|
|
23
|
+
lastProcessedAt: z.string().datetime(),
|
|
27
24
|
});
|
|
28
25
|
// NDVI Trend Data Point Schema
|
|
29
|
-
|
|
30
|
-
time:
|
|
31
|
-
ndvi:
|
|
32
|
-
cloudCover:
|
|
26
|
+
export const ndviTrendDataPointSchema = z.object({
|
|
27
|
+
time: z.string().datetime(),
|
|
28
|
+
ndvi: z.number().min(-1).max(1),
|
|
29
|
+
cloudCover: z.number(),
|
|
33
30
|
});
|
|
34
31
|
// Weekly NDVI Stats Schema
|
|
35
|
-
|
|
36
|
-
week:
|
|
37
|
-
avgNdvi:
|
|
38
|
-
maxNdvi:
|
|
39
|
-
minNdvi:
|
|
32
|
+
export const weeklyNDVIStatsSchema = z.object({
|
|
33
|
+
week: z.string().datetime(),
|
|
34
|
+
avgNdvi: z.number(),
|
|
35
|
+
maxNdvi: z.number(),
|
|
36
|
+
minNdvi: z.number(),
|
|
40
37
|
});
|
|
41
38
|
// Field Alert Schema
|
|
42
|
-
|
|
43
|
-
id:
|
|
44
|
-
fieldId:
|
|
45
|
-
fieldName:
|
|
46
|
-
type:
|
|
47
|
-
severity:
|
|
48
|
-
title:
|
|
49
|
-
message:
|
|
50
|
-
recommendations:
|
|
51
|
-
status:
|
|
52
|
-
acknowledgedAt:
|
|
53
|
-
acknowledgedBy:
|
|
54
|
-
resolvedAt:
|
|
55
|
-
confidence:
|
|
56
|
-
generatedBy:
|
|
57
|
-
createdAt:
|
|
39
|
+
export const fieldAlertSchema = z.object({
|
|
40
|
+
id: z.string().uuid(),
|
|
41
|
+
fieldId: z.string().uuid(),
|
|
42
|
+
fieldName: z.string().optional(),
|
|
43
|
+
type: z.string(),
|
|
44
|
+
severity: z.enum(['low', 'medium', 'high', 'critical']),
|
|
45
|
+
title: z.string(),
|
|
46
|
+
message: z.string(),
|
|
47
|
+
recommendations: z.array(recommendationSchema).nullable(),
|
|
48
|
+
status: z.enum(['active', 'acknowledged', 'resolved']),
|
|
49
|
+
acknowledgedAt: z.string().datetime().nullable(),
|
|
50
|
+
acknowledgedBy: z.string().nullable(),
|
|
51
|
+
resolvedAt: z.string().datetime().nullable(),
|
|
52
|
+
confidence: z.number().min(0).max(1).nullable(),
|
|
53
|
+
generatedBy: z.string(),
|
|
54
|
+
createdAt: z.string().datetime(),
|
|
58
55
|
});
|
|
59
56
|
// Field Comparison Schema
|
|
60
|
-
|
|
61
|
-
fieldId:
|
|
62
|
-
fieldName:
|
|
63
|
-
avgNDVI:
|
|
64
|
-
avgHealthScore:
|
|
65
|
-
rank:
|
|
57
|
+
export const fieldComparisonSchema = z.object({
|
|
58
|
+
fieldId: z.string().uuid(),
|
|
59
|
+
fieldName: z.string(),
|
|
60
|
+
avgNDVI: z.number(),
|
|
61
|
+
avgHealthScore: z.number(),
|
|
62
|
+
rank: z.number(),
|
|
66
63
|
});
|
|
67
64
|
// Farm Monitoring Stats Schema
|
|
68
|
-
|
|
69
|
-
totalFields:
|
|
70
|
-
healthyFields:
|
|
71
|
-
warningFields:
|
|
72
|
-
criticalFields:
|
|
73
|
-
avgNDVI:
|
|
74
|
-
totalActiveAlerts:
|
|
65
|
+
export const farmMonitoringStatsSchema = z.object({
|
|
66
|
+
totalFields: z.number(),
|
|
67
|
+
healthyFields: z.number(),
|
|
68
|
+
warningFields: z.number(),
|
|
69
|
+
criticalFields: z.number(),
|
|
70
|
+
avgNDVI: z.number(),
|
|
71
|
+
totalActiveAlerts: z.number(),
|
|
75
72
|
});
|
|
76
73
|
// Query Schemas
|
|
77
|
-
|
|
78
|
-
startDate:
|
|
79
|
-
endDate:
|
|
80
|
-
interval:
|
|
74
|
+
export const ndviTrendQuerySchema = z.object({
|
|
75
|
+
startDate: z.string().datetime(),
|
|
76
|
+
endDate: z.string().datetime(),
|
|
77
|
+
interval: z.enum(['daily', 'weekly']).default('daily'),
|
|
81
78
|
});
|
|
82
|
-
|
|
83
|
-
status:
|
|
79
|
+
export const alertsQuerySchema = z.object({
|
|
80
|
+
status: z.enum(['active', 'acknowledged', 'resolved']).optional(),
|
|
84
81
|
});
|
|
85
82
|
// Response Schemas
|
|
86
|
-
|
|
87
|
-
message:
|
|
88
|
-
jobId:
|
|
89
|
-
nextAvailableAt:
|
|
83
|
+
export const triggerAnalysisResponseSchema = z.object({
|
|
84
|
+
message: z.string(),
|
|
85
|
+
jobId: z.string().nullable(),
|
|
86
|
+
nextAvailableAt: z.string().datetime().optional(),
|
|
90
87
|
});
|
|
91
|
-
|
|
92
|
-
message:
|
|
93
|
-
code:
|
|
88
|
+
export const fieldMonitoringErrorResponseSchema = z.object({
|
|
89
|
+
message: z.string(),
|
|
90
|
+
code: z.string().optional(),
|
|
94
91
|
});
|
|
95
92
|
// Soil Monitoring Schemas
|
|
96
|
-
|
|
97
|
-
readingDate:
|
|
98
|
-
soilMoisture:
|
|
99
|
-
surfaceTemp:
|
|
100
|
-
temp10cm:
|
|
93
|
+
export const soilReadingSchema = z.object({
|
|
94
|
+
readingDate: z.string().datetime(),
|
|
95
|
+
soilMoisture: z.number().min(0).max(1).nullable(), // m³/m³
|
|
96
|
+
surfaceTemp: z.number().nullable(), // Kelvins
|
|
97
|
+
temp10cm: z.number().nullable(), // Kelvins
|
|
101
98
|
});
|
|
102
|
-
|
|
103
|
-
fieldId:
|
|
104
|
-
fieldName:
|
|
105
|
-
readings:
|
|
106
|
-
avgMoisture:
|
|
107
|
-
moistureTrend:
|
|
108
|
-
lastReadingDate:
|
|
99
|
+
export const soilTrendSchema = z.object({
|
|
100
|
+
fieldId: z.string().uuid(),
|
|
101
|
+
fieldName: z.string(),
|
|
102
|
+
readings: z.array(soilReadingSchema),
|
|
103
|
+
avgMoisture: z.number().nullable(),
|
|
104
|
+
moistureTrend: z.enum(['increasing', 'stable', 'decreasing']).nullable(),
|
|
105
|
+
lastReadingDate: z.string().datetime().nullable(),
|
|
109
106
|
});
|
|
110
107
|
// Historical NDVI Schemas
|
|
111
|
-
|
|
112
|
-
date:
|
|
113
|
-
time:
|
|
114
|
-
ndvi:
|
|
115
|
-
source:
|
|
116
|
-
cloudCoverage:
|
|
117
|
-
imageCoverage:
|
|
108
|
+
export const historicalNDVIDataPointSchema = z.object({
|
|
109
|
+
date: z.string().datetime(),
|
|
110
|
+
time: z.string().datetime().optional(), // Also include 'time' for consistency with NDVI trend endpoint
|
|
111
|
+
ndvi: z.number().min(-1).max(1),
|
|
112
|
+
source: z.enum(['sentinel-2', 'landsat-8', 'modis']),
|
|
113
|
+
cloudCoverage: z.number().min(0).max(100),
|
|
114
|
+
imageCoverage: z.number().min(0).max(100),
|
|
118
115
|
});
|
|
119
116
|
// Intelligent Soil Profile Schemas
|
|
120
|
-
|
|
121
|
-
value:
|
|
122
|
-
unit:
|
|
123
|
-
source:
|
|
124
|
-
confidence:
|
|
125
|
-
lastUpdated:
|
|
126
|
-
sourceId:
|
|
117
|
+
export const nutrientValueSchema = z.object({
|
|
118
|
+
value: z.number().nullable(),
|
|
119
|
+
unit: z.enum(['ppm', 'kg/ha', 'g/kg', '%', 'cmol(c)/kg']),
|
|
120
|
+
source: z.enum(['manual', 'regional_api', 'global_api', 'predicted']),
|
|
121
|
+
confidence: z.number().min(0).max(1),
|
|
122
|
+
lastUpdated: z.string().datetime(),
|
|
123
|
+
sourceId: z.string().optional(),
|
|
127
124
|
});
|
|
128
|
-
|
|
129
|
-
source:
|
|
130
|
-
sourceId:
|
|
131
|
-
priority:
|
|
132
|
-
confidence:
|
|
133
|
-
date:
|
|
134
|
-
notes:
|
|
125
|
+
export const dataSourceInfoSchema = z.object({
|
|
126
|
+
source: z.enum(['manual', 'regional_api', 'global_api', 'predicted']),
|
|
127
|
+
sourceId: z.string().optional(),
|
|
128
|
+
priority: z.number().min(1).max(4),
|
|
129
|
+
confidence: z.number().min(0).max(1),
|
|
130
|
+
date: z.string().datetime(),
|
|
131
|
+
notes: z.string().optional(),
|
|
135
132
|
});
|
|
136
|
-
|
|
137
|
-
quality:
|
|
138
|
-
recommendation:
|
|
139
|
-
optimalRange:
|
|
133
|
+
export const qualityAssessmentSchema = z.object({
|
|
134
|
+
quality: z.enum(['excellent', 'good', 'fair', 'poor', 'critical']),
|
|
135
|
+
recommendation: z.string(),
|
|
136
|
+
optimalRange: z
|
|
140
137
|
.object({
|
|
141
|
-
min:
|
|
142
|
-
max:
|
|
138
|
+
min: z.number(),
|
|
139
|
+
max: z.number(),
|
|
143
140
|
})
|
|
144
141
|
.optional(),
|
|
145
|
-
currentStatus:
|
|
142
|
+
currentStatus: z.enum(['optimal', 'low', 'high', 'critical']),
|
|
146
143
|
});
|
|
147
|
-
|
|
148
|
-
score:
|
|
149
|
-
missingFields:
|
|
150
|
-
completeness:
|
|
144
|
+
export const completenessAssessmentSchema = z.object({
|
|
145
|
+
score: z.number().min(0).max(1),
|
|
146
|
+
missingFields: z.array(z.string()),
|
|
147
|
+
completeness: z.enum(['complete', 'mostly_complete', 'partial', 'incomplete']),
|
|
151
148
|
});
|
|
152
|
-
|
|
153
|
-
priority:
|
|
154
|
-
action:
|
|
155
|
-
details:
|
|
156
|
-
timing:
|
|
157
|
-
severity:
|
|
158
|
-
confidence:
|
|
149
|
+
export const soilRecommendationSchema = z.object({
|
|
150
|
+
priority: z.number().min(1).max(5),
|
|
151
|
+
action: z.string(),
|
|
152
|
+
details: z.string(),
|
|
153
|
+
timing: z.string(),
|
|
154
|
+
severity: z.enum(['low', 'medium', 'high', 'critical']).optional(),
|
|
155
|
+
confidence: z.number().min(0).max(1).optional(),
|
|
159
156
|
});
|
|
160
|
-
|
|
161
|
-
priority:
|
|
162
|
-
action:
|
|
163
|
-
details:
|
|
164
|
-
timing:
|
|
165
|
-
confidence:
|
|
157
|
+
export const seasonalRecommendationSchema = z.object({
|
|
158
|
+
priority: z.number().min(1).max(5),
|
|
159
|
+
action: z.string(),
|
|
160
|
+
details: z.string(),
|
|
161
|
+
timing: z.string(),
|
|
162
|
+
confidence: z.number().min(0).max(1).optional(),
|
|
166
163
|
});
|
|
167
|
-
|
|
168
|
-
inventoryItemId:
|
|
169
|
-
productName:
|
|
170
|
-
quantity:
|
|
171
|
-
unit:
|
|
172
|
-
reason:
|
|
173
|
-
estimatedCost:
|
|
174
|
-
applicationTiming:
|
|
175
|
-
confidence:
|
|
164
|
+
export const intelligentFertilizerRecommendationSchema = z.object({
|
|
165
|
+
inventoryItemId: z.string().uuid().optional(),
|
|
166
|
+
productName: z.string().optional(),
|
|
167
|
+
quantity: z.number(),
|
|
168
|
+
unit: z.string(),
|
|
169
|
+
reason: z.string(),
|
|
170
|
+
estimatedCost: z.number().optional(),
|
|
171
|
+
applicationTiming: z.string().optional(),
|
|
172
|
+
confidence: z.number().min(0).max(1).optional(),
|
|
176
173
|
});
|
|
177
|
-
|
|
178
|
-
priority:
|
|
179
|
-
action:
|
|
180
|
-
details:
|
|
181
|
-
timeframe:
|
|
182
|
-
expectedImpact:
|
|
183
|
-
confidence:
|
|
174
|
+
export const longTermRecommendationSchema = z.object({
|
|
175
|
+
priority: z.number().min(1).max(5),
|
|
176
|
+
action: z.string(),
|
|
177
|
+
details: z.string(),
|
|
178
|
+
timeframe: z.string(),
|
|
179
|
+
expectedImpact: z.string(),
|
|
180
|
+
confidence: z.number().min(0).max(1).optional(),
|
|
184
181
|
});
|
|
185
|
-
|
|
186
|
-
fieldId:
|
|
187
|
-
fieldName:
|
|
188
|
-
coordinates:
|
|
189
|
-
latitude:
|
|
190
|
-
longitude:
|
|
182
|
+
export const intelligentSoilProfileSchema = z.object({
|
|
183
|
+
fieldId: z.string().uuid(),
|
|
184
|
+
fieldName: z.string(),
|
|
185
|
+
coordinates: z.object({
|
|
186
|
+
latitude: z.number(),
|
|
187
|
+
longitude: z.number(),
|
|
191
188
|
}),
|
|
192
|
-
nutrients:
|
|
193
|
-
pH:
|
|
194
|
-
nitrogen:
|
|
195
|
-
phosphorus:
|
|
196
|
-
potassium:
|
|
197
|
-
organicMatter:
|
|
198
|
-
organicCarbon:
|
|
199
|
-
cec:
|
|
189
|
+
nutrients: z.object({
|
|
190
|
+
pH: nutrientValueSchema,
|
|
191
|
+
nitrogen: nutrientValueSchema,
|
|
192
|
+
phosphorus: nutrientValueSchema,
|
|
193
|
+
potassium: nutrientValueSchema,
|
|
194
|
+
organicMatter: nutrientValueSchema,
|
|
195
|
+
organicCarbon: nutrientValueSchema,
|
|
196
|
+
cec: nutrientValueSchema,
|
|
200
197
|
}),
|
|
201
|
-
properties:
|
|
202
|
-
texture:
|
|
203
|
-
sand:
|
|
204
|
-
silt:
|
|
205
|
-
clay:
|
|
206
|
-
classification:
|
|
198
|
+
properties: z.object({
|
|
199
|
+
texture: z.object({
|
|
200
|
+
sand: z.number(),
|
|
201
|
+
silt: z.number(),
|
|
202
|
+
clay: z.number(),
|
|
203
|
+
classification: z.string(),
|
|
207
204
|
}),
|
|
208
|
-
bulkDensity:
|
|
205
|
+
bulkDensity: z.number(),
|
|
209
206
|
}),
|
|
210
|
-
dataSources:
|
|
211
|
-
quality:
|
|
212
|
-
overall:
|
|
213
|
-
score:
|
|
214
|
-
assessments:
|
|
215
|
-
pH:
|
|
216
|
-
organicMatter:
|
|
217
|
-
completeness:
|
|
207
|
+
dataSources: z.record(z.string(), dataSourceInfoSchema),
|
|
208
|
+
quality: z.object({
|
|
209
|
+
overall: z.enum(['excellent', 'good', 'fair', 'poor', 'critical']),
|
|
210
|
+
score: z.number().min(0).max(1),
|
|
211
|
+
assessments: z.object({
|
|
212
|
+
pH: qualityAssessmentSchema,
|
|
213
|
+
organicMatter: qualityAssessmentSchema,
|
|
214
|
+
completeness: completenessAssessmentSchema,
|
|
218
215
|
}),
|
|
219
216
|
}),
|
|
220
|
-
temporal:
|
|
221
|
-
latestUpdate:
|
|
222
|
-
testHistory:
|
|
223
|
-
id:
|
|
224
|
-
date:
|
|
225
|
-
pH:
|
|
226
|
-
nitrogen:
|
|
227
|
-
phosphorus:
|
|
228
|
-
potassium:
|
|
217
|
+
temporal: z.object({
|
|
218
|
+
latestUpdate: z.string().datetime(),
|
|
219
|
+
testHistory: z.array(z.object({
|
|
220
|
+
id: z.string().uuid(),
|
|
221
|
+
date: z.string().datetime(),
|
|
222
|
+
pH: z.number(),
|
|
223
|
+
nitrogen: z.number().nullable(),
|
|
224
|
+
phosphorus: z.number().nullable(),
|
|
225
|
+
potassium: z.number().nullable(),
|
|
229
226
|
})),
|
|
230
|
-
trends:
|
|
227
|
+
trends: z
|
|
231
228
|
.object({
|
|
232
|
-
pH:
|
|
229
|
+
pH: z
|
|
233
230
|
.object({
|
|
234
|
-
direction:
|
|
235
|
-
rate:
|
|
231
|
+
direction: z.enum(['increasing', 'decreasing', 'stable']),
|
|
232
|
+
rate: z.number(),
|
|
236
233
|
})
|
|
237
234
|
.optional(),
|
|
238
|
-
nitrogen:
|
|
235
|
+
nitrogen: z
|
|
239
236
|
.object({
|
|
240
|
-
direction:
|
|
241
|
-
rate:
|
|
237
|
+
direction: z.enum(['increasing', 'decreasing', 'stable']),
|
|
238
|
+
rate: z.number(),
|
|
242
239
|
})
|
|
243
240
|
.optional(),
|
|
244
|
-
phosphorus:
|
|
241
|
+
phosphorus: z
|
|
245
242
|
.object({
|
|
246
|
-
direction:
|
|
247
|
-
rate:
|
|
243
|
+
direction: z.enum(['increasing', 'decreasing', 'stable']),
|
|
244
|
+
rate: z.number(),
|
|
248
245
|
})
|
|
249
246
|
.optional(),
|
|
250
|
-
potassium:
|
|
247
|
+
potassium: z
|
|
251
248
|
.object({
|
|
252
|
-
direction:
|
|
253
|
-
rate:
|
|
249
|
+
direction: z.enum(['increasing', 'decreasing', 'stable']),
|
|
250
|
+
rate: z.number(),
|
|
254
251
|
})
|
|
255
252
|
.optional(),
|
|
256
|
-
organicMatter:
|
|
253
|
+
organicMatter: z
|
|
257
254
|
.object({
|
|
258
|
-
direction:
|
|
259
|
-
rate:
|
|
255
|
+
direction: z.enum(['increasing', 'decreasing', 'stable']),
|
|
256
|
+
rate: z.number(),
|
|
260
257
|
})
|
|
261
258
|
.optional(),
|
|
262
259
|
})
|
|
263
260
|
.optional(),
|
|
264
261
|
}),
|
|
265
|
-
recommendations:
|
|
266
|
-
immediate:
|
|
267
|
-
seasonal:
|
|
268
|
-
fertilizer:
|
|
269
|
-
longTerm:
|
|
270
|
-
summary:
|
|
262
|
+
recommendations: z.object({
|
|
263
|
+
immediate: z.array(soilRecommendationSchema),
|
|
264
|
+
seasonal: z.array(seasonalRecommendationSchema),
|
|
265
|
+
fertilizer: z.array(intelligentFertilizerRecommendationSchema),
|
|
266
|
+
longTerm: z.array(longTermRecommendationSchema).optional(),
|
|
267
|
+
summary: z.string().optional(),
|
|
271
268
|
}),
|
|
272
|
-
metadata:
|
|
273
|
-
confidence:
|
|
274
|
-
completeness:
|
|
275
|
-
lastValidated:
|
|
276
|
-
nextRecommendedTest:
|
|
269
|
+
metadata: z.object({
|
|
270
|
+
confidence: z.number().min(0).max(1),
|
|
271
|
+
completeness: z.number().min(0).max(1),
|
|
272
|
+
lastValidated: z.string().datetime(),
|
|
273
|
+
nextRecommendedTest: z.string().datetime().optional(),
|
|
277
274
|
}),
|
|
278
275
|
});
|