@sentzunhat/zacatl 0.0.5 → 0.0.7
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/README.md +192 -111
- package/context.yaml +151 -0
- package/guidelines.yaml +74 -0
- package/mongodb.yaml +29 -0
- package/package.json +33 -2
- package/patterns.yaml +55 -0
- package/src/error/custom.ts +3 -2
- package/src/micro-service/architecture/application/entry-points/rest/common/handler.ts +1 -2
- package/src/micro-service/architecture/application/entry-points/rest/route-handlers/abstract.ts +16 -2
- package/src/micro-service/architecture/application/entry-points/rest/route-handlers/get-route-handler.ts +3 -5
- package/src/micro-service/architecture/application/entry-points/rest/route-handlers/post-route-handler.ts +4 -6
- package/src/micro-service/architecture/application/entry-points/rest/route-handlers/route-handler.ts +1 -2
- package/src/micro-service/architecture/infrastructure/repositories/abstract.ts +94 -18
- package/src/micro-service/architecture/platform/service/service.ts +4 -0
- package/start.md +34 -0
- package/test/unit/micro-service/architecture/application/application.test.ts +19 -2
- package/test/unit/micro-service/architecture/application/entry-points/rest/route-handlers/abstract.test.ts +30 -10
- package/test/unit/micro-service/architecture/application/entry-points/rest/route-handlers/post-route-handler.test.ts +14 -9
- package/test/unit/micro-service/architecture/infrastructure/repositories/abstract.test.ts +6 -9
- package/test/unit/micro-service/architecture/platform/service/service.test.ts +3 -3
- package/src/errors.ts +0 -72
package/README.md
CHANGED
|
@@ -1,48 +1,58 @@
|
|
|
1
|
-
# Zacatl
|
|
1
|
+
# Zacatl Microservice Framework
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@sentzunhat/zacatl)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
[](https://www.typescriptlang.org/)
|
|
6
6
|
|
|
7
|
-
A
|
|
7
|
+
A modular, high-performance TypeScript microservice framework for Node.js, featuring layered architecture, dependency injection, and robust validation for building scalable APIs and distributed systems.
|
|
8
8
|
|
|
9
9
|
## Table of Contents
|
|
10
10
|
|
|
11
|
-
- [
|
|
11
|
+
- [Overview](#overview)
|
|
12
|
+
- [Key Features](#key-features)
|
|
12
13
|
- [Installation](#installation)
|
|
13
|
-
- [
|
|
14
|
-
- [
|
|
14
|
+
- [Quick Start](#quick-start)
|
|
15
|
+
- [Project Structure](#project-structure)
|
|
16
|
+
- [Core Concepts](#core-concepts)
|
|
15
17
|
- [Configuration](#configuration)
|
|
16
|
-
- [API Reference](#api-reference)
|
|
17
18
|
- [Testing](#testing)
|
|
18
19
|
- [Contributing](#contributing)
|
|
20
|
+
- [Documentation](#documentation)
|
|
19
21
|
- [License](#license)
|
|
20
22
|
|
|
21
|
-
##
|
|
23
|
+
## Overview
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
25
|
+
Zacatl is a TypeScript-first microservice framework that enforces clean, layered (hexagonal) architecture with strict separation of concerns. It's designed for rapid development of robust APIs and distributed systems, with built-in support for dependency injection, validation, and seamless collaboration between human and AI contributors.
|
|
26
|
+
|
|
27
|
+
## Key Features
|
|
28
|
+
|
|
29
|
+
- **🏗️ Layered Architecture**: Clean separation with Application, Domain, Infrastructure, and Platform layers
|
|
30
|
+
- **💉 Dependency Injection**: Built-in DI container using `tsyringe` for better modularity
|
|
31
|
+
- **⚡ High Performance**: Built on Fastify for maximum speed and efficiency
|
|
32
|
+
- **🔍 Type Safety**: Full TypeScript support with strict typing and generics
|
|
33
|
+
- **✅ Validation**: Request/response validation using Zod schemas
|
|
34
|
+
- **🧪 Testing**: Comprehensive testing with Vitest and clear test structure
|
|
35
|
+
- **📊 MongoDB Support**: Built-in repository pattern with Mongoose integration
|
|
36
|
+
- **🌐 Internationalization**: Multi-language support with i18n
|
|
37
|
+
- **🚀 Production Ready**: Error handling, logging, and monitoring built-in
|
|
32
38
|
|
|
33
39
|
## Installation
|
|
34
40
|
|
|
41
|
+
Install Zacatl using npm:
|
|
42
|
+
|
|
35
43
|
```bash
|
|
36
44
|
npm install @sentzunhat/zacatl
|
|
37
|
-
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or with yarn:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
38
50
|
yarn add @sentzunhat/zacatl
|
|
39
|
-
# or
|
|
40
|
-
bun install @sentzunhat/zacatl
|
|
41
51
|
```
|
|
42
52
|
|
|
43
|
-
##
|
|
53
|
+
## Quick Start
|
|
44
54
|
|
|
45
|
-
|
|
55
|
+
Here's a minimal example to get you started:
|
|
46
56
|
|
|
47
57
|
```typescript
|
|
48
58
|
import Fastify from "fastify";
|
|
@@ -84,131 +94,202 @@ const microservice = new MicroService({
|
|
|
84
94
|
await microservice.start({ port: 9000 });
|
|
85
95
|
```
|
|
86
96
|
|
|
87
|
-
|
|
97
|
+
For a complete example with route handlers, see our [examples](./examples) directory.
|
|
88
98
|
|
|
89
|
-
|
|
90
|
-
import { z } from "zod";
|
|
91
|
-
import { GetRouteHandler } from "@sentzunhat/zacatl";
|
|
99
|
+
## Project Structure
|
|
92
100
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
101
|
+
```
|
|
102
|
+
src/
|
|
103
|
+
├── configuration.ts # App configuration and environment settings
|
|
104
|
+
├── logs.ts # Structured logging with Pino
|
|
105
|
+
├── optionals.ts # Optional utility types and helpers
|
|
106
|
+
├── error/ # Custom error classes (BadRequest, NotFound, etc.)
|
|
107
|
+
├── locales/ # Internationalization files (en.json, fr.json)
|
|
108
|
+
├── micro-service/
|
|
109
|
+
│ └── architecture/
|
|
110
|
+
│ ├── application/ # HTTP entry points, validation, route handlers
|
|
111
|
+
│ ├── domain/ # Business logic, models, services (pure)
|
|
112
|
+
│ ├── infrastructure/ # Database repositories, external adapters
|
|
113
|
+
│ └── platform/ # Service orchestration, DI setup, startup
|
|
114
|
+
└── utils/ # Utility functions (base64, hmac, etc.)
|
|
115
|
+
|
|
116
|
+
test/
|
|
117
|
+
└── unit/ # Unit tests mirroring src/ structure
|
|
118
|
+
```
|
|
98
119
|
|
|
99
|
-
|
|
120
|
+
### Layer Responsibilities
|
|
100
121
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
schema: {
|
|
106
|
-
response: {
|
|
107
|
-
200: UserSchema,
|
|
108
|
-
},
|
|
109
|
-
},
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
async handler(request, reply): Promise<User> {
|
|
114
|
-
const userId = request.params.id;
|
|
115
|
-
// Fetch user from database, etc.
|
|
116
|
-
return {
|
|
117
|
-
id: userId,
|
|
118
|
-
name: "John Doe",
|
|
119
|
-
email: "john@example.com",
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
```
|
|
122
|
+
- **Application Layer**: Handles HTTP requests, validation, and delegates to domain logic
|
|
123
|
+
- **Domain Layer**: Contains pure business logic, models, and services (no infrastructure dependencies)
|
|
124
|
+
- **Infrastructure Layer**: Manages persistence (MongoDB repositories) and external integrations
|
|
125
|
+
- **Platform Layer**: Bootstraps the application, configures DI container, and starts the server
|
|
124
126
|
|
|
125
|
-
|
|
127
|
+
---
|
|
126
128
|
|
|
127
|
-
|
|
128
|
-
import { Schema } from "mongoose";
|
|
129
|
-
import { singleton } from "tsyringe";
|
|
130
|
-
import { BaseRepository } from "@sentzunhat/zacatl";
|
|
131
|
-
|
|
132
|
-
interface Product {
|
|
133
|
-
name: string;
|
|
134
|
-
price: number;
|
|
135
|
-
description: string;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const productSchema = new Schema<Product>({
|
|
139
|
-
name: { type: String, required: true },
|
|
140
|
-
price: { type: Number, required: true },
|
|
141
|
-
description: { type: String, required: true },
|
|
142
|
-
});
|
|
129
|
+
## 3. Core Architectural Concepts
|
|
143
130
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
131
|
+
- **Layered (Hexagonal) Architecture:**
|
|
132
|
+
- Platform → Application → Domain → Infrastructure
|
|
133
|
+
- Strict separation of concerns; each layer has a single responsibility.
|
|
134
|
+
- **Error Handling:** All errors extend `CustomError` (see `src/error/`).
|
|
135
|
+
- **Validation:** Use `zod` schemas for all request/response validation.
|
|
136
|
+
- **Service Registration:** Register handlers/services in the DI container.
|
|
149
137
|
|
|
150
|
-
|
|
151
|
-
return this.model.findOne({ name }).exec();
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
```
|
|
138
|
+
---
|
|
155
139
|
|
|
156
|
-
##
|
|
140
|
+
## 4. Coding Standards for Humans and AI
|
|
141
|
+
|
|
142
|
+
- **Naming:**
|
|
143
|
+
- Files/folders: lowercase, hyphens (e.g., `user-repository.ts`)
|
|
144
|
+
- Classes: PascalCase
|
|
145
|
+
- Functions/variables: camelCase, descriptive
|
|
146
|
+
- **Code Style:**
|
|
147
|
+
- Clean, modular, and straightforward
|
|
148
|
+
- Use strong typing and TypeScript generics
|
|
149
|
+
- DRY principle: extract reusable logic
|
|
150
|
+
- Minimal comments; use tests to document behavior
|
|
151
|
+
- Validate all inputs and sanitize external data
|
|
152
|
+
- **AI Patterns:**
|
|
153
|
+
- Replicate DI, modularity, and test structure
|
|
154
|
+
- Update YAML docs when generating new code
|
|
157
155
|
|
|
158
|
-
|
|
156
|
+
---
|
|
159
157
|
|
|
160
|
-
|
|
161
|
-
- **Domain**: Business logic providers and services
|
|
162
|
-
- **Infrastructure**: Repositories and external dependencies
|
|
163
|
-
- **Platform**: Service startup, database connections, and server configuration
|
|
158
|
+
## 5. Dependency Injection (DI) Details
|
|
164
159
|
|
|
165
|
-
|
|
160
|
+
- **DI Container:** All services, repositories, and handlers are registered using `tsyringe`.
|
|
161
|
+
- **No direct instantiation:** Always resolve dependencies via DI.
|
|
162
|
+
- **AI Registration:** When generating new components, ensure they are registered in the DI container.
|
|
163
|
+
|
|
164
|
+
---
|
|
166
165
|
|
|
167
|
-
##
|
|
166
|
+
## 6. Database Schema & Persistence
|
|
168
167
|
|
|
169
|
-
- **
|
|
170
|
-
- **
|
|
168
|
+
- **MongoDB schemas:** Define all schemas in `src/micro-service/architecture/infrastructure/repositories/`.
|
|
169
|
+
- **Repository pattern:** Extend `BaseRepository` for new collections.
|
|
170
|
+
- **Schema best practices:**
|
|
171
|
+
- Favor embedding for related data
|
|
172
|
+
- Keep schemas minimal and property names concise
|
|
173
|
+
- Use references for large or independent data
|
|
174
|
+
- See `mongodb.yaml` for full guidelines
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## 7. Error Management and Validation
|
|
179
|
+
|
|
180
|
+
- **Error Classes:** All errors extend `CustomError` (see `src/error/`).
|
|
181
|
+
- **Throw, don’t return:** Always throw errors for exceptional cases.
|
|
182
|
+
- **Validation:** Use `zod` for all request/response validation. Place schemas in the Application layer.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## 8. Testing Philosophy and Setup
|
|
187
|
+
|
|
188
|
+
- **Framework:** Use `vitest` for all tests.
|
|
189
|
+
- **Structure:** Place tests in `test/unit/`, mirroring the `src/` structure.
|
|
190
|
+
- **Mocking:** Mock all external dependencies (DB, services) in tests.
|
|
191
|
+
- **AI Testing:** When generating new logic, always add or update tests.
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## 9. Minimal Usage Example
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
import Fastify from "fastify";
|
|
199
|
+
import { MicroService } from "@sentzunhat/zacatl";
|
|
200
|
+
|
|
201
|
+
const fastifyApp = Fastify();
|
|
202
|
+
|
|
203
|
+
const microservice = new MicroService({
|
|
204
|
+
architecture: {
|
|
205
|
+
application: {
|
|
206
|
+
entryPoints: {
|
|
207
|
+
rest: {
|
|
208
|
+
hookHandlers: [], // Add hook handler classes
|
|
209
|
+
routeHandlers: [], // Add route handler classes
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
domain: { providers: [] }, // Add domain provider classes
|
|
214
|
+
infrastructure: { repositories: [] }, // Add repository classes
|
|
215
|
+
service: {
|
|
216
|
+
name: "my-service",
|
|
217
|
+
server: {
|
|
218
|
+
type: "SERVER",
|
|
219
|
+
vendor: "FASTIFY",
|
|
220
|
+
instance: fastifyApp,
|
|
221
|
+
},
|
|
222
|
+
databases: [
|
|
223
|
+
// Example for MongoDB:
|
|
224
|
+
// {
|
|
225
|
+
// vendor: "MONGOOSE",
|
|
226
|
+
// instance: new Mongoose(),
|
|
227
|
+
// connectionString: "mongodb://localhost/mydb",
|
|
228
|
+
// }
|
|
229
|
+
],
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
await microservice.start({ port: 9000 });
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## 10. Configuration and Environment Variables
|
|
240
|
+
|
|
241
|
+
- **Localization:** Place locale JSON files in `src/locales/` (e.g., `en.json`)
|
|
242
|
+
- **Environment Variables:**
|
|
171
243
|
- `SERVICE_NAME` - Service name
|
|
172
244
|
- `NODE_ENV` - Environment (development, production, test)
|
|
173
245
|
- `CONNECTION_STRING` - Database connection string
|
|
174
246
|
|
|
175
|
-
|
|
247
|
+
---
|
|
176
248
|
|
|
177
|
-
|
|
249
|
+
## 11. Extending the Codebase (for Humans & AI)
|
|
178
250
|
|
|
179
|
-
-
|
|
180
|
-
-
|
|
181
|
-
-
|
|
182
|
-
- `
|
|
251
|
+
- Add new features by creating new handlers, services, or repositories in the appropriate layer.
|
|
252
|
+
- Register all new classes in the DI container.
|
|
253
|
+
- Write tests for all new logic.
|
|
254
|
+
- Update YAML docs (`context.yaml`, `guidelines.yaml`, `patterns.yaml`, `mongodb.yaml`) with new patterns or conventions.
|
|
183
255
|
|
|
184
|
-
|
|
256
|
+
---
|
|
185
257
|
|
|
186
|
-
|
|
258
|
+
## 12. Documentation References
|
|
187
259
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
```
|
|
260
|
+
- [`context.yaml`](./context.yaml): Architecture, components, and project context
|
|
261
|
+
- [`guidelines.yaml`](./guidelines.yaml): Coding standards and best practices
|
|
262
|
+
- [`patterns.yaml`](./patterns.yaml): Design and usage patterns
|
|
263
|
+
- [`mongodb.yaml`](./mongodb.yaml): MongoDB schema guidelines
|
|
193
264
|
|
|
194
|
-
|
|
265
|
+
---
|
|
195
266
|
|
|
196
|
-
## Contributing
|
|
267
|
+
## 13. Contributing Workflow
|
|
197
268
|
|
|
198
|
-
|
|
269
|
+
### For Humans
|
|
199
270
|
|
|
200
271
|
1. Fork the repository
|
|
201
272
|
2. Create your feature branch: `git checkout -b feature/amazing-feature`
|
|
202
273
|
3. Commit your changes: `git commit -m 'Add some amazing feature'`
|
|
203
274
|
4. Push to the branch: `git push origin feature/amazing-feature`
|
|
204
275
|
5. Open a Pull Request
|
|
276
|
+
6. Ensure all tests pass and docs are updated
|
|
205
277
|
|
|
206
|
-
|
|
278
|
+
### For AI Agents
|
|
207
279
|
|
|
208
|
-
|
|
280
|
+
- Parse YAML docs for context and conventions
|
|
281
|
+
- Register new code in the DI container
|
|
282
|
+
- Add or update tests in `test/unit/`
|
|
283
|
+
- Update YAML docs with new features or patterns
|
|
209
284
|
|
|
210
285
|
---
|
|
211
286
|
|
|
212
|
-
|
|
287
|
+
## 14. License and Maintainers
|
|
288
|
+
|
|
289
|
+
- **License:** MIT License © 2025 Sentzunhat
|
|
290
|
+
- **Maintainer:** Diego Beltran ([LinkedIn](https://www.linkedin.com/in/diego-beltran))
|
|
291
|
+
- **Project URL:** [GitHub](https://github.com/sentzunhat/zacatl)
|
|
292
|
+
|
|
293
|
+
---
|
|
213
294
|
|
|
214
|
-
|
|
295
|
+
_For all details, see the YAML documentation files above. Zacatl is designed for seamless collaboration between humans and AI agents._
|
package/context.yaml
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Zacatl Project: Structured Context
|
|
2
|
+
|
|
3
|
+
components:
|
|
4
|
+
- name: MicroService
|
|
5
|
+
type: class
|
|
6
|
+
file: src/micro-service/architecture/platform/micro-service.ts
|
|
7
|
+
description: |
|
|
8
|
+
The main orchestrator for the microservice. Bootstraps Application, Domain, Infrastructure, and Service layers. Handles startup, dependency registration, and handler registration.
|
|
9
|
+
methods:
|
|
10
|
+
- name: constructor
|
|
11
|
+
description: Initializes all architecture layers from config.
|
|
12
|
+
- name: start
|
|
13
|
+
description: Starts the service, configures databases, registers handlers, and launches the HTTP server.
|
|
14
|
+
dependencies:
|
|
15
|
+
- Application
|
|
16
|
+
- Domain
|
|
17
|
+
- Infrastructure
|
|
18
|
+
- Service
|
|
19
|
+
|
|
20
|
+
- name: Application
|
|
21
|
+
type: class
|
|
22
|
+
file: src/micro-service/architecture/application/application.ts
|
|
23
|
+
description: |
|
|
24
|
+
Handles HTTP entry points (REST), validation, and delegates to domain logic. Registers route and hook handlers using DI.
|
|
25
|
+
methods:
|
|
26
|
+
- name: constructor
|
|
27
|
+
description: Configures i18n and stores entry point config.
|
|
28
|
+
- name: start
|
|
29
|
+
description: Registers and stores REST hook and route handlers.
|
|
30
|
+
dependencies:
|
|
31
|
+
- AbstractArchitecture
|
|
32
|
+
- HookHandler
|
|
33
|
+
- RouteHandler
|
|
34
|
+
|
|
35
|
+
- name: Infrastructure
|
|
36
|
+
type: class
|
|
37
|
+
file: src/micro-service/architecture/infrastructure/infrastructure.ts
|
|
38
|
+
description: |
|
|
39
|
+
Registers and manages repositories (e.g., MongoDB) for persistence. Uses DI for repository registration.
|
|
40
|
+
methods:
|
|
41
|
+
- name: constructor
|
|
42
|
+
description: Stores repository config.
|
|
43
|
+
- name: start
|
|
44
|
+
description: Registers repositories in DI container.
|
|
45
|
+
dependencies:
|
|
46
|
+
- AbstractArchitecture
|
|
47
|
+
|
|
48
|
+
- name: BaseRepository
|
|
49
|
+
type: abstract class
|
|
50
|
+
file: src/micro-service/architecture/infrastructure/repositories/abstract.ts
|
|
51
|
+
description: |
|
|
52
|
+
Abstract base for MongoDB repositories. Handles model creation, lazy initialization, and CRUD methods. Ensures returned documents have an id field.
|
|
53
|
+
methods:
|
|
54
|
+
- name: constructor
|
|
55
|
+
description: Sets up Mongoose model and schema.
|
|
56
|
+
- name: findById
|
|
57
|
+
description: Finds a document by id and returns a lean object with id.
|
|
58
|
+
- name: create
|
|
59
|
+
description: Creates a new document and returns a lean object with id.
|
|
60
|
+
- name: update
|
|
61
|
+
description: Updates a document by id and returns a lean object with id.
|
|
62
|
+
- name: delete
|
|
63
|
+
description: Deletes a document by id and returns a lean object with id.
|
|
64
|
+
dependencies:
|
|
65
|
+
- mongoose
|
|
66
|
+
- tsyringe
|
|
67
|
+
|
|
68
|
+
- name: AbstractArchitecture
|
|
69
|
+
type: abstract class
|
|
70
|
+
file: src/micro-service/architecture/architecture.ts
|
|
71
|
+
description: |
|
|
72
|
+
Provides generic dependency registration helpers for all architecture layers. Enforces a start() contract.
|
|
73
|
+
methods:
|
|
74
|
+
- name: registerDependencies
|
|
75
|
+
description: Registers an array of classes in the DI container.
|
|
76
|
+
- name: registerAndStoreDependencies
|
|
77
|
+
description: Registers classes and stores resolved instances in a provided array.
|
|
78
|
+
- name: start
|
|
79
|
+
description: Abstract method to be implemented by subclasses.
|
|
80
|
+
dependencies:
|
|
81
|
+
- tsyringe
|
|
82
|
+
|
|
83
|
+
- name: CustomError
|
|
84
|
+
type: class
|
|
85
|
+
file: src/error/custom.ts
|
|
86
|
+
description: |
|
|
87
|
+
Base class for all custom errors. Supports metadata, error codes, and unique IDs. Used for structured error handling.
|
|
88
|
+
methods:
|
|
89
|
+
- name: constructor
|
|
90
|
+
description: Initializes error with message, code, reason, metadata, and stack trace.
|
|
91
|
+
|
|
92
|
+
- name: getConfigOrThrow
|
|
93
|
+
type: function
|
|
94
|
+
file: src/configuration.ts
|
|
95
|
+
description: |
|
|
96
|
+
Retrieves configuration values from the config system. Throws if missing.
|
|
97
|
+
|
|
98
|
+
- name: defaultLogger
|
|
99
|
+
type: object
|
|
100
|
+
file: src/logs.ts
|
|
101
|
+
description: |
|
|
102
|
+
Pino-based logger configured with environment and service metadata. Used for structured logging.
|
|
103
|
+
|
|
104
|
+
- name: Utility Exports
|
|
105
|
+
type: module
|
|
106
|
+
file: src/utils/index.ts
|
|
107
|
+
description: |
|
|
108
|
+
Exports utility functions (e.g., base64, hmac) for use throughout the codebase.
|
|
109
|
+
|
|
110
|
+
layers:
|
|
111
|
+
- name: Platform
|
|
112
|
+
description: Bootstraps the app, configures DI, starts the server.
|
|
113
|
+
files:
|
|
114
|
+
- src/micro-service/architecture/platform/micro-service.ts
|
|
115
|
+
- src/micro-service/architecture/platform/service/service.ts
|
|
116
|
+
- name: Application
|
|
117
|
+
description: Handles HTTP requests, validation, delegates to domain logic.
|
|
118
|
+
files:
|
|
119
|
+
- src/micro-service/architecture/application/application.ts
|
|
120
|
+
- src/micro-service/architecture/application/entry-points/rest/route-handlers/
|
|
121
|
+
- src/micro-service/architecture/application/entry-points/rest/hook-handlers/
|
|
122
|
+
- name: Domain
|
|
123
|
+
description: Pure business rules, models, and logic (no infrastructure deps).
|
|
124
|
+
files:
|
|
125
|
+
- src/micro-service/architecture/domain/
|
|
126
|
+
- name: Infrastructure
|
|
127
|
+
description: Persistence (MongoDB repositories), external service integration.
|
|
128
|
+
files:
|
|
129
|
+
- src/micro-service/architecture/infrastructure/repositories/
|
|
130
|
+
- src/micro-service/architecture/infrastructure/infrastructure.ts
|
|
131
|
+
|
|
132
|
+
patterns:
|
|
133
|
+
- Dependency Injection: All services, repositories, and handlers are registered in the DI container (tsyringe). Never instantiate dependencies directly.
|
|
134
|
+
- Error Handling: Custom error classes extend CustomError. Errors are thrown and bubble up to Fastify's error handler unless custom handling is needed.
|
|
135
|
+
- Validation: All request/response validation uses zod schemas.
|
|
136
|
+
- Testing: All business logic, handlers, and utilities are unit tested using vitest. Tests mirror the src/ structure.
|
|
137
|
+
|
|
138
|
+
config:
|
|
139
|
+
- Localization: Locale JSON files in src/locales/ (e.g., en.json)
|
|
140
|
+
- Environment Variables:
|
|
141
|
+
- SERVICE_NAME: Service name
|
|
142
|
+
- NODE_ENV: Environment (development, production, test)
|
|
143
|
+
- CONNECTION_STRING: Database connection string
|
|
144
|
+
- APP_VERSION: Application version
|
|
145
|
+
- APP_ENV: Application environment
|
|
146
|
+
|
|
147
|
+
testing:
|
|
148
|
+
- All tests are in test/unit/, mirroring src/ structure.
|
|
149
|
+
- Uses vitest for all tests.
|
|
150
|
+
- Mocks external dependencies (DB, services) in tests.
|
|
151
|
+
- Test helpers in test/unit/helpers/.
|
package/guidelines.yaml
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Zacatl Project: Coding Guidelines & Best Practices
|
|
2
|
+
|
|
3
|
+
naming:
|
|
4
|
+
file_folder:
|
|
5
|
+
- Use lowercase and hyphens (e.g., user-repository.ts, route-handlers/)
|
|
6
|
+
variables:
|
|
7
|
+
- Use meaningful, descriptive names
|
|
8
|
+
classes:
|
|
9
|
+
- Use PascalCase for class names
|
|
10
|
+
functions:
|
|
11
|
+
- Use camelCase for function and method names
|
|
12
|
+
|
|
13
|
+
style:
|
|
14
|
+
- Write clean, modular, and straightforward code
|
|
15
|
+
- Use strong typing and TypeScript generics where appropriate
|
|
16
|
+
- Prefer async/await for asynchronous code
|
|
17
|
+
- Keep functions short, focused, and readable
|
|
18
|
+
- Prefer clarity over excessive comments; use tests to document behavior
|
|
19
|
+
- Avoid code duplication (DRY principle); extract reusable logic into utils/ or shared services
|
|
20
|
+
- Use modern TypeScript/ES features
|
|
21
|
+
|
|
22
|
+
architecture:
|
|
23
|
+
- Follow layered (hexagonal) architecture: Platform → Application → Domain → Infrastructure
|
|
24
|
+
- Strict separation of concerns between layers
|
|
25
|
+
- Application: Handles HTTP, validation, delegates to domain
|
|
26
|
+
- Domain: Pure business logic, no infrastructure dependencies
|
|
27
|
+
- Infrastructure: Persistence, external integrations
|
|
28
|
+
- Platform: Bootstraps, configures DI, starts server
|
|
29
|
+
|
|
30
|
+
patterns:
|
|
31
|
+
dependency_injection:
|
|
32
|
+
- Use tsyringe for all DI
|
|
33
|
+
- Register all services, repositories, and handlers in the DI container
|
|
34
|
+
- Never instantiate dependencies directly; always resolve via DI
|
|
35
|
+
error_handling:
|
|
36
|
+
- All custom errors extend CustomError (src/error/custom.ts)
|
|
37
|
+
- Use CustomError.handle(error) in middleware or route handlers to log/format errors
|
|
38
|
+
- Always include relevant metadata and a clear message in error instances
|
|
39
|
+
- Throw errors for exceptional cases; do not return error objects
|
|
40
|
+
- Let errors bubble up to Fastify’s error handler unless custom handling is needed
|
|
41
|
+
validation:
|
|
42
|
+
- Use zod schemas for all request/response validation
|
|
43
|
+
testing:
|
|
44
|
+
- Use vitest for all tests
|
|
45
|
+
- Place tests in test/, mirroring src/ structure
|
|
46
|
+
- Write unit tests for all logic
|
|
47
|
+
- Mock all external dependencies (DB, services) in tests
|
|
48
|
+
- Use descriptive test names and group related tests in files named after the module under test
|
|
49
|
+
- Run tests using the vitest CLI
|
|
50
|
+
documentation:
|
|
51
|
+
- Update context.yaml and guidelines.yaml with any new patterns, conventions, or architectural changes
|
|
52
|
+
- Document new features, patterns, or conventions in YAML, not Markdown
|
|
53
|
+
|
|
54
|
+
mongodb:
|
|
55
|
+
- Define all schemas in infrastructure/repositories/
|
|
56
|
+
- Embed related data for performance when possible
|
|
57
|
+
- Keep schemas minimal and use concise property names
|
|
58
|
+
- Use references for large or independent data
|
|
59
|
+
- Ensure documents stay well below MongoDB’s 16MB limit
|
|
60
|
+
- Define indexes for frequently queried fields
|
|
61
|
+
- Use Mongoose and zod for schema and runtime validation
|
|
62
|
+
- Consider schema versioning for breaking changes
|
|
63
|
+
|
|
64
|
+
extending:
|
|
65
|
+
- Add new features by creating new handlers, services, or repositories in the appropriate layer
|
|
66
|
+
- Register all new classes in the DI container
|
|
67
|
+
- Write tests for all new logic
|
|
68
|
+
- Update context.yaml and guidelines.yaml with new patterns or conventions
|
|
69
|
+
|
|
70
|
+
security:
|
|
71
|
+
- Validate all inputs
|
|
72
|
+
- Handle errors gracefully
|
|
73
|
+
- Never expose sensitive data
|
|
74
|
+
- Sanitize and validate all external data
|
package/mongodb.yaml
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Zacatl Project: MongoDB Schema Design Guidelines
|
|
2
|
+
|
|
3
|
+
origin: mongodb_schema_design_guidelines.md
|
|
4
|
+
source: MongoDB_schema_design_guidelines.pdf
|
|
5
|
+
|
|
6
|
+
principles:
|
|
7
|
+
- favor_embedding:
|
|
8
|
+
rule: Embed related data within a single document when possible to improve performance by reducing the need for joins/queries.
|
|
9
|
+
rationale: Embedded documents ensure related data is retrieved together, enhancing read performance for one-to-few/one-to-many relationships.
|
|
10
|
+
- minimalism_and_simplicity:
|
|
11
|
+
rule: Design schemas with simplicity and minimalism. Use nested objects to reflect natural data hierarchies.
|
|
12
|
+
rationale: Minimal schemas are easier to understand, maintain, and scale.
|
|
13
|
+
- property_naming:
|
|
14
|
+
rule: Use single-word property names when possible; otherwise, limit to two words.
|
|
15
|
+
rationale: Short, concise property names reduce errors and improve readability.
|
|
16
|
+
- document_size_and_cardinality:
|
|
17
|
+
rule: Keep document size within MongoDB’s 16MB limit. Avoid embedding data that could grow unbounded (high-cardinality relationships).
|
|
18
|
+
rationale: Large documents degrade performance and complicate replication/backup. Use references for large/independent data.
|
|
19
|
+
- lifecycle_consistency:
|
|
20
|
+
rule: Embed data only if it shares a lifecycle with the parent document. Use references if embedded data is accessed/updated independently.
|
|
21
|
+
rationale: Aligning lifecycles ensures consistent, predictable schema behavior.
|
|
22
|
+
|
|
23
|
+
flexibility:
|
|
24
|
+
- These guidelines are best practices and should be adapted to specific application requirements and data access patterns.
|
|
25
|
+
- The recommendation for concise property names is flexible, but clarity and consistency are critical.
|
|
26
|
+
|
|
27
|
+
conclusion:
|
|
28
|
+
- Following these guidelines will help ensure MongoDB schemas are optimized for performance, maintainability, and scalability.
|
|
29
|
+
- Adapt as needed for your application’s needs.
|
package/package.json
CHANGED
|
@@ -2,12 +2,43 @@
|
|
|
2
2
|
"name": "@sentzunhat/zacatl",
|
|
3
3
|
"main": "src/index.ts",
|
|
4
4
|
"module": "src/index.ts",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.7",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/sentzunhat/zacatl.git"
|
|
9
9
|
},
|
|
10
|
-
"description": "",
|
|
10
|
+
"description": "A modular, high-performance TypeScript microservice framework for Node.js, featuring layered architecture, dependency injection, and robust validation for building scalable APIs and distributed systems.",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"typescript",
|
|
13
|
+
"microservice",
|
|
14
|
+
"microservices",
|
|
15
|
+
"framework",
|
|
16
|
+
"nodejs",
|
|
17
|
+
"dependency-injection",
|
|
18
|
+
"hexagonal-architecture",
|
|
19
|
+
"layered-architecture",
|
|
20
|
+
"clean-architecture",
|
|
21
|
+
"fastify",
|
|
22
|
+
"mongodb",
|
|
23
|
+
"mongoose",
|
|
24
|
+
"zod",
|
|
25
|
+
"validation",
|
|
26
|
+
"vitest",
|
|
27
|
+
"testing",
|
|
28
|
+
"api",
|
|
29
|
+
"rest-api",
|
|
30
|
+
"backend",
|
|
31
|
+
"server",
|
|
32
|
+
"enterprise",
|
|
33
|
+
"scalable",
|
|
34
|
+
"modular",
|
|
35
|
+
"tsyringe",
|
|
36
|
+
"pino",
|
|
37
|
+
"logging",
|
|
38
|
+
"i18n",
|
|
39
|
+
"internationalization",
|
|
40
|
+
"artisan"
|
|
41
|
+
],
|
|
11
42
|
"author": "Diego Beltran <beltrd@gmail.com> (https://sentzunhat.com)",
|
|
12
43
|
"contributors": [
|
|
13
44
|
{
|