@solutionspool/node-micro-contracts 1.0.0
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/ARCHITECTURE.md +302 -0
- package/QUICKSTART.md +204 -0
- package/README.md +95 -0
- package/USAGE_GUIDE.md +434 -0
- package/examples/auth-routes.example.js +38 -0
- package/examples/event-consumption.example.js +109 -0
- package/examples/event-publishing.example.js +82 -0
- package/index.js +25 -0
- package/middleware/validate.js +75 -0
- package/package.json +19 -0
- package/schemas/common.schema.js +33 -0
- package/schemas/events.schema.js +55 -0
- package/schemas/user.schema.js +91 -0
- package/test-contracts.js +229 -0
package/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# Contracts Package Architecture
|
|
2
|
+
|
|
3
|
+
## π System Overview
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
7
|
+
β @node-micro/contracts β
|
|
8
|
+
β Centralized Contract Package β
|
|
9
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
10
|
+
β
|
|
11
|
+
ββββββββββββββββ΄βββββββββββββββ
|
|
12
|
+
β β
|
|
13
|
+
βΌ βΌ
|
|
14
|
+
βββββββββββββββββββββ βββββββββββββββββββββ
|
|
15
|
+
β auth-service β β user-service β
|
|
16
|
+
β β β β
|
|
17
|
+
β β’ Routes β β β’ Routes β
|
|
18
|
+
β β’ Controllers β β β’ Controllers β
|
|
19
|
+
β β’ Event Pub ββββββββββββΆ β’ Event Sub β
|
|
20
|
+
βββββββββββββββββββββ βββββββββββββββββββββ
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## ποΈ Package Structure
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
@node-micro/contracts
|
|
27
|
+
β
|
|
28
|
+
βββ π index.js # Main exports
|
|
29
|
+
β
|
|
30
|
+
βββ π schemas/
|
|
31
|
+
β βββ user.schema.js # User-related schemas
|
|
32
|
+
β β βββ UserRole # Enum: user|provider|admin
|
|
33
|
+
β β βββ UserBaseSchema # Base user fields
|
|
34
|
+
β β βββ UserRegistrationSchema
|
|
35
|
+
β β βββ UserLoginSchema
|
|
36
|
+
β β βββ UserProfileUpdateSchema
|
|
37
|
+
β β βββ UserResponseSchema
|
|
38
|
+
β β βββ JWTPayloadSchema
|
|
39
|
+
β β βββ AuthResponseSchema
|
|
40
|
+
β β
|
|
41
|
+
β βββ events.schema.js # Event schemas
|
|
42
|
+
β βββ UserRegisteredEventSchema
|
|
43
|
+
β βββ UserVerifiedEventSchema
|
|
44
|
+
β βββ UserUpdatedEventSchema
|
|
45
|
+
β βββ UserDeletedEventSchema
|
|
46
|
+
β
|
|
47
|
+
βββ π middleware/
|
|
48
|
+
β βββ validate.js # Validation middleware
|
|
49
|
+
β βββ validateRequest()
|
|
50
|
+
β βββ validateQuery()
|
|
51
|
+
β βββ validateParams()
|
|
52
|
+
β
|
|
53
|
+
βββ π examples/
|
|
54
|
+
β βββ auth-routes.example.js
|
|
55
|
+
β βββ event-publishing.example.js
|
|
56
|
+
β βββ event-consumption.example.js
|
|
57
|
+
β
|
|
58
|
+
βββ π docs/
|
|
59
|
+
βββ README.md
|
|
60
|
+
βββ QUICKSTART.md
|
|
61
|
+
βββ USAGE_GUIDE.md
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## π Data Flow
|
|
65
|
+
|
|
66
|
+
### 1. HTTP Request Flow (with Validation)
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
ββββββββββββ ββββββββββββββββ ββββββββββββ ββββββββββββ
|
|
70
|
+
β Client βββββββΆβ Validation βββββββΆβ Route βββββββΆβControllerβ
|
|
71
|
+
β β β Middleware β β β β β
|
|
72
|
+
ββββββββββββ ββββββββββββββββ ββββββββββββ ββββββββββββ
|
|
73
|
+
β
|
|
74
|
+
β (if valid)
|
|
75
|
+
βΌ
|
|
76
|
+
req.validatedData
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 2. Event Publishing Flow (auth-service)
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
|
|
83
|
+
β Controller βββββββΆβ Validate βββββββΆβ RabbitMQ β
|
|
84
|
+
β (create β β Event β β Exchange β
|
|
85
|
+
β user) β β Schema β β β
|
|
86
|
+
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
|
|
87
|
+
β
|
|
88
|
+
βΌ
|
|
89
|
+
UserRegisteredEventSchema.parse()
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 3. Event Consumption Flow (user-service)
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
|
|
96
|
+
β RabbitMQ βββββββΆβ Validate βββββββΆβ Create β
|
|
97
|
+
β Queue β β Event β β User β
|
|
98
|
+
β β β Schema β β Profile β
|
|
99
|
+
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
|
|
100
|
+
β
|
|
101
|
+
βΌ
|
|
102
|
+
UserRegisteredEventSchema.parse()
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## π Contract Types
|
|
106
|
+
|
|
107
|
+
### Request Contracts (HTTP)
|
|
108
|
+
|
|
109
|
+
```javascript
|
|
110
|
+
// Input validation for API endpoints
|
|
111
|
+
UserRegistrationSchema β POST /register
|
|
112
|
+
UserLoginSchema β POST /login
|
|
113
|
+
UserProfileUpdateSchema β PUT /profile
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Event Contracts (Message Queue)
|
|
117
|
+
|
|
118
|
+
```javascript
|
|
119
|
+
// Inter-service communication
|
|
120
|
+
UserRegisteredEventSchema β auth-service β user-service
|
|
121
|
+
UserVerifiedEventSchema β auth-service β user-service
|
|
122
|
+
UserUpdatedEventSchema β any-service β user-service
|
|
123
|
+
UserDeletedEventSchema β any-service β user-service
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Response Contracts
|
|
127
|
+
|
|
128
|
+
```javascript
|
|
129
|
+
// Standardized API responses
|
|
130
|
+
UserResponseSchema β User data (no password)
|
|
131
|
+
AuthResponseSchema β Login/Register response
|
|
132
|
+
JWTPayloadSchema β Token payload structure
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## π Validation Layers
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
Layer 1: API Gateway (Kong)
|
|
139
|
+
β
|
|
140
|
+
βΌ
|
|
141
|
+
Layer 2: Request Validation (Zod Middleware)
|
|
142
|
+
β
|
|
143
|
+
βΌ
|
|
144
|
+
Layer 3: Business Logic (Controller)
|
|
145
|
+
β
|
|
146
|
+
βΌ
|
|
147
|
+
Layer 4: Event Validation (Zod Schema)
|
|
148
|
+
β
|
|
149
|
+
βΌ
|
|
150
|
+
Layer 5: Message Queue (RabbitMQ)
|
|
151
|
+
β
|
|
152
|
+
βΌ
|
|
153
|
+
Layer 6: Event Consumption Validation (Zod Schema)
|
|
154
|
+
β
|
|
155
|
+
βΌ
|
|
156
|
+
Layer 7: Database (Sequelize)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## π― Usage Patterns
|
|
160
|
+
|
|
161
|
+
### Pattern 1: Route + Middleware
|
|
162
|
+
|
|
163
|
+
```javascript
|
|
164
|
+
router.post(
|
|
165
|
+
"/register",
|
|
166
|
+
validateRequest(UserRegistrationSchema), // Middleware
|
|
167
|
+
controller.register, // Handler
|
|
168
|
+
);
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Pattern 2: Manual Validation
|
|
172
|
+
|
|
173
|
+
```javascript
|
|
174
|
+
const result = UserRegistrationSchema.safeParse(data);
|
|
175
|
+
if (!result.success) {
|
|
176
|
+
return handleError(result.error);
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Pattern 3: Event Publishing
|
|
181
|
+
|
|
182
|
+
```javascript
|
|
183
|
+
const eventData = UserRegisteredEventSchema.parse(data);
|
|
184
|
+
await messageQueue.publishEvent("users", "user.registered", eventData);
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Pattern 4: Event Consumption
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
await messageQueue.subscribeToEvent(
|
|
191
|
+
"users",
|
|
192
|
+
"queue",
|
|
193
|
+
"user.registered",
|
|
194
|
+
async (rawData) => {
|
|
195
|
+
const validated = UserRegisteredEventSchema.parse(rawData);
|
|
196
|
+
await processUser(validated);
|
|
197
|
+
},
|
|
198
|
+
);
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## π Benefits by Layer
|
|
202
|
+
|
|
203
|
+
| Layer | Without Contracts | With Contracts |
|
|
204
|
+
| ----------------- | ------------------------------- | --------------------------------- |
|
|
205
|
+
| **Routes** | Manual validation, inconsistent | Middleware, standardized |
|
|
206
|
+
| **Controllers** | Type uncertainty | Type-safe data |
|
|
207
|
+
| **Events** | No validation, trust data | Validated at source & destination |
|
|
208
|
+
| **Consumers** | Risk of invalid data | Guaranteed valid structure |
|
|
209
|
+
| **Debugging** | Hard to trace issues | Clear validation errors |
|
|
210
|
+
| **Documentation** | Separate docs needed | Self-documenting schemas |
|
|
211
|
+
|
|
212
|
+
## π Update Flow
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
1. Update Schema
|
|
216
|
+
/packages/contracts/schemas/user.schema.js
|
|
217
|
+
|
|
218
|
+
2. Changes Immediately Available (symlinked)
|
|
219
|
+
auth-service β
|
|
220
|
+
user-service β
|
|
221
|
+
|
|
222
|
+
3. Tests Still Pass
|
|
223
|
+
npm run test
|
|
224
|
+
|
|
225
|
+
4. Deploy
|
|
226
|
+
All services get updated contracts
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## π Contract Governance
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
βββββββββββββββββββββββββββββββββββββββββββ
|
|
233
|
+
β Contract Owner β
|
|
234
|
+
β (contracts package) β
|
|
235
|
+
βββββββββββββββββββββββββββββββββββββββββββ
|
|
236
|
+
β
|
|
237
|
+
βββββββββββ΄ββββββββββ
|
|
238
|
+
βΌ βΌ
|
|
239
|
+
βββββββββββ βββββββββββ
|
|
240
|
+
βProducer β βConsumer β
|
|
241
|
+
βServices β βServices β
|
|
242
|
+
β β β β
|
|
243
|
+
β auth- β β user- β
|
|
244
|
+
β service β β service β
|
|
245
|
+
βββββββββββ βββββββββββ
|
|
246
|
+
|
|
247
|
+
All changes must go through the contract package
|
|
248
|
+
No direct data structure changes in services
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## π¨ Example: Complete User Registration Flow
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
1. Client β POST /register
|
|
255
|
+
β
|
|
256
|
+
2. validateRequest(UserRegistrationSchema)
|
|
257
|
+
β
|
|
258
|
+
ββ Valid? β Continue
|
|
259
|
+
ββ Invalid? β 400 Error with details
|
|
260
|
+
β
|
|
261
|
+
3. Controller creates user
|
|
262
|
+
β
|
|
263
|
+
4. UserRegisteredEventSchema.parse(userData)
|
|
264
|
+
β
|
|
265
|
+
5. Publish to RabbitMQ
|
|
266
|
+
β
|
|
267
|
+
6. user-service receives event
|
|
268
|
+
β
|
|
269
|
+
7. UserRegisteredEventSchema.parse(eventData)
|
|
270
|
+
β
|
|
271
|
+
8. Create user profile
|
|
272
|
+
β
|
|
273
|
+
9. β Success - User exists in both services
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## π Scalability
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
Current:
|
|
280
|
+
auth-service βββ
|
|
281
|
+
ββββΆ @node-micro/contracts
|
|
282
|
+
user-service βββ
|
|
283
|
+
|
|
284
|
+
Future:
|
|
285
|
+
auth-service βββ
|
|
286
|
+
user-service βββ€
|
|
287
|
+
booking-service βββΌβββΆ @node-micro/contracts
|
|
288
|
+
provider-service βββ€
|
|
289
|
+
payment-service βββ
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
All services share the same contract definitions!
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
**Visual Key:**
|
|
297
|
+
|
|
298
|
+
- π File
|
|
299
|
+
- π Folder
|
|
300
|
+
- ββΆ Data Flow
|
|
301
|
+
- β Success
|
|
302
|
+
- β Failure
|
package/QUICKSTART.md
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Quick Start: Using Contracts
|
|
2
|
+
|
|
3
|
+
## π 3-Minute Integration Guide
|
|
4
|
+
|
|
5
|
+
### 1. Import What You Need
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
const {
|
|
9
|
+
// Validation Middleware
|
|
10
|
+
validateRequest,
|
|
11
|
+
|
|
12
|
+
// Request Schemas
|
|
13
|
+
UserRegistrationSchema,
|
|
14
|
+
UserLoginSchema,
|
|
15
|
+
UserProfileUpdateSchema,
|
|
16
|
+
|
|
17
|
+
// Event Schemas
|
|
18
|
+
UserRegisteredEventSchema,
|
|
19
|
+
UserUpdatedEventSchema,
|
|
20
|
+
UserDeletedEventSchema,
|
|
21
|
+
} = require("@node-micro/contracts");
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### 2. Add to Your Routes (auth-service)
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
// routes/auth.js
|
|
28
|
+
const express = require("express");
|
|
29
|
+
const router = express.Router();
|
|
30
|
+
const {
|
|
31
|
+
validateRequest,
|
|
32
|
+
UserRegistrationSchema,
|
|
33
|
+
UserLoginSchema,
|
|
34
|
+
} = require("@node-micro/contracts");
|
|
35
|
+
const AuthController = require("../controllers/authController");
|
|
36
|
+
|
|
37
|
+
const authController = new AuthController(messageQueue);
|
|
38
|
+
|
|
39
|
+
router.post("/register", validateRequest(UserRegistrationSchema), (req, res) =>
|
|
40
|
+
authController.register(req, res),
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
router.post("/login", validateRequest(UserLoginSchema), (req, res) =>
|
|
44
|
+
authController.login(req, res),
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
module.exports = router;
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 3. Update Your Controller (auth-service)
|
|
51
|
+
|
|
52
|
+
```javascript
|
|
53
|
+
// controllers/authController.js
|
|
54
|
+
const { UserRegisteredEventSchema } = require("@node-micro/contracts");
|
|
55
|
+
|
|
56
|
+
class AuthController {
|
|
57
|
+
async register(req, res) {
|
|
58
|
+
try {
|
|
59
|
+
// Use req.validatedData instead of req.body
|
|
60
|
+
const { name, email, password, role, mobile } = req.validatedData;
|
|
61
|
+
|
|
62
|
+
// ... create user ...
|
|
63
|
+
|
|
64
|
+
// Validate event before publishing
|
|
65
|
+
if (this.messageQueue) {
|
|
66
|
+
const eventData = UserRegisteredEventSchema.parse({
|
|
67
|
+
userId: user.id,
|
|
68
|
+
name: user.name,
|
|
69
|
+
email: user.email,
|
|
70
|
+
mobile: mobile,
|
|
71
|
+
role: user.role,
|
|
72
|
+
createdAt: user.createdAt,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
await this.messageQueue.publishEvent(
|
|
76
|
+
"users",
|
|
77
|
+
"user.registered",
|
|
78
|
+
eventData,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
res.status(201).json({ message: "Success", token, user });
|
|
83
|
+
} catch (error) {
|
|
84
|
+
res.status(500).json({ error: error.message });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 4. Validate Events in Listeners (user-service)
|
|
91
|
+
|
|
92
|
+
```javascript
|
|
93
|
+
// events/listeners.js
|
|
94
|
+
const { UserRegisteredEventSchema } = require("@node-micro/contracts");
|
|
95
|
+
|
|
96
|
+
async function subscribeToEvents(messageQueue) {
|
|
97
|
+
await messageQueue.subscribeToEvent(
|
|
98
|
+
"users",
|
|
99
|
+
"user-service-queue",
|
|
100
|
+
"user.registered",
|
|
101
|
+
async (rawData) => {
|
|
102
|
+
try {
|
|
103
|
+
// Validate incoming event
|
|
104
|
+
const userData = UserRegisteredEventSchema.parse(rawData);
|
|
105
|
+
|
|
106
|
+
// Use validated data
|
|
107
|
+
await User.create({
|
|
108
|
+
id: userData.userId,
|
|
109
|
+
name: userData.name,
|
|
110
|
+
email: userData.email,
|
|
111
|
+
mobile: userData.mobile,
|
|
112
|
+
role: userData.role,
|
|
113
|
+
createdAt: userData.createdAt,
|
|
114
|
+
});
|
|
115
|
+
} catch (error) {
|
|
116
|
+
if (error.name === "ZodError") {
|
|
117
|
+
console.error("Invalid event:", error.errors);
|
|
118
|
+
} else {
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## β
That's It!
|
|
128
|
+
|
|
129
|
+
You now have:
|
|
130
|
+
|
|
131
|
+
- β
Request validation on all endpoints
|
|
132
|
+
- β
Event validation for publishing
|
|
133
|
+
- β
Event validation for consumption
|
|
134
|
+
- β
Consistent error messages
|
|
135
|
+
- β
Type-safe data contracts
|
|
136
|
+
|
|
137
|
+
## π Next Steps
|
|
138
|
+
|
|
139
|
+
- Read [USAGE_GUIDE.md](./USAGE_GUIDE.md) for complete documentation
|
|
140
|
+
- Check [/examples](./examples) for more patterns
|
|
141
|
+
- Review [/schemas](./schemas) to see all available schemas
|
|
142
|
+
|
|
143
|
+
## π― Common Patterns
|
|
144
|
+
|
|
145
|
+
### Validate but Don't Fail Registration if Event Publish Fails
|
|
146
|
+
|
|
147
|
+
```javascript
|
|
148
|
+
if (this.messageQueue) {
|
|
149
|
+
try {
|
|
150
|
+
const eventData = UserRegisteredEventSchema.parse(data);
|
|
151
|
+
await this.messageQueue.publishEvent("users", "user.registered", eventData);
|
|
152
|
+
} catch (error) {
|
|
153
|
+
console.error("Event publish failed:", error);
|
|
154
|
+
// Don't throw - user is already created
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Handle Duplicate Users in Event Listener
|
|
160
|
+
|
|
161
|
+
```javascript
|
|
162
|
+
try {
|
|
163
|
+
const userData = UserRegisteredEventSchema.parse(rawData);
|
|
164
|
+
await User.create(userData);
|
|
165
|
+
} catch (error) {
|
|
166
|
+
if (error.name === "ZodError") {
|
|
167
|
+
console.error("Invalid event data");
|
|
168
|
+
} else if (error.name === "SequelizeUniqueConstraintError") {
|
|
169
|
+
console.log("User already exists - skipping");
|
|
170
|
+
} else {
|
|
171
|
+
throw error; // Trigger retry
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Manual Validation with Better Error Messages
|
|
177
|
+
|
|
178
|
+
```javascript
|
|
179
|
+
const result = UserRegistrationSchema.safeParse(req.body);
|
|
180
|
+
|
|
181
|
+
if (!result.success) {
|
|
182
|
+
return res.status(400).json({
|
|
183
|
+
error: "Validation failed",
|
|
184
|
+
details: result.error.errors.map((err) => ({
|
|
185
|
+
field: err.path.join("."),
|
|
186
|
+
message: err.message,
|
|
187
|
+
})),
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## π οΈ Troubleshooting
|
|
193
|
+
|
|
194
|
+
**Q: Validation middleware not working?**
|
|
195
|
+
A: Make sure the middleware is placed BEFORE your controller in the route chain.
|
|
196
|
+
|
|
197
|
+
**Q: Getting ZodError in production?**
|
|
198
|
+
A: Use `safeParse()` instead of `parse()` to handle errors gracefully.
|
|
199
|
+
|
|
200
|
+
**Q: Need to update contracts?**
|
|
201
|
+
A: Edit schemas in `/schemas`, then reinstall in services: `npm install ../../packages/contracts`
|
|
202
|
+
|
|
203
|
+
**Q: How to add custom validation?**
|
|
204
|
+
A: Extend existing schemas or create custom ones using Zod's `.extend()` and `.refine()` methods.
|
package/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# @node-micro/contracts
|
|
2
|
+
|
|
3
|
+
Centralized contracts and schemas for node-micro microservices communication.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package provides Zod-based schemas for validating data contracts between microservices. It ensures type safety and consistent data structures across the auth-service and user-service.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install file:../../packages/contracts
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Basic Import
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
const {
|
|
21
|
+
UserRegistrationSchema,
|
|
22
|
+
UserLoginSchema,
|
|
23
|
+
UserRegisteredEventSchema,
|
|
24
|
+
JWTPayloadSchema,
|
|
25
|
+
} = require("@node-micro/contracts");
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Validation Example
|
|
29
|
+
|
|
30
|
+
```javascript
|
|
31
|
+
// Validate registration data
|
|
32
|
+
const result = UserRegistrationSchema.safeParse(req.body);
|
|
33
|
+
|
|
34
|
+
if (!result.success) {
|
|
35
|
+
return res.status(400).json({
|
|
36
|
+
error: "Validation failed",
|
|
37
|
+
details: result.error.errors,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const validData = result.data;
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Event Validation
|
|
45
|
+
|
|
46
|
+
```javascript
|
|
47
|
+
// Validate event data before publishing
|
|
48
|
+
const eventData = {
|
|
49
|
+
userId: user.id,
|
|
50
|
+
name: user.name,
|
|
51
|
+
email: user.email,
|
|
52
|
+
mobile: user.mobile,
|
|
53
|
+
role: user.role,
|
|
54
|
+
createdAt: user.createdAt,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const validated = UserRegisteredEventSchema.parse(eventData);
|
|
58
|
+
await messageQueue.publishEvent("users", "user.registered", validated);
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Available Schemas
|
|
62
|
+
|
|
63
|
+
### User Schemas
|
|
64
|
+
|
|
65
|
+
- `UserRole` - Enum for user roles (user, provider, admin)
|
|
66
|
+
- `UserBaseSchema` - Base user fields
|
|
67
|
+
- `UserRegistrationSchema` - User registration request
|
|
68
|
+
- `UserLoginSchema` - User login request
|
|
69
|
+
- `UserProfileUpdateSchema` - User profile update
|
|
70
|
+
- `UserResponseSchema` - User response (without password)
|
|
71
|
+
- `JWTPayloadSchema` - JWT token payload
|
|
72
|
+
- `AuthResponseSchema` - Auth response with token
|
|
73
|
+
|
|
74
|
+
### Event Schemas
|
|
75
|
+
|
|
76
|
+
- `UserRegisteredEventSchema` - User registration event
|
|
77
|
+
- `UserVerifiedEventSchema` - User verification event
|
|
78
|
+
- `UserUpdatedEventSchema` - User update event
|
|
79
|
+
- `UserDeletedEventSchema` - User deletion event
|
|
80
|
+
|
|
81
|
+
## Type Inference
|
|
82
|
+
|
|
83
|
+
Use Zod's type inference for TypeScript-like type safety:
|
|
84
|
+
|
|
85
|
+
```javascript
|
|
86
|
+
const { z } = require("zod");
|
|
87
|
+
const { UserRegistrationSchema } = require("@node-micro/contracts");
|
|
88
|
+
|
|
89
|
+
// Infer the type
|
|
90
|
+
// type UserRegistration = z.infer<typeof UserRegistrationSchema>;
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## License
|
|
94
|
+
|
|
95
|
+
ISC
|