@deepintel-ltd/farmpro-contracts 1.5.7 → 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,122 +1,116 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.dateRangeQuerySchema = exports.paginationQuerySchema = exports.errorResponseSchema = exports.createJsonApiResourceSchema = exports.timestampsSchema = exports.idParamSchema = exports.jsonApiSuccessResponseSchema = exports.jsonApiErrorResponseSchema = exports.jsonApiErrorSchema = exports.jsonApiIncludeQuerySchema = exports.jsonApiFieldsQuerySchema = exports.jsonApiFilterQuerySchema = exports.jsonApiSortQuerySchema = exports.jsonApiPaginationMetaSchema = exports.jsonApiPaginationLinksSchema = exports.jsonApiPaginationQuerySchema = exports.jsonApiCollectionResponseSchema = exports.jsonApiSingleResponseSchema = exports.jsonApiResourceSchema = exports.geoJSONGeometrySchema = void 0;
|
|
4
|
-
const zod_1 = require("zod");
|
|
1
|
+
import { z } from 'zod';
|
|
5
2
|
/**
|
|
6
3
|
* Common schemas used across all API contracts - JSON:API compliant
|
|
7
4
|
*/
|
|
8
5
|
// GeoJSON Geometry Schema (Polygon, MultiPolygon, Point, LineString)
|
|
9
|
-
|
|
10
|
-
type:
|
|
11
|
-
coordinates:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
export const geoJSONGeometrySchema = z.object({
|
|
7
|
+
type: z.enum(['Polygon', 'MultiPolygon', 'Point', 'LineString']),
|
|
8
|
+
coordinates: z.union([
|
|
9
|
+
z.array(z.array(z.array(z.number()))), // Polygon: [[[lng, lat], ...]]
|
|
10
|
+
z.array(z.array(z.array(z.array(z.number())))), // MultiPolygon: [[[[lng, lat], ...]]]
|
|
11
|
+
z.array(z.number()), // Point: [lng, lat]
|
|
12
|
+
z.array(z.array(z.number())), // LineString: [[lng, lat], ...]
|
|
16
13
|
]),
|
|
17
14
|
});
|
|
18
15
|
// JSON:API Resource Object Base
|
|
19
|
-
|
|
20
|
-
type:
|
|
21
|
-
id:
|
|
22
|
-
attributes:
|
|
23
|
-
relationships:
|
|
24
|
-
links:
|
|
25
|
-
meta:
|
|
16
|
+
export const jsonApiResourceSchema = z.object({
|
|
17
|
+
type: z.string(),
|
|
18
|
+
id: z.string(),
|
|
19
|
+
attributes: z.record(z.unknown()).optional(),
|
|
20
|
+
relationships: z.record(z.unknown()).optional(),
|
|
21
|
+
links: z.record(z.string()).optional(),
|
|
22
|
+
meta: z.record(z.unknown()).optional(),
|
|
26
23
|
});
|
|
27
24
|
// JSON:API Single Resource Response
|
|
28
|
-
const jsonApiSingleResponseSchema = (resourceSchema) =>
|
|
25
|
+
export const jsonApiSingleResponseSchema = (resourceSchema) => z.object({
|
|
29
26
|
data: resourceSchema,
|
|
30
|
-
included:
|
|
31
|
-
meta:
|
|
32
|
-
links:
|
|
27
|
+
included: z.array(jsonApiResourceSchema).optional(),
|
|
28
|
+
meta: z.record(z.unknown()).optional(),
|
|
29
|
+
links: z.record(z.string()).optional(),
|
|
33
30
|
});
|
|
34
|
-
exports.jsonApiSingleResponseSchema = jsonApiSingleResponseSchema;
|
|
35
31
|
// JSON:API Collection Response
|
|
36
|
-
const jsonApiCollectionResponseSchema = (resourceSchema) =>
|
|
37
|
-
data:
|
|
38
|
-
included:
|
|
39
|
-
meta:
|
|
40
|
-
links:
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
'page[
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
'filter[
|
|
65
|
-
'filter[
|
|
66
|
-
'filter[
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
zod_1.z.string() // comma-separated field names
|
|
32
|
+
export const jsonApiCollectionResponseSchema = (resourceSchema) => z.object({
|
|
33
|
+
data: z.array(resourceSchema),
|
|
34
|
+
included: z.array(jsonApiResourceSchema).optional(),
|
|
35
|
+
meta: z.record(z.unknown()).optional(),
|
|
36
|
+
links: z.record(z.string()).optional(),
|
|
37
|
+
});
|
|
38
|
+
export const jsonApiPaginationQuerySchema = z.object({
|
|
39
|
+
'page[number]': z.coerce.number().int().positive().default(1).optional(),
|
|
40
|
+
'page[size]': z.coerce.number().int().positive().max(100).default(20).optional(),
|
|
41
|
+
});
|
|
42
|
+
export const jsonApiPaginationLinksSchema = z.object({
|
|
43
|
+
first: z.string().optional(),
|
|
44
|
+
last: z.string().optional(),
|
|
45
|
+
prev: z.string().optional(),
|
|
46
|
+
next: z.string().optional(),
|
|
47
|
+
self: z.string(),
|
|
48
|
+
});
|
|
49
|
+
export const jsonApiPaginationMetaSchema = z.object({
|
|
50
|
+
totalRecords: z.number().int().nonnegative(),
|
|
51
|
+
totalPages: z.number().int().nonnegative(),
|
|
52
|
+
currentPage: z.number().int().positive(),
|
|
53
|
+
pageSize: z.number().int().positive(),
|
|
54
|
+
});
|
|
55
|
+
export const jsonApiSortQuerySchema = z.object({
|
|
56
|
+
sort: z.string().optional(), // e.g., "name,-createdAt"
|
|
57
|
+
});
|
|
58
|
+
export const jsonApiFilterQuerySchema = z.object({
|
|
59
|
+
'filter[startDate]': z.string().datetime().optional(),
|
|
60
|
+
'filter[endDate]': z.string().datetime().optional(),
|
|
61
|
+
'filter[status]': z.string().optional(),
|
|
62
|
+
'filter[crop]': z.string().optional(),
|
|
63
|
+
});
|
|
64
|
+
export const jsonApiFieldsQuerySchema = z.record(z.string(), // resource type
|
|
65
|
+
z.string() // comma-separated field names
|
|
71
66
|
).optional();
|
|
72
|
-
|
|
73
|
-
include:
|
|
67
|
+
export const jsonApiIncludeQuerySchema = z.object({
|
|
68
|
+
include: z.string().optional(), // e.g., "fields,team"
|
|
74
69
|
});
|
|
75
|
-
|
|
76
|
-
id:
|
|
77
|
-
links:
|
|
78
|
-
about:
|
|
70
|
+
export const jsonApiErrorSchema = z.object({
|
|
71
|
+
id: z.string().optional(),
|
|
72
|
+
links: z.object({
|
|
73
|
+
about: z.string().optional(),
|
|
79
74
|
}).optional(),
|
|
80
|
-
status:
|
|
81
|
-
code:
|
|
82
|
-
title:
|
|
83
|
-
detail:
|
|
84
|
-
source:
|
|
85
|
-
pointer:
|
|
86
|
-
parameter:
|
|
75
|
+
status: z.string().optional(), // HTTP status code as string
|
|
76
|
+
code: z.string().optional(), // Application-specific error code
|
|
77
|
+
title: z.string().optional(), // Short, human-readable summary
|
|
78
|
+
detail: z.string().optional(), // Human-readable explanation
|
|
79
|
+
source: z.object({
|
|
80
|
+
pointer: z.string().optional(), // JSON Pointer to associated field
|
|
81
|
+
parameter: z.string().optional(), // Query parameter that caused the error
|
|
87
82
|
}).optional(),
|
|
88
|
-
meta:
|
|
83
|
+
meta: z.record(z.unknown()).optional(),
|
|
89
84
|
});
|
|
90
|
-
|
|
91
|
-
errors:
|
|
92
|
-
meta:
|
|
85
|
+
export const jsonApiErrorResponseSchema = z.object({
|
|
86
|
+
errors: z.array(jsonApiErrorSchema),
|
|
87
|
+
meta: z.record(z.unknown()).optional(),
|
|
93
88
|
});
|
|
94
|
-
|
|
95
|
-
meta:
|
|
96
|
-
message:
|
|
89
|
+
export const jsonApiSuccessResponseSchema = z.object({
|
|
90
|
+
meta: z.object({
|
|
91
|
+
message: z.string(),
|
|
97
92
|
}),
|
|
98
93
|
});
|
|
99
|
-
|
|
100
|
-
id:
|
|
94
|
+
export const idParamSchema = z.object({
|
|
95
|
+
id: z.string().uuid(),
|
|
101
96
|
});
|
|
102
|
-
|
|
103
|
-
createdAt:
|
|
104
|
-
updatedAt:
|
|
97
|
+
export const timestampsSchema = z.object({
|
|
98
|
+
createdAt: z.string().datetime(),
|
|
99
|
+
updatedAt: z.string().datetime(),
|
|
105
100
|
});
|
|
106
101
|
// Helper to create a JSON:API resource schema
|
|
107
|
-
const createJsonApiResourceSchema = (resourceType, attributesSchema) =>
|
|
108
|
-
type:
|
|
109
|
-
id:
|
|
102
|
+
export const createJsonApiResourceSchema = (resourceType, attributesSchema) => z.object({
|
|
103
|
+
type: z.literal(resourceType),
|
|
104
|
+
id: z.string(),
|
|
110
105
|
attributes: attributesSchema,
|
|
111
|
-
relationships:
|
|
112
|
-
links:
|
|
113
|
-
meta:
|
|
106
|
+
relationships: z.record(z.unknown()).optional(),
|
|
107
|
+
links: z.record(z.string()).optional(),
|
|
108
|
+
meta: z.record(z.unknown()).optional(),
|
|
114
109
|
});
|
|
115
|
-
exports.createJsonApiResourceSchema = createJsonApiResourceSchema;
|
|
116
110
|
// Backward compatibility exports (deprecated - use JSON:API versions)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
'filter[startDate]':
|
|
121
|
-
'filter[endDate]':
|
|
111
|
+
export const errorResponseSchema = jsonApiErrorResponseSchema;
|
|
112
|
+
export const paginationQuerySchema = jsonApiPaginationQuerySchema;
|
|
113
|
+
export const dateRangeQuerySchema = z.object({
|
|
114
|
+
'filter[startDate]': z.string().datetime().optional(),
|
|
115
|
+
'filter[endDate]': z.string().datetime().optional(),
|
|
122
116
|
});
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.uploadFileBodySchema = exports.uploadedFileResponseSchema = exports.uploadedFileResourceSchema = exports.uploadedFileAttributesSchema = exports.documentListResponseSchema = exports.documentResponseSchema = exports.documentResourceSchema = exports.updateDocumentSchema = exports.createDocumentSchema = exports.updateDocumentAttributesSchema = exports.createDocumentAttributesSchema = exports.documentAttributesSchema = exports.relatedEntitySchema = exports.relatedEntityTypeSchema = exports.documentTypeSchema = void 0;
|
|
4
|
-
const zod_1 = require("zod");
|
|
5
|
-
const common_schemas_1 = require("./common.schemas");
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { timestampsSchema, createJsonApiResourceSchema, jsonApiSingleResponseSchema, jsonApiCollectionResponseSchema } from './common.schemas';
|
|
6
3
|
/**
|
|
7
4
|
* Document schemas - JSON:API compliant
|
|
8
5
|
*/
|
|
9
6
|
// Document type enum
|
|
10
|
-
|
|
7
|
+
export const documentTypeSchema = z.enum([
|
|
11
8
|
'receipt',
|
|
12
9
|
'certificate',
|
|
13
10
|
'land-document',
|
|
@@ -17,74 +14,74 @@ exports.documentTypeSchema = zod_1.z.enum([
|
|
|
17
14
|
'other',
|
|
18
15
|
]);
|
|
19
16
|
// Related entity type enum
|
|
20
|
-
|
|
17
|
+
export const relatedEntityTypeSchema = z.enum(['farm', 'field', 'purchase', 'expense', 'equipment', 'other']);
|
|
21
18
|
// Related entity schema
|
|
22
|
-
|
|
23
|
-
type:
|
|
24
|
-
id:
|
|
19
|
+
export const relatedEntitySchema = z.object({
|
|
20
|
+
type: relatedEntityTypeSchema,
|
|
21
|
+
id: z.string().uuid(),
|
|
25
22
|
});
|
|
26
23
|
// Document attributes schema (for JSON:API attributes object)
|
|
27
|
-
|
|
28
|
-
farmId:
|
|
29
|
-
name:
|
|
30
|
-
type:
|
|
31
|
-
category:
|
|
32
|
-
fileUrl:
|
|
33
|
-
fileExtension:
|
|
34
|
-
fileSize:
|
|
35
|
-
uploadedDate:
|
|
36
|
-
uploadedBy:
|
|
37
|
-
relatedTo:
|
|
38
|
-
tags:
|
|
39
|
-
description:
|
|
40
|
-
}).merge(
|
|
24
|
+
export const documentAttributesSchema = z.object({
|
|
25
|
+
farmId: z.string().uuid(),
|
|
26
|
+
name: z.string(),
|
|
27
|
+
type: documentTypeSchema,
|
|
28
|
+
category: z.string().nullable(),
|
|
29
|
+
fileUrl: z.string(),
|
|
30
|
+
fileExtension: z.string().nullable().optional(),
|
|
31
|
+
fileSize: z.number().int().positive().nullable(), // in bytes
|
|
32
|
+
uploadedDate: z.string().datetime(),
|
|
33
|
+
uploadedBy: z.string().uuid().nullable(),
|
|
34
|
+
relatedTo: relatedEntitySchema.nullable(),
|
|
35
|
+
tags: z.array(z.string()).optional(),
|
|
36
|
+
description: z.string().nullable(),
|
|
37
|
+
}).merge(timestampsSchema);
|
|
41
38
|
// Create document attributes (input)
|
|
42
|
-
|
|
43
|
-
name:
|
|
44
|
-
type:
|
|
45
|
-
category:
|
|
46
|
-
fileUrl:
|
|
47
|
-
fileSize:
|
|
48
|
-
relatedTo:
|
|
49
|
-
tags:
|
|
50
|
-
description:
|
|
39
|
+
export const createDocumentAttributesSchema = z.object({
|
|
40
|
+
name: z.string().min(1).max(200),
|
|
41
|
+
type: documentTypeSchema,
|
|
42
|
+
category: z.string().optional(),
|
|
43
|
+
fileUrl: z.string().optional(), // View URL path (optional - will be set after file upload)
|
|
44
|
+
fileSize: z.number().int().positive().optional(), // in bytes
|
|
45
|
+
relatedTo: relatedEntitySchema.optional(),
|
|
46
|
+
tags: z.array(z.string()).optional(),
|
|
47
|
+
description: z.string().optional(),
|
|
51
48
|
});
|
|
52
49
|
// Update document attributes (input)
|
|
53
|
-
|
|
54
|
-
name:
|
|
55
|
-
type:
|
|
56
|
-
category:
|
|
57
|
-
fileUrl:
|
|
58
|
-
fileSize:
|
|
59
|
-
relatedTo:
|
|
60
|
-
tags:
|
|
61
|
-
description:
|
|
50
|
+
export const updateDocumentAttributesSchema = z.object({
|
|
51
|
+
name: z.string().min(1).max(200).optional(),
|
|
52
|
+
type: documentTypeSchema.optional(),
|
|
53
|
+
category: z.string().nullable().optional(),
|
|
54
|
+
fileUrl: z.string().optional(), // View URL path (can be updated after file upload)
|
|
55
|
+
fileSize: z.number().int().positive().optional(), // in bytes
|
|
56
|
+
relatedTo: relatedEntitySchema.nullable().optional(),
|
|
57
|
+
tags: z.array(z.string()).optional(),
|
|
58
|
+
description: z.string().nullable().optional(),
|
|
62
59
|
});
|
|
63
60
|
// Create document input (JSON:API format)
|
|
64
|
-
|
|
65
|
-
type:
|
|
66
|
-
attributes:
|
|
61
|
+
export const createDocumentSchema = z.object({
|
|
62
|
+
type: z.literal('documents'),
|
|
63
|
+
attributes: createDocumentAttributesSchema,
|
|
67
64
|
});
|
|
68
65
|
// Update document input (JSON:API format)
|
|
69
|
-
|
|
70
|
-
type:
|
|
71
|
-
id:
|
|
72
|
-
attributes:
|
|
66
|
+
export const updateDocumentSchema = z.object({
|
|
67
|
+
type: z.literal('documents'),
|
|
68
|
+
id: z.string().uuid(),
|
|
69
|
+
attributes: updateDocumentAttributesSchema,
|
|
73
70
|
});
|
|
74
71
|
// Document resource (JSON:API resource object)
|
|
75
|
-
|
|
72
|
+
export const documentResourceSchema = createJsonApiResourceSchema('documents', documentAttributesSchema);
|
|
76
73
|
// Document responses (JSON:API format)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
fileUrl:
|
|
81
|
-
fileSize:
|
|
82
|
-
fileName:
|
|
83
|
-
contentType:
|
|
84
|
-
uploadedAt:
|
|
74
|
+
export const documentResponseSchema = jsonApiSingleResponseSchema(documentResourceSchema);
|
|
75
|
+
export const documentListResponseSchema = jsonApiCollectionResponseSchema(documentResourceSchema);
|
|
76
|
+
export const uploadedFileAttributesSchema = z.object({
|
|
77
|
+
fileUrl: z.string(),
|
|
78
|
+
fileSize: z.number().int().positive(),
|
|
79
|
+
fileName: z.string(),
|
|
80
|
+
contentType: z.string().optional(),
|
|
81
|
+
uploadedAt: z.string().datetime(),
|
|
85
82
|
});
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
file:
|
|
83
|
+
export const uploadedFileResourceSchema = createJsonApiResourceSchema('uploaded-files', uploadedFileAttributesSchema);
|
|
84
|
+
export const uploadedFileResponseSchema = jsonApiSingleResponseSchema(uploadedFileResourceSchema);
|
|
85
|
+
export const uploadFileBodySchema = z.object({
|
|
86
|
+
file: z.any(),
|
|
90
87
|
});
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.maintenanceRecordSchema = exports.equipmentListResponseSchema = exports.equipmentResponseSchema = exports.maintenanceRecordResourceSchema = exports.equipmentResourceSchema = exports.createMaintenanceRecordSchema = exports.updateEquipmentSchema = exports.createEquipmentSchema = exports.createMaintenanceRecordAttributesSchema = exports.updateEquipmentAttributesSchema = exports.createEquipmentAttributesSchema = exports.equipmentAttributesSchema = exports.maintenanceRecordAttributesSchema = exports.maintenanceScheduleSchema = exports.maintenanceTypeSchema = exports.equipmentStatusSchema = exports.equipmentTypeSchema = void 0;
|
|
4
|
-
const zod_1 = require("zod");
|
|
5
|
-
const common_schemas_1 = require("./common.schemas");
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { timestampsSchema, createJsonApiResourceSchema, jsonApiSingleResponseSchema, jsonApiCollectionResponseSchema } from './common.schemas';
|
|
6
3
|
/**
|
|
7
4
|
* Equipment schemas - JSON:API compliant
|
|
8
5
|
*/
|
|
9
6
|
// Equipment type enum
|
|
10
|
-
|
|
7
|
+
export const equipmentTypeSchema = z.enum([
|
|
11
8
|
'tractor',
|
|
12
9
|
'sprayer',
|
|
13
10
|
'harvester',
|
|
@@ -18,108 +15,108 @@ exports.equipmentTypeSchema = zod_1.z.enum([
|
|
|
18
15
|
'other',
|
|
19
16
|
]);
|
|
20
17
|
// Equipment status enum
|
|
21
|
-
|
|
18
|
+
export const equipmentStatusSchema = z.enum(['operational', 'maintenance', 'repair', 'retired']);
|
|
22
19
|
// Maintenance type enum
|
|
23
|
-
|
|
20
|
+
export const maintenanceTypeSchema = z.enum(['routine', 'oil-change', 'inspection', 'repair', 'other']);
|
|
24
21
|
// Maintenance schedule
|
|
25
|
-
|
|
26
|
-
intervalDays:
|
|
27
|
-
lastMaintenanceDate:
|
|
28
|
-
nextMaintenanceDate:
|
|
29
|
-
maintenanceType:
|
|
30
|
-
description:
|
|
22
|
+
export const maintenanceScheduleSchema = z.object({
|
|
23
|
+
intervalDays: z.number().int().positive(),
|
|
24
|
+
lastMaintenanceDate: z.string().datetime().nullable(),
|
|
25
|
+
nextMaintenanceDate: z.string().datetime().nullable(),
|
|
26
|
+
maintenanceType: maintenanceTypeSchema,
|
|
27
|
+
description: z.string().nullable(),
|
|
31
28
|
});
|
|
32
29
|
// Maintenance record attributes
|
|
33
|
-
|
|
34
|
-
date:
|
|
35
|
-
type:
|
|
36
|
-
description:
|
|
37
|
-
cost:
|
|
38
|
-
performedBy:
|
|
39
|
-
nextMaintenanceDate:
|
|
40
|
-
notes:
|
|
30
|
+
export const maintenanceRecordAttributesSchema = z.object({
|
|
31
|
+
date: z.string().datetime(),
|
|
32
|
+
type: maintenanceTypeSchema,
|
|
33
|
+
description: z.string(),
|
|
34
|
+
cost: z.number().nonnegative().nullable(),
|
|
35
|
+
performedBy: z.string().nullable(), // TeamMember ID or service provider
|
|
36
|
+
nextMaintenanceDate: z.string().datetime().nullable(),
|
|
37
|
+
notes: z.string().nullable(),
|
|
41
38
|
});
|
|
42
39
|
// Equipment attributes schema (for JSON:API attributes object)
|
|
43
|
-
|
|
44
|
-
farmId:
|
|
45
|
-
name:
|
|
46
|
-
type:
|
|
47
|
-
brand:
|
|
48
|
-
model:
|
|
49
|
-
serialNumber:
|
|
50
|
-
purchaseDate:
|
|
51
|
-
purchasePrice:
|
|
52
|
-
currentValue:
|
|
53
|
-
status:
|
|
54
|
-
location:
|
|
55
|
-
assignedTo:
|
|
56
|
-
assignedToName:
|
|
57
|
-
maintenanceSchedule:
|
|
58
|
-
maintenanceHistory:
|
|
59
|
-
notes:
|
|
60
|
-
}).merge(
|
|
40
|
+
export const equipmentAttributesSchema = z.object({
|
|
41
|
+
farmId: z.string().uuid(),
|
|
42
|
+
name: z.string(),
|
|
43
|
+
type: equipmentTypeSchema,
|
|
44
|
+
brand: z.string().nullable(),
|
|
45
|
+
model: z.string().nullable(),
|
|
46
|
+
serialNumber: z.string().nullable(),
|
|
47
|
+
purchaseDate: z.string().datetime().nullable(),
|
|
48
|
+
purchasePrice: z.number().nullable(),
|
|
49
|
+
currentValue: z.number().nullable(),
|
|
50
|
+
status: equipmentStatusSchema,
|
|
51
|
+
location: z.string().nullable(),
|
|
52
|
+
assignedTo: z.string().uuid().nullable(),
|
|
53
|
+
assignedToName: z.string().nullable().optional(),
|
|
54
|
+
maintenanceSchedule: maintenanceScheduleSchema.nullable().optional(),
|
|
55
|
+
maintenanceHistory: z.array(maintenanceRecordAttributesSchema).optional(),
|
|
56
|
+
notes: z.string().nullable(),
|
|
57
|
+
}).merge(timestampsSchema);
|
|
61
58
|
// Create equipment attributes (input)
|
|
62
|
-
|
|
63
|
-
name:
|
|
64
|
-
type:
|
|
65
|
-
brand:
|
|
66
|
-
model:
|
|
67
|
-
serialNumber:
|
|
68
|
-
purchaseDate:
|
|
69
|
-
purchasePrice:
|
|
70
|
-
currentValue:
|
|
71
|
-
status:
|
|
72
|
-
location:
|
|
73
|
-
assignedTo:
|
|
74
|
-
notes:
|
|
59
|
+
export const createEquipmentAttributesSchema = z.object({
|
|
60
|
+
name: z.string().min(1).max(200),
|
|
61
|
+
type: equipmentTypeSchema,
|
|
62
|
+
brand: z.string().optional(),
|
|
63
|
+
model: z.string().optional(),
|
|
64
|
+
serialNumber: z.string().optional(),
|
|
65
|
+
purchaseDate: z.string().datetime().optional(),
|
|
66
|
+
purchasePrice: z.number().nonnegative().optional(),
|
|
67
|
+
currentValue: z.number().nonnegative().optional(), // Depreciated value
|
|
68
|
+
status: equipmentStatusSchema.default('operational'),
|
|
69
|
+
location: z.string().optional(),
|
|
70
|
+
assignedTo: z.string().uuid().optional(), // TeamMember ID
|
|
71
|
+
notes: z.string().optional(),
|
|
75
72
|
});
|
|
76
73
|
// Update equipment attributes (input)
|
|
77
|
-
|
|
78
|
-
name:
|
|
79
|
-
type:
|
|
80
|
-
brand:
|
|
81
|
-
model:
|
|
82
|
-
serialNumber:
|
|
83
|
-
purchaseDate:
|
|
84
|
-
purchasePrice:
|
|
85
|
-
currentValue:
|
|
86
|
-
status:
|
|
87
|
-
location:
|
|
88
|
-
assignedTo:
|
|
89
|
-
notes:
|
|
74
|
+
export const updateEquipmentAttributesSchema = z.object({
|
|
75
|
+
name: z.string().min(1).max(200).optional(),
|
|
76
|
+
type: equipmentTypeSchema.optional(),
|
|
77
|
+
brand: z.string().nullable().optional(),
|
|
78
|
+
model: z.string().nullable().optional(),
|
|
79
|
+
serialNumber: z.string().nullable().optional(),
|
|
80
|
+
purchaseDate: z.string().datetime().nullable().optional(),
|
|
81
|
+
purchasePrice: z.number().nonnegative().nullable().optional(),
|
|
82
|
+
currentValue: z.number().nonnegative().nullable().optional(),
|
|
83
|
+
status: equipmentStatusSchema.optional(),
|
|
84
|
+
location: z.string().nullable().optional(),
|
|
85
|
+
assignedTo: z.string().uuid().nullable().optional(),
|
|
86
|
+
notes: z.string().nullable().optional(),
|
|
90
87
|
});
|
|
91
88
|
// Create maintenance record attributes (input)
|
|
92
|
-
|
|
93
|
-
date:
|
|
94
|
-
type:
|
|
95
|
-
description:
|
|
96
|
-
cost:
|
|
97
|
-
performedBy:
|
|
98
|
-
nextMaintenanceDate:
|
|
99
|
-
notes:
|
|
89
|
+
export const createMaintenanceRecordAttributesSchema = z.object({
|
|
90
|
+
date: z.string().datetime(),
|
|
91
|
+
type: maintenanceTypeSchema,
|
|
92
|
+
description: z.string().min(1),
|
|
93
|
+
cost: z.number().nonnegative().optional(),
|
|
94
|
+
performedBy: z.string().nullable().optional(),
|
|
95
|
+
nextMaintenanceDate: z.string().datetime().optional(),
|
|
96
|
+
notes: z.string().optional(),
|
|
100
97
|
});
|
|
101
98
|
// Create equipment input (JSON:API format)
|
|
102
|
-
|
|
103
|
-
type:
|
|
104
|
-
attributes:
|
|
99
|
+
export const createEquipmentSchema = z.object({
|
|
100
|
+
type: z.literal('equipment'),
|
|
101
|
+
attributes: createEquipmentAttributesSchema,
|
|
105
102
|
});
|
|
106
103
|
// Update equipment input (JSON:API format)
|
|
107
|
-
|
|
108
|
-
type:
|
|
109
|
-
id:
|
|
110
|
-
attributes:
|
|
104
|
+
export const updateEquipmentSchema = z.object({
|
|
105
|
+
type: z.literal('equipment'),
|
|
106
|
+
id: z.string().uuid(),
|
|
107
|
+
attributes: updateEquipmentAttributesSchema,
|
|
111
108
|
});
|
|
112
109
|
// Create maintenance record input (JSON:API format)
|
|
113
|
-
|
|
114
|
-
type:
|
|
115
|
-
attributes:
|
|
110
|
+
export const createMaintenanceRecordSchema = z.object({
|
|
111
|
+
type: z.literal('maintenance-records'),
|
|
112
|
+
attributes: createMaintenanceRecordAttributesSchema,
|
|
116
113
|
});
|
|
117
114
|
// Equipment resource (JSON:API resource object)
|
|
118
|
-
|
|
115
|
+
export const equipmentResourceSchema = createJsonApiResourceSchema('equipment', equipmentAttributesSchema);
|
|
119
116
|
// Maintenance record resource (JSON:API resource object)
|
|
120
|
-
|
|
117
|
+
export const maintenanceRecordResourceSchema = createJsonApiResourceSchema('maintenance-records', maintenanceRecordAttributesSchema);
|
|
121
118
|
// Equipment responses (JSON:API format)
|
|
122
|
-
|
|
123
|
-
|
|
119
|
+
export const equipmentResponseSchema = jsonApiSingleResponseSchema(equipmentResourceSchema);
|
|
120
|
+
export const equipmentListResponseSchema = jsonApiCollectionResponseSchema(equipmentResourceSchema);
|
|
124
121
|
// Maintenance record response (JSON:API format)
|
|
125
|
-
|
|
122
|
+
export const maintenanceRecordSchema = jsonApiSingleResponseSchema(maintenanceRecordResourceSchema);
|