create-charcole 2.0.4 → 2.2.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.
Files changed (100) hide show
  1. package/CHANGELOG.md +290 -14
  2. package/README.md +258 -312
  3. package/bin/index.js +392 -55
  4. package/bin/lib/pkgManager.js +8 -25
  5. package/bin/lib/templateHandler.js +5 -42
  6. package/create-charcole-2.1.0.tgz +0 -0
  7. package/package.json +2 -2
  8. package/packages/swagger/BACKWARD_COMPATIBILITY.md +145 -0
  9. package/packages/swagger/CHANGELOG.md +404 -0
  10. package/packages/swagger/README.md +578 -0
  11. package/packages/swagger/charcole-swagger-1.0.0.tgz +0 -0
  12. package/packages/swagger/package-lock.json +1715 -0
  13. package/packages/swagger/package.json +44 -0
  14. package/packages/swagger/src/helpers.js +427 -0
  15. package/packages/swagger/src/index.d.ts +126 -0
  16. package/packages/swagger/src/index.js +12 -0
  17. package/packages/swagger/src/setup.js +100 -0
  18. package/template/js/.env.example +8 -0
  19. package/template/js/README.md +128 -5
  20. package/template/js/basePackage.json +11 -13
  21. package/template/js/src/app.js +8 -2
  22. package/template/js/src/config/swagger.config.js +15 -0
  23. package/template/js/src/lib/swagger/SWAGGER_GUIDE.md +561 -0
  24. package/template/js/src/modules/auth/auth.constants.js +3 -0
  25. package/template/js/src/modules/auth/auth.controller.js +29 -0
  26. package/template/js/src/modules/auth/auth.middlewares.js +19 -0
  27. package/template/js/src/modules/auth/auth.routes.js +131 -0
  28. package/template/js/src/modules/auth/auth.schemas.js +60 -0
  29. package/template/js/src/modules/auth/auth.service.js +67 -0
  30. package/template/js/src/modules/auth/package.json +6 -0
  31. package/template/js/src/modules/health/controller.js +104 -3
  32. package/template/js/src/modules/swagger/charcole-swagger-1.0.0.tgz +0 -0
  33. package/template/js/src/modules/swagger/package.json +5 -0
  34. package/template/js/src/repositories/user.repo.js +19 -0
  35. package/template/js/src/routes/index.js +25 -0
  36. package/template/js/src/routes/protected.js +57 -0
  37. package/template/ts/.env.example +8 -0
  38. package/template/ts/README.md +128 -5
  39. package/template/ts/basePackage.json +19 -15
  40. package/template/ts/build.js +46 -0
  41. package/template/ts/src/app.ts +12 -7
  42. package/template/ts/src/config/swagger.config.ts +30 -0
  43. package/template/ts/src/lib/swagger/SWAGGER_GUIDE.md +561 -0
  44. package/template/ts/src/middlewares/errorHandler.ts +15 -23
  45. package/template/ts/src/middlewares/requestLogger.ts +1 -1
  46. package/template/ts/src/middlewares/validateRequest.ts +1 -1
  47. package/template/ts/src/modules/auth/auth.constants.ts +6 -0
  48. package/template/ts/src/modules/auth/auth.controller.ts +32 -0
  49. package/template/ts/src/modules/auth/auth.middlewares.ts +46 -0
  50. package/template/ts/src/modules/auth/auth.routes.ts +52 -0
  51. package/template/ts/src/modules/auth/auth.schemas.ts +73 -0
  52. package/template/ts/src/modules/auth/auth.service.ts +106 -0
  53. package/template/ts/src/modules/auth/package.json +10 -0
  54. package/template/ts/src/modules/health/controller.ts +61 -45
  55. package/template/ts/src/modules/swagger/charcole-swagger-1.0.0.tgz +0 -0
  56. package/template/ts/src/modules/swagger/package.json +5 -0
  57. package/template/ts/src/repositories/user.repo.ts +33 -0
  58. package/template/ts/src/routes/index.ts +24 -0
  59. package/template/ts/src/routes/protected.ts +46 -0
  60. package/template/ts/src/server.ts +3 -4
  61. package/template/ts/src/utils/logger.ts +1 -1
  62. package/template/ts/tsconfig.json +14 -7
  63. package/tmpclaude-1049-cwd +1 -0
  64. package/tmpclaude-3e37-cwd +1 -0
  65. package/tmpclaude-4d73-cwd +1 -0
  66. package/tmpclaude-8a8e-cwd +1 -0
  67. package/template/js/ARCHITECTURE_DIAGRAMS.md +0 -283
  68. package/template/js/CHECKLIST.md +0 -279
  69. package/template/js/COMPLETE.md +0 -405
  70. package/template/js/ERROR_HANDLING.md +0 -393
  71. package/template/js/IMPLEMENTATION.md +0 -368
  72. package/template/js/IMPLEMENTATION_COMPLETE.md +0 -363
  73. package/template/js/INDEX.md +0 -290
  74. package/template/js/QUICK_REFERENCE.md +0 -270
  75. package/template/js/package.json +0 -28
  76. package/template/js/src/routes.js +0 -17
  77. package/template/js/test-api.js +0 -100
  78. package/template/ts/ARCHITECTURE_DIAGRAMS.md +0 -283
  79. package/template/ts/CHECKLIST.md +0 -279
  80. package/template/ts/COMPLETE.md +0 -405
  81. package/template/ts/ERROR_HANDLING.md +0 -393
  82. package/template/ts/IMPLEMENTATION.md +0 -368
  83. package/template/ts/IMPLEMENTATION_COMPLETE.md +0 -363
  84. package/template/ts/INDEX.md +0 -290
  85. package/template/ts/QUICK_REFERENCE.md +0 -270
  86. package/template/ts/package.json +0 -32
  87. package/template/ts/src/app.js +0 -75
  88. package/template/ts/src/config/constants.js +0 -20
  89. package/template/ts/src/config/env.js +0 -26
  90. package/template/ts/src/middlewares/errorHandler.js +0 -180
  91. package/template/ts/src/middlewares/requestLogger.js +0 -33
  92. package/template/ts/src/middlewares/validateRequest.js +0 -42
  93. package/template/ts/src/modules/health/controller.js +0 -50
  94. package/template/ts/src/routes.js +0 -17
  95. package/template/ts/src/routes.ts +0 -16
  96. package/template/ts/src/server.js +0 -38
  97. package/template/ts/src/utils/AppError.js +0 -182
  98. package/template/ts/src/utils/logger.js +0 -73
  99. package/template/ts/src/utils/response.js +0 -51
  100. package/template/ts/test-api.js +0 -100
package/README.md CHANGED
@@ -1,408 +1,354 @@
1
- # Charcole API
1
+ # Charcole API v2.2
2
2
 
3
- > **Charcole is a production-grade Node.js backend starter CLI that scaffolds enterprise-ready Express APIs with first-class TypeScript or JavaScript support, centralized error handling, Zod validation, and structured logging out of the box.**
3
+ > **Charcole v2.2 is a production-grade Node.js backend starter CLI that scaffolds enterprise-ready Express APIs with first-class TypeScript or JavaScript support, centralized error handling, Zod validation, structured logging, optional JWT authentication, **auto-generated Swagger documentation**, and a revolutionary repository pattern for database abstraction.**
4
4
 
5
5
  [![Node.js](https://img.shields.io/badge/Node.js-18+-green.svg)](https://nodejs.org/)
6
6
  [![Express.js](https://img.shields.io/badge/Express-4.18+-blue.svg)](https://expressjs.com/)
7
7
  [![Zod](https://img.shields.io/badge/Zod-3.22+-purple.svg)](https://zod.dev/)
8
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
8
9
  [![License: ISC](https://img.shields.io/badge/License-ISC-yellow.svg)](LICENSE)
9
10
 
10
- ## 🎯 What This Is
11
+ ## What's New in v2.2
11
12
 
12
- A **production-ready Node.js Express backend** with:
13
+ ### 🎯 Auto-Generated Swagger Documentation (@charcoles/swagger)
13
14
 
14
- - **TypeScript or JavaScript** templates (v2 feature)
15
- - ✅ **Centralized Error Handling** - Every error flows through one place
16
- - ✅ **Error Classification** - Operational vs Programmer errors distinguished
17
- - ✅ **Zod Validation** - Type-safe schema validation with automatic error formatting
18
- - ✅ **Structured Logging** - Color-coded logs with context and stack traces
19
- - ✅ **Consistent JSON Responses** - Standardized format across all endpoints
20
- - ✅ **Production-Safe** - Internal details hidden from clients in production
21
- - ✅ **Async Error Handling** - Promise rejection leaks prevented with asyncHandler
22
- - ✅ **Graceful Shutdown** - Proper cleanup on SIGTERM/SIGINT
23
- - ✅ **Request Logging** - Method, path, status, duration, IP automatically tracked
24
- - ✅ **Unhandled Exception Catching** - All edge cases caught and logged
15
+ The game-changing feature that eliminates 60-80% of API documentation overhead:
25
16
 
26
- ## 🚀 Quick Start
17
+ - **Zero schema duplication** - Define Zod schemas once, auto-generate OpenAPI specs
18
+ - **Effortless documentation** - Minimal JSDoc comments with `$ref` to Zod schemas
19
+ - **Built-in response templates** - Common responses (Success, ValidationError, Unauthorized, NotFound) included
20
+ - **Always in sync** - Impossible for docs to drift from validation schemas
21
+ - **Optional module** - Include/exclude during project creation
22
+ - **Framework agnostic** - Works with any Express.js project via `npm install @charcoles/swagger`
27
23
 
28
- ### Installation
24
+ **Before (76 lines of manual duplication):**
29
25
 
30
- ```bash
31
- # Create your charcole app now
32
- npx create-charcole@latest charcole-demo
33
-
34
- # Configure environment
35
- cp .env.example .env
36
-
37
- # Start development server (with auto-reload)
38
- npm run dev
39
-
40
- # OR start production server
41
- npm start
42
- ```
43
-
44
- Server runs on `http://localhost:3000` by default.
45
-
46
- ## 📋 Key Features
47
-
48
- ### 🛡️ Enterprise-Grade Error Handling
49
-
50
- **No More `res.status(500).json(...)`**
51
-
52
- Every error in your application flows through a centralized global error handler that:
53
-
54
- 1. **Normalizes** all error types (ZodError, TypeError, custom AppError, etc.)
55
- 2. **Classifies** errors as operational (expected) or programmer (bugs)
56
- 3. **Logs** appropriately (WARN for operational, ERROR with stack for programmer)
57
- 4. **Sanitizes** responses (hides details in production, shows context in dev)
58
-
59
- ```javascript
60
- // ✅ Throw AppError - ALWAYS
61
- throw new NotFoundError("User", { id: userId });
62
- throw new ValidationError("Invalid input", errors);
63
- throw new ConflictError("Email already exists");
26
+ ```typescript
27
+ // Zod schema for validation
28
+ const registerSchema = z.object({
29
+ email: z.string().email(),
30
+ password: z.string().min(8),
31
+ });
64
32
 
65
- // Never do this
66
- res.status(404).json({ error: "Not found" });
33
+ // Manual OpenAPI schema (duplicate!)
34
+ /**
35
+ * @swagger
36
+ * /api/auth/register:
37
+ * post:
38
+ * requestBody:
39
+ * schema:
40
+ * type: object
41
+ * properties:
42
+ * email:
43
+ * type: string
44
+ * format: email
45
+ * password:
46
+ * type: string
47
+ * minLength: 8
48
+ * ... 60 more lines
49
+ */
67
50
  ```
68
51
 
69
- ### 🔐 Type-Safe Validation
52
+ **After with @charcoles/swagger (20 lines, zero duplication):**
70
53
 
71
- ```javascript
72
- import { z } from "zod";
73
- import { validateRequest } from "./middlewares/validateRequest.js";
74
-
75
- const createUserSchema = z.object({
76
- body: z.object({
77
- email: z.string().email(),
78
- name: z.string().min(1),
79
- }),
54
+ ```typescript
55
+ // 1. Register schema once in swagger.config.ts
56
+ setupSwagger(app, {
57
+ schemas: { registerSchema }, // Auto-converted!
80
58
  });
81
59
 
82
- router.post("/users", validateRequest(createUserSchema), handler);
60
+ // 2. Reference in JSDoc
61
+ /**
62
+ * @swagger
63
+ * /api/auth/register:
64
+ * post:
65
+ * summary: Register user
66
+ * requestBody:
67
+ * content:
68
+ * application/json:
69
+ * schema:
70
+ * $ref: '#/components/schemas/registerSchema'
71
+ * responses:
72
+ * 201:
73
+ * $ref: '#/components/responses/Success'
74
+ * 400:
75
+ * $ref: '#/components/responses/ValidationError'
76
+ */
83
77
  ```
84
78
 
85
- ### 📝 Structured Logging
79
+ **Result:** Change your Zod schema → Swagger updates automatically! 🎉
86
80
 
87
- ```javascript
88
- import { logger } from "./utils/logger.js";
81
+ ### Previous Features (v2.1)
89
82
 
90
- logger.debug("Debug message", { data: true });
91
- logger.info("Info message", { data: true });
92
- logger.warn("Warning message", { data: true });
93
- logger.error("Error message", { data: true });
94
- ```
83
+ #### Revolutionary Repository Pattern
95
84
 
96
- ### 📊 Consistent JSON Responses
85
+ - **Database abstraction layer** - Switch databases without changing business logic
86
+ - **In-memory repository included** - Test APIs instantly without database setup
87
+ - **Clean separation** - Business logic stays independent of database implementation
88
+ - **Future-proof** - Easy migration between MongoDB, PostgreSQL, MySQL, etc.
97
89
 
98
- All responses follow the same format:
90
+ #### Optional JWT Authentication Module
99
91
 
100
- **Success:**
92
+ - **Complete auth system** - Register, login, logout, protected routes
93
+ - **JWT-based authentication** - Stateless, scalable token management
94
+ - **Password hashing** - Secure bcrypt password handling
95
+ - **Ready-to-use** - Production-ready auth APIs out of the box
96
+ - **Modular design** - Include/exclude during project creation
101
97
 
102
- ```json
103
- {
104
- "success": true,
105
- "message": "User created successfully",
106
- "data": { "id": "123", "name": "John" },
107
- "timestamp": "2024-01-20T12:00:00.000Z"
108
- }
109
- ```
98
+ ## Quick Start
99
+
100
+ ```bash
101
+ # Create your charcole app now (with or without project name)
102
+ npx create-charcole@latest my-awesome-api
110
103
 
111
- **Error:**
104
+ # OR (interactive mode)
105
+ npx create-charcole@latest
112
106
 
113
- ```json
114
- {
115
- "success": false,
116
- "message": "User not found",
117
- "code": "NOT_FOUND",
118
- "statusCode": 404,
119
- "context": { "id": "999" },
120
- "timestamp": "2024-01-20T12:00:00.000Z"
121
- }
122
- ```
107
+ # Follow prompts to select:
108
+ # 1. Language: TypeScript or JavaScript
109
+ # 2. JWT Authentication: Yes/No (includes complete auth system)
110
+ # 3. Swagger Documentation: Yes/No (auto-generated from Zod schemas)
123
111
 
124
- **Validation Error:**
125
-
126
- ```json
127
- {
128
- "success": false,
129
- "message": "Validation failed",
130
- "code": "VALIDATION_ERROR",
131
- "statusCode": 422,
132
- "errors": [
133
- { "field": "email", "message": "Invalid email", "code": "invalid_email" }
134
- ],
135
- "timestamp": "2024-01-20T12:00:00.000Z"
136
- }
137
- ```
112
+ # Configure environment
113
+ cp .env.example .env
138
114
 
139
- ## 🏗️ Error Classes
115
+ # Start development server (with auto-reload)
116
+ npm run dev
140
117
 
141
- Use these specialized error classes:
118
+ # Visit Swagger UI (if swagger enabled)
119
+ # http://localhost:3000/api-docs
142
120
 
143
- ```javascript
144
- import {
145
- AppError, // Base class
146
- ValidationError, // 422 - Input validation failed
147
- BadRequestError, // 400 - Malformed request
148
- AuthenticationError, // 401 - Invalid credentials
149
- AuthorizationError, // 403 - Permission denied
150
- NotFoundError, // 404 - Resource not found
151
- ConflictError, // 409 - Duplicate/conflict
152
- InternalServerError, // 500 - Unexpected error
153
- } from "./middlewares/errorHandler.js";
121
+ # OR start production server
122
+ npm start
154
123
  ```
155
124
 
156
- ## 📚 Documentation
125
+ Server runs on http://localhost:3000 by default.
157
126
 
158
- | Document | Purpose |
159
- | ------------------------------------------------- | --------------------------------- |
160
- | [Getting Started](template/README.md) | Setup & directory structure guide |
161
- | [Quick Reference](QUICK_REFERENCE.md) | Quick patterns & golden rules |
162
- | [Error Handling Guide](ERROR_HANDLING.md) | Comprehensive error documentation |
163
- | [Architecture Diagrams](ARCHITECTURE_DIAGRAMS.md) | Visual system architecture |
164
- | [Full Implementation](IMPLEMENTATION_COMPLETE.md) | Complete implementation details |
127
+ ## Swagger Documentation (New in v2.2)
165
128
 
166
- ## 🎓 4 Golden Rules
129
+ ### The Problem
167
130
 
168
- 1. **Wrap async handlers** with `asyncHandler`
131
+ Traditional API documentation requires writing the same schema twice:
169
132
 
170
- ```javascript
171
- router.get("/users/:id", asyncHandler(async (req, res) => { ... }))
172
- ```
133
+ 1. Once in Zod for validation
134
+ 2. Again in OpenAPI/Swagger YAML
173
135
 
174
- 2. **Throw AppError** (never use `res.status().json()`)
136
+ This leads to:
175
137
 
176
- ```javascript
177
- throw new NotFoundError("User", { id });
178
- ```
138
+ - ❌ Massive duplication (76+ lines per endpoint)
139
+ - Out-of-sync documentation
140
+ - ❌ High maintenance burden
179
141
 
180
- 3. **Validate requests** with `validateRequest`
142
+ ### The Solution
181
143
 
182
- ```javascript
183
- router.post("/users", validateRequest(schema), handler);
184
- ```
144
+ @charcoles/swagger automatically converts your Zod schemas to OpenAPI:
185
145
 
186
- 4. **Send success** with `sendSuccess`
187
- ```javascript
188
- sendSuccess(res, data, 201, "User created");
189
- ```
146
+ ```typescript
147
+ // Before: Register schema in swagger.config.ts
148
+ import { registerSchema, loginSchema } from "./schemas";
190
149
 
191
- ## 📂 Project Structure
150
+ setupSwagger(app, {
151
+ schemas: {
152
+ registerSchema, // Auto-converted to OpenAPI!
153
+ loginSchema,
154
+ },
155
+ });
192
156
 
193
- ```
194
- src/
195
- ├── config/
196
- │ ├── env.js # Environment validation with Zod
197
- └── constants.js # HTTP status codes & error messages
198
- ├── middlewares/
199
- │ ├── errorHandler.js # ⭐ Global error handler + asyncHandler
200
- │ ├── validateRequest.js # Request validation middleware
201
- │ └── requestLogger.js # Request logging
202
- ├── modules/
203
- │ └── health/
204
- │ └── controller.js # Example handlers
205
- ├── utils/
206
- │ ├── AppError.js # ⭐ Error class hierarchy
207
- │ ├── logger.js # Structured logging
208
- │ └── response.js # Success response helpers
209
- ├── app.js # Express app setup
210
- ├── routes.js # API routes
211
- └── server.js # Server entry point
157
+ // After: Use $ref everywhere
158
+ /**
159
+ * @swagger
160
+ * schema:
161
+ * $ref: '#/components/schemas/registerSchema'
162
+ */
212
163
  ```
213
164
 
214
- ## 🚀 Running
165
+ ### Benefits
215
166
 
216
- ```bash
217
- # Development (with auto-reload and full logging)
218
- npm run dev
167
+ | Aspect | Before | After | Improvement |
168
+ | ---------------------- | --------------- | -------------- | ------------------ |
169
+ | **Lines per endpoint** | 45-76 lines | 10-20 lines | **60-75% less** |
170
+ | **Schema duplication** | 100% | 0% | **Eliminated** |
171
+ | **Maintenance** | Update 2 places | Update 1 place | **50% less work** |
172
+ | **Sync issues** | Common | Impossible | **Always in sync** |
219
173
 
220
- # Production (optimized, minimal logging)
221
- npm start
174
+ **See complete guide:** `src/lib/swagger/SWAGGER_GUIDE.md` (when swagger is enabled)
222
175
 
223
- # Test API endpoints
224
- node test-api.js
225
- ```
176
+ ## Repository Pattern: A Game Changer
226
177
 
227
- ## 🔧 Configuration
178
+ ### The Problem
228
179
 
229
- Environment variables (see `.env.example`):
180
+ Traditional apps mix database logic with business logic. Switching databases means rewriting everything.
230
181
 
231
- ```env
232
- NODE_ENV=development # development, production, test
233
- PORT=3000 # Server port
234
- LOG_LEVEL=info # debug, info, warn, error
235
- CORS_ORIGIN=* # CORS allowed origins
236
- REQUEST_TIMEOUT=30000 # Request timeout in milliseconds
237
- ```
182
+ ### The Solution
238
183
 
239
- ## 💻 Example: Create User Endpoint
184
+ Charcole introduces a Repository Pattern that abstracts database operations:
240
185
 
241
186
  ```javascript
242
- import { asyncHandler, ConflictError } from "./middlewares/errorHandler.js";
243
- import { validateRequest } from "./middlewares/validateRequest.js";
244
- import { sendSuccess } from "./utils/response.js";
245
- import { z } from "zod";
246
-
247
- // 1. Define validation schema
248
- const createUserSchema = z.object({
249
- body: z.object({
250
- email: z.string().email("Invalid email"),
251
- name: z.string().min(1, "Name required").max(100),
252
- }),
253
- });
187
+ // Traditional approach (tightly coupled)
188
+ // app.ts
189
+ import mongoose from 'mongoose';
254
190
 
255
- // 2. Define handler (wrapped with asyncHandler)
256
- export const createUser = asyncHandler(async (req, res) => {
257
- const { email, name } = req.validatedData.body;
191
+ async function getUser(id: string) {
192
+ return await UserModel.findById(id); // Direct MongoDB dependency
193
+ }
258
194
 
259
- // Check for duplicate
260
- const exists = await User.findOne({ email });
261
- if (exists) {
262
- throw new ConflictError("Email already exists", { email });
263
- }
195
+ // Charcole v2.2 approach (abstracted)
196
+ // repositories/user.repo.ts
197
+ const users: User[] = [];
198
+
199
+ type CreateUserData = {
200
+ email: string;
201
+ name: string;
202
+ passwordHash: string;
203
+ };
204
+
205
+ export const userRepo = {
206
+ async findByEmail(email: string): Promise<User | undefined> {
207
+ return users.find((u) => u.email === email);
208
+ },
209
+
210
+ async create(data: CreateUserData): Promise<User> {
211
+ const user: User = {
212
+ id: randomUUID(),
213
+ email: data.email,
214
+ name: data.name,
215
+ passwordHash: data.passwordHash,
216
+ role: "user",
217
+ provider: "credentials",
218
+ isEmailVerified: false,
219
+ createdAt: new Date(),
220
+ updatedAt: new Date(),
221
+ };
222
+
223
+ users.push(user);
224
+ return user;
225
+ },
226
+ };
227
+
228
+ // controller.js
229
+ async login(req, res) {
230
+ try {
231
+ const result = await AuthService.login(req.body, req.app.locals.userRepo);
232
+
233
+ res.json(result);
234
+ } catch (err) {
235
+ res.status(401).json({ message: err.message });
236
+ }
237
+ },
238
+ ```
264
239
 
265
- // Create user (any error is automatically caught)
266
- const user = await User.create({ email, name });
240
+ ### Benefits
267
241
 
268
- // Send success
269
- sendSuccess(res, user, 201, "User created successfully");
270
- });
242
+ - Test instantly - In-memory repository works without database setup
243
+ - Switch databases easily - Change MongoDB to PostgreSQL by updating one file
244
+ - ✅ Clean architecture - Business logic stays pure
245
+ - ✅ Better testing - Mock repositories for unit tests
246
+ - ✅ Future-proof - Adapt to any database technology
271
247
 
272
- // 3. Use in routes
273
- router.post("/users", validateRequest(createUserSchema), createUser);
274
- ```
248
+ ## JWT Authentication Module (Optional)
275
249
 
276
- **Results:**
250
+ ### What's Included
277
251
 
278
- - Valid request 201 with user data
279
- - ✅ Invalid email → 422 with field errors
280
- - ✅ Duplicate email → 409 conflict
281
- - ✅ Database error → 500 (logged, generic message sent in prod)
252
+ When you select "Yes" for authentication during project creation:
282
253
 
283
- ## 🌐 API Endpoints
254
+ ```
255
+ src/modules/auth/
256
+ │ ├── auth.controller.ts # Register, login, logout, me endpoints
257
+ │ ├── auth.middleware.ts # JWT verification, protected routes
258
+ │ ├── auth.service.ts # Business logic for authentication
259
+ │ ├── auth.routes.ts # Auth API routes
260
+ │ ├── auth.schemas.ts # Auth API Schemas (auto-documented if Swagger enabled!)
261
+ │ └── auth.constants.ts # Auth API constants
262
+ ```
284
263
 
285
- All endpoints follow the same error handling pattern:
264
+ ### Available Endpoints
286
265
 
287
266
  ```
288
- GET / # Root - API info
289
- GET /api/health # Health check
290
- POST /api/items # Create item (example)
267
+ POST /api/auth/register # Create new account
268
+ POST /api/auth/login # Get JWT token
269
+ GET /api/protected/me # Get current user (protected)
291
270
  ```
292
271
 
293
- ## What Makes This Special
272
+ ## Golden Rules (Updated for v2.2)
294
273
 
295
- Unlike typical Express APIs, Charcole:
274
+ 1. **Wrap async handlers with asyncHandler**
296
275
 
297
- - ✅ **Distinguishes operational from programmer errors** - Different handling for expected vs unexpected errors
298
- - **Never leaks internal details** - Production-safe error responses
299
- - ✅ **Catches all async errors** - No promise rejections leak
300
- - ✅ **Logs with full context** - Debugging is easy
301
- - ✅ **Validates everything** - Zod integration prevents bad data
302
- - ✅ **Consistent responses** - Predictable format for every endpoint
303
- - ✅ **Production-ready** - Graceful shutdown, signal handling, etc.
276
+ ```typescript
277
+ router.get("/users/:id", asyncHandler(async (req, res) => { ... }))
278
+ ```
304
279
 
305
- ## 🔄 Error Flow
280
+ 2. **Throw AppError (never use res.status().json())**
306
281
 
307
- ```
308
- Request arrives
309
-
310
- Handler (wrapped with asyncHandler)
311
- ├─ Success → sendSuccess() → Response sent ✓
312
- └─ Error thrown ✘
313
-
314
- Global error handler catches it
315
-
316
- Error normalized & classified
317
-
318
- Logged (WARN for operational, ERROR with stack for programmer)
319
-
320
- Consistent JSON response sent
321
- ```
282
+ ```typescript
283
+ throw new NotFoundError("User", { id });
284
+ ```
322
285
 
323
- ## 📊 Logging Examples
286
+ 3. **Validate requests with validateRequest**
324
287
 
325
- ### Operational Error (Expected)
288
+ ```typescript
289
+ router.post("/users", validateRequest(schema), handler);
290
+ ```
326
291
 
327
- ```
328
- [2024-01-20T12:00:00.000Z] WARN: Operational Error: NOT_FOUND
329
- { "code": "NOT_FOUND", "message": "User not found", "statusCode": 404 }
330
- ```
292
+ 4. **Use repositories for database operations**
331
293
 
332
- ### Programmer Error (Bug)
294
+ ```typescript
295
+ // ❌ Direct database calls
296
+ const user = await UserModel.findById(id);
333
297
 
334
- ```
335
- [2024-01-20T12:00:00.000Z] ERROR: Programmer Error: REFERENCE_ERROR
336
- { "code": "REFERENCE_ERROR", "message": "user is not defined" }
337
- ReferenceError: user is not defined
338
- at handler.js:15:3
339
- ...
340
- ```
298
+ // ✅ Repository pattern
299
+ const user = await AuthService.login(req.body, req.app.locals.userRepo);
300
+ ```
341
301
 
342
- ## 🛠️ Development
302
+ 5. **Define schemas once in Zod (if Swagger enabled)**
343
303
 
344
- ```bash
345
- # Install dependencies
346
- npm install
304
+ ```typescript
305
+ // Single source of truth
306
+ const userSchema = z.object({ ... });
347
307
 
348
- # Start dev server with auto-reload
349
- npm run dev
308
+ // Register in swagger.config.ts
309
+ setupSwagger(app, { schemas: { userSchema } });
350
310
 
351
- # Check for syntax errors
352
- npm run lint
311
+ // Never duplicate in JSDoc
312
+ ```
353
313
 
354
- # Run tests
355
- npm test
356
- ```
314
+ ## Why Choose Charcole v2.2?
315
+
316
+ ### For Startups
357
317
 
358
- ## 📦 Dependencies
318
+ - **Launch faster** - Production-ready API with auto-generated docs in minutes
319
+ - **Test without DB** - In-memory repository for rapid prototyping
320
+ - **Built-in auth** - User management out of the box
321
+ - **Clean code** - Follows best practices from day one
322
+ - **Free documentation** - Swagger UI generated automatically
359
323
 
360
- - **Express** - Web framework
361
- - **Zod** - Schema validation
362
- - **CORS** - Cross-origin requests
363
- - **dotenv** - Environment variables
364
- - **nodemon** - Auto-reload (dev only)
324
+ ### For Enterprises
365
325
 
366
- ## 🚢 Production Checklist
326
+ - **Maintainable** - Repository pattern enables easy database migrations
327
+ - **Scalable** - Modular architecture grows with your needs
328
+ - **Reliable** - Battle-tested error handling
329
+ - **Type-safe** - Full TypeScript support reduces bugs
330
+ - **Always in sync** - Documentation can't get outdated
367
331
 
368
- Before deploying:
332
+ ### For Developers
369
333
 
370
- - [ ] Set `NODE_ENV=production`
371
- - [ ] Configure `CORS_ORIGIN` for your domain
372
- - [ ] Set `LOG_LEVEL=warn` or higher
373
- - [ ] Add database connection
374
- - [ ] Implement authentication
375
- - [ ] Add rate limiting
376
- - [ ] Set up error monitoring (e.g., Sentry)
377
- - [ ] Configure reverse proxy (nginx/apache)
378
- - [ ] Test all error scenarios
379
- - [ ] Verify no secrets in error responses
334
+ - **Learn best practices** - Production patterns built-in
335
+ - **Effortless docs** - 60-80% less documentation work
336
+ - **Easy to extend** - Add modules, databases, features
337
+ - **Great DX** - Excellent error messages and logging
338
+ - **Future-proof** - Designed for long-term maintenance
380
339
 
381
340
  ## 🤝 Contributing
382
341
 
383
- Contributions welcome! Please:
342
+ We welcome contributions! Please:
384
343
 
385
- 1. Follow the error handling patterns
386
- 2. Always use `asyncHandler` for async handlers
387
- 3. Throw `AppError` instances for errors
388
- 4. Include context in errors
389
- 5. Add tests for new features
344
+ 1. Fork the repository, create new branch and raise a pull request. If it fits with the goals of **charcole** we'll merge it
345
+ 2. Follow the repository pattern for database operations
346
+ 3. Use TypeScript for new features
347
+ 4. Include tests with in-memory repositories
348
+ 5. Document new modules thoroughly
349
+ 6. Update README.md for significant changes
350
+ 7. If adding Swagger docs, use Zod schemas as single source of truth
390
351
 
391
352
  ## 📄 License
392
353
 
393
354
  ISC
394
-
395
- ---
396
-
397
- **Made for teams that care about code quality and production reliability.** 🚀
398
-
399
- Need help? See the [Getting Started Guide](template/README.md) or [Full Documentation](ERROR_HANDLING.md).
400
-
401
- ## 🆕 What’s New in v2.0
402
-
403
- - 🚀 **First-class TypeScript & JavaScript support**
404
- - 🧠 CLI-driven language selection
405
- - 🧩 Modular template architecture (future feature expansion)
406
- - 🧼 Cleaner project generation flow
407
- - 📦 Improved dependency handling
408
- - 🏗️ Foundation for built-in auth, Swagger, Docker modules