@deepintel-ltd/farmpro-contracts 1.5.8 → 1.5.9
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.js +70 -73
- 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.js +57 -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,66 +1,63 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.farmListResponseSchema = exports.farmDetailResponseSchema = exports.farmResponseSchema = exports.farmDetailResourceSchema = exports.farmResourceSchema = exports.updateFarmSchema = exports.createFarmSchema = exports.updateFarmAttributesSchema = exports.createFarmAttributesSchema = exports.farmAttributesSchema = exports.currencySchema = 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
|
* Farm schemas - JSON:API compliant
|
|
8
5
|
*/
|
|
9
6
|
// Currency enum for supported currencies
|
|
10
|
-
|
|
7
|
+
export const currencySchema = z.enum(['NGN', 'USD']);
|
|
11
8
|
// Farm attributes schema (for JSON:API attributes object)
|
|
12
|
-
|
|
13
|
-
name:
|
|
14
|
-
location:
|
|
15
|
-
size:
|
|
16
|
-
boundary:
|
|
17
|
-
currency:
|
|
18
|
-
}).merge(
|
|
9
|
+
export const farmAttributesSchema = z.object({
|
|
10
|
+
name: z.string().min(1).max(100),
|
|
11
|
+
location: z.string(),
|
|
12
|
+
size: z.number().nullable(),
|
|
13
|
+
boundary: geoJSONGeometrySchema.nullable(),
|
|
14
|
+
currency: currencySchema,
|
|
15
|
+
}).merge(timestampsSchema);
|
|
19
16
|
// Farm attributes for creation (input)
|
|
20
|
-
|
|
21
|
-
name:
|
|
22
|
-
location:
|
|
23
|
-
size:
|
|
24
|
-
boundary:
|
|
25
|
-
currency:
|
|
17
|
+
export const createFarmAttributesSchema = z.object({
|
|
18
|
+
name: z.string().min(1).max(100),
|
|
19
|
+
location: z.string().min(1),
|
|
20
|
+
size: z.number().positive().optional(),
|
|
21
|
+
boundary: geoJSONGeometrySchema.optional(),
|
|
22
|
+
currency: currencySchema.optional().default('NGN'),
|
|
26
23
|
});
|
|
27
24
|
// Farm attributes for update (input)
|
|
28
|
-
|
|
25
|
+
export const updateFarmAttributesSchema = createFarmAttributesSchema.partial();
|
|
29
26
|
// Create farm input (JSON:API format)
|
|
30
|
-
|
|
31
|
-
type:
|
|
32
|
-
attributes:
|
|
27
|
+
export const createFarmSchema = z.object({
|
|
28
|
+
type: z.literal('farms'),
|
|
29
|
+
attributes: createFarmAttributesSchema,
|
|
33
30
|
});
|
|
34
31
|
// Update farm input (JSON:API format)
|
|
35
|
-
|
|
36
|
-
type:
|
|
37
|
-
id:
|
|
38
|
-
attributes:
|
|
32
|
+
export const updateFarmSchema = z.object({
|
|
33
|
+
type: z.literal('farms'),
|
|
34
|
+
id: z.string().uuid(),
|
|
35
|
+
attributes: updateFarmAttributesSchema,
|
|
39
36
|
});
|
|
40
37
|
// Farm resource (JSON:API resource object)
|
|
41
|
-
|
|
38
|
+
export const farmResourceSchema = createJsonApiResourceSchema('farms', farmAttributesSchema);
|
|
42
39
|
// Farm detail resource with relationships
|
|
43
|
-
|
|
44
|
-
relationships:
|
|
45
|
-
fields:
|
|
46
|
-
meta:
|
|
47
|
-
count:
|
|
40
|
+
export const farmDetailResourceSchema = farmResourceSchema.extend({
|
|
41
|
+
relationships: z.object({
|
|
42
|
+
fields: z.object({
|
|
43
|
+
meta: z.object({
|
|
44
|
+
count: z.number().int().nonnegative(),
|
|
48
45
|
}),
|
|
49
|
-
links:
|
|
50
|
-
related:
|
|
46
|
+
links: z.object({
|
|
47
|
+
related: z.string(),
|
|
51
48
|
}),
|
|
52
49
|
}).optional(),
|
|
53
|
-
team:
|
|
54
|
-
meta:
|
|
55
|
-
count:
|
|
50
|
+
team: z.object({
|
|
51
|
+
meta: z.object({
|
|
52
|
+
count: z.number().int().nonnegative(),
|
|
56
53
|
}),
|
|
57
|
-
links:
|
|
58
|
-
related:
|
|
54
|
+
links: z.object({
|
|
55
|
+
related: z.string(),
|
|
59
56
|
}),
|
|
60
57
|
}).optional(),
|
|
61
58
|
}).optional(),
|
|
62
59
|
});
|
|
63
60
|
// Farm responses (JSON:API format)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
export const farmResponseSchema = jsonApiSingleResponseSchema(farmResourceSchema);
|
|
62
|
+
export const farmDetailResponseSchema = jsonApiSingleResponseSchema(farmDetailResourceSchema);
|
|
63
|
+
export const farmListResponseSchema = jsonApiCollectionResponseSchema(farmResourceSchema);
|
|
@@ -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
|
});
|