Skip to content

Commit 056bc3b

Browse files
committed
Add API contract schemas for CRUD and bulk operations
Introduces contract.zod.ts with Zod schemas for standard API request and response payloads, including create, update, delete, get, list, and bulk operations. Also exports these contracts from the package entry point for SDK and documentation generation.
1 parent 3239f53 commit 056bc3b

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
import { z } from 'zod';
2+
import { QuerySchema } from './query.zod';
3+
4+
// ==========================================
5+
// 1. Base Envelopes
6+
// ==========================================
7+
8+
export const ApiErrorSchema = z.object({
9+
code: z.string().describe('Error code (e.g. validation_error)'),
10+
message: z.string().describe('Readable error message'),
11+
details: z.any().optional().describe('Additional error context (e.g. field validation errors)'),
12+
});
13+
14+
export const BaseResponseSchema = z.object({
15+
success: z.boolean().describe('Operation success status'),
16+
error: ApiErrorSchema.optional().describe('Error details if success is false'),
17+
meta: z.object({
18+
timestamp: z.string(),
19+
duration: z.number().optional(),
20+
requestId: z.string().optional(),
21+
traceId: z.string().optional(),
22+
}).optional().describe('Response metadata'),
23+
});
24+
25+
// ==========================================
26+
// 2. Request Payloads (Inputs)
27+
// ==========================================
28+
29+
export const RecordDataSchema = z.record(z.any()).describe('Key-value map of record data');
30+
31+
/**
32+
* Standard Create Request
33+
*/
34+
export const CreateRequestSchema = z.object({
35+
data: RecordDataSchema.describe('Record data to insert'),
36+
});
37+
38+
/**
39+
* Standard Update Request
40+
*/
41+
export const UpdateRequestSchema = z.object({
42+
data: RecordDataSchema.describe('Partial record data to update'),
43+
});
44+
45+
/**
46+
* Standard Bulk Request
47+
*/
48+
export const BulkRequestSchema = z.object({
49+
records: z.array(RecordDataSchema).describe('Array of records to process'),
50+
allOrNone: z.boolean().default(true).describe('If true, rollback entire transaction on any failure'),
51+
});
52+
53+
/**
54+
* Export Request
55+
*/
56+
export const ExportRequestSchema = QuerySchema.extend({
57+
format: z.enum(['csv', 'json', 'xlsx']).default('csv'),
58+
});
59+
60+
// ==========================================
61+
// 3. Response Payloads (Outputs)
62+
// ==========================================
63+
64+
/**
65+
* Single Record Response (Get/Create/Update)
66+
*/
67+
export const SingleRecordResponseSchema = BaseResponseSchema.extend({
68+
data: RecordDataSchema.describe('The requested or modified record'),
69+
});
70+
71+
/**
72+
* List/Query Response
73+
*/
74+
export const ListRecordResponseSchema = BaseResponseSchema.extend({
75+
data: z.array(RecordDataSchema).describe('Array of matching records'),
76+
pagination: z.object({
77+
total: z.number().describe('Total matching records count'),
78+
limit: z.number().describe('Page size'),
79+
offset: z.number().describe('Page offset'),
80+
hasMore: z.boolean().describe('Are there more pages?'),
81+
}).describe('Pagination info'),
82+
});
83+
84+
/**
85+
* Modification Result (for Batch/Bulk operations)
86+
*/
87+
export const ModificationResultSchema = z.object({
88+
id: z.string().optional().describe('Record ID if processed'),
89+
success: z.boolean(),
90+
errors: z.array(ApiErrorSchema).optional(),
91+
});
92+
93+
/**
94+
* Bulk Operation Response
95+
*/
96+
export const BulkResponseSchema = BaseResponseSchema.extend({
97+
data: z.array(ModificationResultSchema).describe('Results for each item in the batch'),
98+
});
99+
100+
/**
101+
* Delete Response
102+
*/
103+
export const DeleteResponseSchema = BaseResponseSchema.extend({
104+
id: z.string().describe('ID of the deleted record'),
105+
});
106+
107+
// ==========================================
108+
// 4. API Contract Registry
109+
// ==========================================
110+
111+
/**
112+
* Standard API Contracts map
113+
* Used for generating SDKs and Documentation
114+
*/
115+
export const ApiContracts = {
116+
create: {
117+
input: CreateRequestSchema,
118+
output: SingleRecordResponseSchema
119+
},
120+
update: {
121+
input: UpdateRequestSchema,
122+
output: SingleRecordResponseSchema
123+
},
124+
delete: {
125+
input: z.object({}), // usually just ID in URL
126+
output: DeleteResponseSchema
127+
},
128+
get: {
129+
input: z.object({}), // usually just ID in URL
130+
output: SingleRecordResponseSchema
131+
},
132+
list: {
133+
input: QuerySchema,
134+
output: ListRecordResponseSchema
135+
},
136+
bulk_create: {
137+
input: BulkRequestSchema,
138+
output: BulkResponseSchema
139+
},
140+
bulk_update: {
141+
input: BulkRequestSchema,
142+
output: BulkResponseSchema
143+
},
144+
bulk_delete: {
145+
input: z.object({ ids: z.array(z.string()) }),
146+
output: BulkResponseSchema
147+
}
148+
};

packages/spec/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export * from './data/flow.zod';
1818
export * from './data/dataset.zod';
1919
export * from './data/query.zod';
2020
export * from './data/mapping.zod';
21+
export * from './data/contract.zod';
2122

2223
// AI Protocol (Agent, RAG)
2324
export * from './ai/agent.zod';

0 commit comments

Comments
 (0)