fragment-ts 1.0.2 → 1.0.3

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 (304) hide show
  1. package/README.md +401 -0
  2. package/USAGE.md +1439 -0
  3. package/bin/fragment.js +2 -0
  4. package/dist/ai/ai.module.d.ts +27 -0
  5. package/dist/ai/ai.module.d.ts.map +1 -0
  6. package/dist/ai/ai.module.js +77 -0
  7. package/dist/ai/ai.module.js.map +1 -0
  8. package/dist/auth/auth.module.d.ts +18 -0
  9. package/dist/auth/auth.module.d.ts.map +1 -0
  10. package/dist/auth/auth.module.js +89 -0
  11. package/dist/auth/auth.module.js.map +1 -0
  12. package/dist/cli/commands/build.command.d.ts +6 -1
  13. package/dist/cli/commands/build.command.d.ts.map +1 -0
  14. package/dist/cli/commands/build.command.js +130 -10
  15. package/dist/cli/commands/build.command.js.map +1 -1
  16. package/dist/cli/commands/diagnostics.command.d.ts +16 -0
  17. package/dist/cli/commands/diagnostics.command.d.ts.map +1 -0
  18. package/dist/cli/commands/diagnostics.command.js +419 -0
  19. package/dist/cli/commands/diagnostics.command.js.map +1 -0
  20. package/dist/cli/commands/generate.command.d.ts +13 -6
  21. package/dist/cli/commands/generate.command.d.ts.map +1 -0
  22. package/dist/cli/commands/generate.command.js +200 -128
  23. package/dist/cli/commands/generate.command.js.map +1 -1
  24. package/dist/cli/commands/init.command.d.ts +11 -5
  25. package/dist/cli/commands/init.command.d.ts.map +1 -0
  26. package/dist/cli/commands/init.command.js +267 -305
  27. package/dist/cli/commands/init.command.js.map +1 -1
  28. package/dist/cli/commands/migrate.command.d.ts +12 -5
  29. package/dist/cli/commands/migrate.command.d.ts.map +1 -0
  30. package/dist/cli/commands/migrate.command.js +211 -83
  31. package/dist/cli/commands/migrate.command.js.map +1 -1
  32. package/dist/cli/commands/serve.command.d.ts +5 -4
  33. package/dist/cli/commands/serve.command.d.ts.map +1 -0
  34. package/dist/cli/commands/serve.command.js +178 -21
  35. package/dist/cli/commands/serve.command.js.map +1 -1
  36. package/dist/cli/index.d.ts +2 -0
  37. package/dist/cli/index.d.ts.map +1 -0
  38. package/dist/cli/index.js +22 -0
  39. package/dist/cli/index.js.map +1 -0
  40. package/dist/core/container/di-container.d.ts +13 -7
  41. package/dist/core/container/di-container.d.ts.map +1 -0
  42. package/dist/core/container/di-container.js +75 -25
  43. package/dist/core/container/di-container.js.map +1 -1
  44. package/dist/core/decorators/application.decorator.d.ts +8 -0
  45. package/dist/core/decorators/application.decorator.d.ts.map +1 -0
  46. package/dist/core/decorators/application.decorator.js +16 -0
  47. package/dist/core/decorators/application.decorator.js.map +1 -0
  48. package/dist/core/decorators/auto-configuration.decorator.d.ts +2 -0
  49. package/dist/core/decorators/auto-configuration.decorator.d.ts.map +1 -0
  50. package/dist/core/decorators/auto-configuration.decorator.js +19 -0
  51. package/dist/core/decorators/auto-configuration.decorator.js.map +1 -0
  52. package/dist/core/decorators/conditional.decorators.d.ts +4 -0
  53. package/dist/core/decorators/conditional.decorators.d.ts.map +1 -0
  54. package/dist/core/decorators/conditional.decorators.js +22 -0
  55. package/dist/core/decorators/conditional.decorators.js.map +1 -0
  56. package/dist/core/decorators/controller.decorator.d.ts +1 -3
  57. package/dist/core/decorators/controller.decorator.d.ts.map +1 -0
  58. package/dist/core/decorators/controller.decorator.js +12 -9
  59. package/dist/core/decorators/controller.decorator.js.map +1 -1
  60. package/dist/core/decorators/http.decorators.d.ts +12 -0
  61. package/dist/core/decorators/http.decorators.d.ts.map +1 -0
  62. package/dist/core/decorators/http.decorators.js +52 -0
  63. package/dist/core/decorators/http.decorators.js.map +1 -0
  64. package/dist/core/decorators/injectable.decorator.d.ts +3 -3
  65. package/dist/core/decorators/injectable.decorator.d.ts.map +1 -0
  66. package/dist/core/decorators/injectable.decorator.js +11 -8
  67. package/dist/core/decorators/injectable.decorator.js.map +1 -1
  68. package/dist/core/decorators/injection.decorators.d.ts +5 -0
  69. package/dist/core/decorators/injection.decorators.d.ts.map +1 -0
  70. package/dist/core/decorators/injection.decorators.js +29 -0
  71. package/dist/core/decorators/injection.decorators.js.map +1 -0
  72. package/dist/core/decorators/repository.decorator.d.ts +1 -0
  73. package/dist/core/decorators/repository.decorator.d.ts.map +1 -0
  74. package/dist/core/decorators/repository.decorator.js +12 -1
  75. package/dist/core/decorators/repository.decorator.js.map +1 -1
  76. package/dist/core/decorators/service.decorator.d.ts +1 -0
  77. package/dist/core/decorators/service.decorator.d.ts.map +1 -0
  78. package/dist/core/decorators/service.decorator.js +12 -1
  79. package/dist/core/decorators/service.decorator.js.map +1 -1
  80. package/dist/core/index.d.ts +13 -0
  81. package/dist/core/index.d.ts.map +1 -0
  82. package/dist/core/index.js +29 -0
  83. package/dist/core/index.js.map +1 -0
  84. package/dist/core/loader/file-loader.d.ts +5 -0
  85. package/dist/core/loader/file-loader.d.ts.map +1 -0
  86. package/dist/core/loader/file-loader.js +85 -0
  87. package/dist/core/loader/file-loader.js.map +1 -0
  88. package/dist/core/metadata/metadata-keys.d.ts +20 -0
  89. package/dist/core/metadata/metadata-keys.d.ts.map +1 -0
  90. package/dist/core/metadata/metadata-keys.js +23 -0
  91. package/dist/core/metadata/metadata-keys.js.map +1 -0
  92. package/dist/core/metadata/metadata-storage.d.ts +36 -0
  93. package/dist/core/metadata/metadata-storage.d.ts.map +1 -0
  94. package/dist/core/metadata/metadata-storage.js +53 -0
  95. package/dist/core/metadata/metadata-storage.js.map +1 -0
  96. package/dist/core/scanner/component-scanner.d.ts +16 -0
  97. package/dist/core/scanner/component-scanner.d.ts.map +1 -0
  98. package/dist/core/scanner/component-scanner.js +147 -0
  99. package/dist/core/scanner/component-scanner.js.map +1 -0
  100. package/dist/index.d.ts +22 -0
  101. package/dist/index.d.ts.map +1 -0
  102. package/dist/index.js +60 -0
  103. package/dist/index.js.map +1 -0
  104. package/dist/plugins/plugin-manager.d.ts +14 -0
  105. package/dist/plugins/plugin-manager.d.ts.map +1 -0
  106. package/dist/{cli/utils/file-generator.js → plugins/plugin-manager.js} +32 -24
  107. package/dist/plugins/plugin-manager.js.map +1 -0
  108. package/dist/shared/errors.d.ts +18 -0
  109. package/dist/shared/errors.d.ts.map +1 -0
  110. package/dist/shared/errors.js +41 -0
  111. package/dist/shared/errors.js.map +1 -0
  112. package/dist/testing/runner.d.ts +26 -0
  113. package/dist/testing/runner.d.ts.map +1 -0
  114. package/dist/testing/runner.js +143 -0
  115. package/dist/testing/runner.js.map +1 -0
  116. package/dist/typeorm/typeorm-module.d.ts +36 -0
  117. package/dist/typeorm/typeorm-module.d.ts.map +1 -0
  118. package/dist/typeorm/typeorm-module.js +150 -0
  119. package/dist/typeorm/typeorm-module.js.map +1 -0
  120. package/dist/web/application.d.ts +29 -0
  121. package/dist/web/application.d.ts.map +1 -0
  122. package/dist/web/application.js +301 -0
  123. package/dist/web/application.js.map +1 -0
  124. package/dist/web/interfaces.d.ts +14 -0
  125. package/dist/web/interfaces.d.ts.map +1 -0
  126. package/dist/{auth/dto/login.dto.js → web/interfaces.js} +1 -1
  127. package/dist/web/interfaces.js.map +1 -0
  128. package/examples/blog-api/fragment.json +14 -0
  129. package/examples/blog-api/package-lock.json +3405 -0
  130. package/examples/blog-api/package.json +19 -0
  131. package/examples/blog-api/src/controllers/app.controller.ts +9 -0
  132. package/examples/blog-api/src/controllers/auth.controller.ts +17 -0
  133. package/examples/blog-api/src/controllers/category.controller.ts +29 -0
  134. package/examples/blog-api/src/controllers/comment.controller.ts +31 -0
  135. package/examples/blog-api/src/controllers/post.controller.ts +46 -0
  136. package/examples/blog-api/src/dto/create-category.dto.ts +6 -0
  137. package/examples/blog-api/src/dto/create-comment.dto.ts +6 -0
  138. package/examples/blog-api/src/dto/create-post.dto.ts +6 -0
  139. package/examples/blog-api/src/entities/category.entity.ts +16 -0
  140. package/examples/blog-api/src/entities/comment.entity.ts +29 -0
  141. package/examples/blog-api/src/entities/post.entity.ts +42 -0
  142. package/examples/blog-api/src/entities/user.entity.ts +25 -0
  143. package/examples/blog-api/src/main.ts +16 -0
  144. package/examples/blog-api/src/migrations/1767737463842-InitialSchema.ts +60 -0
  145. package/examples/blog-api/src/repositories/category.repository.ts +25 -0
  146. package/examples/blog-api/src/repositories/comment.repository.ts +25 -0
  147. package/examples/blog-api/src/repositories/post.repository.ts +29 -0
  148. package/examples/blog-api/src/seeds/SampleData.seed.ts +41 -0
  149. package/examples/blog-api/src/services/app.service.ts +8 -0
  150. package/examples/blog-api/src/services/auth.service.ts +15 -0
  151. package/examples/blog-api/src/services/category.service.ts +27 -0
  152. package/examples/blog-api/src/services/comment.service.ts +31 -0
  153. package/examples/blog-api/src/services/post.service.ts +35 -0
  154. package/examples/blog-api/tsconfig.json +23 -0
  155. package/package.json +55 -33
  156. package/src/ai/ai.module.ts +110 -0
  157. package/src/auth/auth.module.ts +77 -0
  158. package/src/cli/commands/build.command.ts +123 -13
  159. package/src/cli/commands/diagnostics.command.ts +438 -0
  160. package/src/cli/commands/generate.command.ts +206 -137
  161. package/src/cli/commands/init.command.ts +337 -349
  162. package/src/cli/commands/migrate.command.ts +203 -88
  163. package/src/cli/commands/serve.command.ts +176 -24
  164. package/src/cli/index.ts +23 -0
  165. package/src/core/container/di-container.ts +83 -26
  166. package/src/core/decorators/application.decorator.ts +26 -0
  167. package/src/core/decorators/auto-configuration.decorator.ts +17 -0
  168. package/src/core/decorators/conditional.decorators.ts +19 -0
  169. package/src/core/decorators/controller.decorator.ts +14 -11
  170. package/src/core/decorators/http.decorators.ts +71 -0
  171. package/src/core/decorators/injectable.decorator.ts +14 -9
  172. package/src/core/decorators/injection.decorators.ts +26 -0
  173. package/src/core/decorators/repository.decorator.ts +13 -2
  174. package/src/core/decorators/service.decorator.ts +13 -2
  175. package/src/core/index.ts +13 -0
  176. package/src/core/loader/file-loader.ts +55 -0
  177. package/src/core/metadata/metadata-keys.ts +19 -0
  178. package/src/core/metadata/metadata-storage.ts +91 -0
  179. package/src/core/scanner/component-scanner.ts +129 -0
  180. package/src/index.ts +45 -0
  181. package/src/plugins/plugin-manager.ts +52 -0
  182. package/src/shared/errors.ts +34 -0
  183. package/src/testing/runner.ts +143 -0
  184. package/src/typeorm/typeorm-module.ts +216 -0
  185. package/src/web/application.ts +348 -0
  186. package/src/web/interfaces.ts +17 -0
  187. package/tsconfig.json +8 -6
  188. package/.env.example +0 -0
  189. package/base.ts +0 -1810
  190. package/base2.ts +0 -968
  191. package/bin/frg.ts +0 -5
  192. package/config/fragment.lock.yaml +0 -0
  193. package/config/fragment.yaml +0 -0
  194. package/dist/app.d.ts +0 -15
  195. package/dist/app.js +0 -91
  196. package/dist/app.js.map +0 -1
  197. package/dist/auth/auth.controller.d.ts +0 -10
  198. package/dist/auth/auth.controller.js +0 -88
  199. package/dist/auth/auth.controller.js.map +0 -1
  200. package/dist/auth/auth.middleware.d.ts +0 -2
  201. package/dist/auth/auth.middleware.js +0 -25
  202. package/dist/auth/auth.middleware.js.map +0 -1
  203. package/dist/auth/auth.service.d.ts +0 -20
  204. package/dist/auth/auth.service.js +0 -144
  205. package/dist/auth/auth.service.js.map +0 -1
  206. package/dist/auth/dto/login.dto.d.ts +0 -9
  207. package/dist/auth/dto/login.dto.js.map +0 -1
  208. package/dist/cli/cli.d.ts +0 -12
  209. package/dist/cli/cli.js +0 -187
  210. package/dist/cli/cli.js.map +0 -1
  211. package/dist/cli/commands/config.command.d.ts +0 -6
  212. package/dist/cli/commands/config.command.js +0 -285
  213. package/dist/cli/commands/config.command.js.map +0 -1
  214. package/dist/cli/templates/controller.template.d.ts +0 -1
  215. package/dist/cli/templates/controller.template.js +0 -53
  216. package/dist/cli/templates/controller.template.js.map +0 -1
  217. package/dist/cli/templates/entity.template.d.ts +0 -1
  218. package/dist/cli/templates/entity.template.js +0 -24
  219. package/dist/cli/templates/entity.template.js.map +0 -1
  220. package/dist/cli/templates/repository.template.d.ts +0 -1
  221. package/dist/cli/templates/repository.template.js +0 -44
  222. package/dist/cli/templates/repository.template.js.map +0 -1
  223. package/dist/cli/templates/service.template.d.ts +0 -1
  224. package/dist/cli/templates/service.template.js +0 -44
  225. package/dist/cli/templates/service.template.js.map +0 -1
  226. package/dist/cli/utils/file-generator.d.ts +0 -9
  227. package/dist/cli/utils/file-generator.js.map +0 -1
  228. package/dist/cli/utils/logger.d.ts +0 -14
  229. package/dist/cli/utils/logger.js +0 -50
  230. package/dist/cli/utils/logger.js.map +0 -1
  231. package/dist/controllers/health.controller.d.ts +0 -13
  232. package/dist/controllers/health.controller.js +0 -51
  233. package/dist/controllers/health.controller.js.map +0 -1
  234. package/dist/core/config/config-loader.d.ts +0 -31
  235. package/dist/core/config/config-loader.js +0 -99
  236. package/dist/core/config/config-loader.js.map +0 -1
  237. package/dist/core/decorators/auth-guard.decorator.d.ts +0 -3
  238. package/dist/core/decorators/auth-guard.decorator.js +0 -19
  239. package/dist/core/decorators/auth-guard.decorator.js.map +0 -1
  240. package/dist/core/decorators/autowire.decorator.d.ts +0 -3
  241. package/dist/core/decorators/autowire.decorator.js +0 -18
  242. package/dist/core/decorators/autowire.decorator.js.map +0 -1
  243. package/dist/core/decorators/middleware.decorator.d.ts +0 -3
  244. package/dist/core/decorators/middleware.decorator.js +0 -21
  245. package/dist/core/decorators/middleware.decorator.js.map +0 -1
  246. package/dist/core/decorators/route.decorator.d.ts +0 -14
  247. package/dist/core/decorators/route.decorator.js +0 -33
  248. package/dist/core/decorators/route.decorator.js.map +0 -1
  249. package/dist/core/openai/openai-client.d.ts +0 -12
  250. package/dist/core/openai/openai-client.js +0 -94
  251. package/dist/core/openai/openai-client.js.map +0 -1
  252. package/dist/database/data-source.d.ts +0 -4
  253. package/dist/database/data-source.js +0 -27
  254. package/dist/database/data-source.js.map +0 -1
  255. package/dist/entities/session.entity.d.ts +0 -9
  256. package/dist/entities/session.entity.js +0 -46
  257. package/dist/entities/session.entity.js.map +0 -1
  258. package/dist/entities/user.entity.d.ts +0 -10
  259. package/dist/entities/user.entity.js +0 -49
  260. package/dist/entities/user.entity.js.map +0 -1
  261. package/dist/middlewares/logging.middleware.d.ts +0 -2
  262. package/dist/middlewares/logging.middleware.js +0 -29
  263. package/dist/middlewares/logging.middleware.js.map +0 -1
  264. package/dist/repositories/session.repository.d.ts +0 -9
  265. package/dist/repositories/session.repository.js +0 -51
  266. package/dist/repositories/session.repository.js.map +0 -1
  267. package/dist/repositories/user.repository.d.ts +0 -10
  268. package/dist/repositories/user.repository.js +0 -44
  269. package/dist/repositories/user.repository.js.map +0 -1
  270. package/dist/server.d.ts +0 -1
  271. package/dist/server.js +0 -31
  272. package/dist/server.js.map +0 -1
  273. package/dist/services/health.service.d.ts +0 -13
  274. package/dist/services/health.service.js +0 -45
  275. package/dist/services/health.service.js.map +0 -1
  276. package/readme.md +0 -120
  277. package/src/app.ts +0 -121
  278. package/src/auth/auth.controller.ts +0 -52
  279. package/src/auth/auth.middleware.ts +0 -27
  280. package/src/auth/auth.service.ts +0 -110
  281. package/src/auth/dto/login.dto.ts +0 -11
  282. package/src/cli/cli.ts +0 -212
  283. package/src/cli/commands/config.command.ts +0 -280
  284. package/src/cli/templates/controller.template.ts +0 -51
  285. package/src/cli/templates/entity.template.ts +0 -22
  286. package/src/cli/templates/repository.template.ts +0 -42
  287. package/src/cli/templates/service.template.ts +0 -42
  288. package/src/cli/utils/file-generator.ts +0 -37
  289. package/src/cli/utils/logger.ts +0 -52
  290. package/src/controllers/health.controller.ts +0 -24
  291. package/src/core/config/config-loader.ts +0 -98
  292. package/src/core/decorators/auth-guard.decorator.ts +0 -15
  293. package/src/core/decorators/autowire.decorator.ts +0 -18
  294. package/src/core/decorators/middleware.decorator.ts +0 -18
  295. package/src/core/decorators/route.decorator.ts +0 -33
  296. package/src/core/openai/openai-client.ts +0 -99
  297. package/src/database/data-source.ts +0 -29
  298. package/src/entities/session.entity.ts +0 -25
  299. package/src/entities/user.entity.ts +0 -27
  300. package/src/middlewares/logging.middleware.ts +0 -28
  301. package/src/repositories/session.repository.ts +0 -42
  302. package/src/repositories/user.repository.ts +0 -37
  303. package/src/server.ts +0 -32
  304. package/src/services/health.service.ts +0 -29
package/USAGE.md ADDED
@@ -0,0 +1,1439 @@
1
+ # Fragment Framework - Comprehensive Use Cases & Examples
2
+
3
+ ## Table of Contents
4
+
5
+ - [Quick Start](#quick-start)
6
+ - [Basic REST API](#basic-rest-api)
7
+ - [Authentication & Authorization](#authentication--authorization)
8
+ - [Database Operations](#database-operations)
9
+ - [AI-Powered Applications](#ai-powered-applications)
10
+ - [Dependency Injection Patterns](#dependency-injection-patterns)
11
+ - [Advanced Routing](#advanced-routing)
12
+ - [Custom Middleware](#custom-middleware)
13
+ - [Testing](#testing)
14
+ - [Production Deployment](#production-deployment)
15
+ - [CLI Reference](#cli-reference)
16
+ - [Best Practices](#best-practices)
17
+ - [Troubleshooting](#troubleshooting)
18
+
19
+ ---
20
+
21
+ ## Quick Start
22
+
23
+ ### Installation & Project Initialization
24
+
25
+ ```bash
26
+ # Install Fragment CLI globally
27
+ npm install -g fragment
28
+
29
+ # Option 1: Initialize in current directory
30
+ mkdir my-app && cd my-app
31
+ fragment init .
32
+
33
+ # Option 2: Create new directory and initialize
34
+ fragment init my-app
35
+ cd my-app
36
+
37
+ # Option 3: Use specific template
38
+ fragment init my-api --template=api
39
+
40
+ # Option 4: Select features interactively
41
+ fragment init my-app --features=auth,ai,database
42
+
43
+ # Option 5: Skip npm install (install manually later)
44
+ fragment init my-app --skip-install
45
+ ```
46
+
47
+ **Yes, `fragment init .` initializes in the current directory!**
48
+
49
+ ### Start Development
50
+
51
+ ```bash
52
+ # Start with hot reload (auto-restarts on file changes)
53
+ fragment serve
54
+
55
+ # Start on custom port
56
+ fragment serve --port=4000
57
+
58
+ # Start without watch mode
59
+ fragment serve --no-watch
60
+
61
+ # Build for production
62
+ fragment build
63
+
64
+ # Run production build
65
+ npm start
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Basic REST API
71
+
72
+ ### Use Case 1: Simple CRUD API
73
+
74
+ Create a complete REST API for managing products.
75
+
76
+ ```bash
77
+ # Generate complete resource (controller, service, entity, DTO, repository)
78
+ fragment generate resource product
79
+
80
+ # Or use shorthand
81
+ fragment g resource product
82
+ ```
83
+
84
+ **Generated Files:**
85
+
86
+ **src/controllers/product.controller.ts**
87
+
88
+ ```typescript
89
+ import { Controller, Get, Post, Put, Delete, Body, Param } from "fragment";
90
+ import { ProductService } from "../services/product.service";
91
+
92
+ @Controller("/products")
93
+ export class ProductController {
94
+ constructor(private productService: ProductService) {}
95
+
96
+ @Get()
97
+ async findAll() {
98
+ return this.productService.findAll();
99
+ }
100
+
101
+ @Get("/:id")
102
+ async findOne(@Param("id") id: string) {
103
+ return this.productService.findOne(id);
104
+ }
105
+
106
+ @Post()
107
+ async create(@Body() body: any) {
108
+ return this.productService.create(body);
109
+ }
110
+
111
+ @Put("/:id")
112
+ async update(@Param("id") id: string, @Body() body: any) {
113
+ return this.productService.update(id, body);
114
+ }
115
+
116
+ @Delete("/:id")
117
+ async delete(@Param("id") id: string) {
118
+ return this.productService.delete(id);
119
+ }
120
+ }
121
+ ```
122
+
123
+ **src/services/product.service.ts**
124
+
125
+ ```typescript
126
+ import { Service } from "fragment";
127
+ import { ProductRepository } from "../repositories/product.repository";
128
+
129
+ @Service()
130
+ export class ProductService {
131
+ constructor(private productRepository: ProductRepository) {}
132
+
133
+ async findAll() {
134
+ return this.productRepository.findAll();
135
+ }
136
+
137
+ async findOne(id: string) {
138
+ const product = await this.productRepository.findById(parseInt(id));
139
+ if (!product) {
140
+ throw new Error("Product not found");
141
+ }
142
+ return product;
143
+ }
144
+
145
+ async create(data: any) {
146
+ return this.productRepository.create(data);
147
+ }
148
+
149
+ async update(id: string, data: any) {
150
+ return this.productRepository.update(parseInt(id), data);
151
+ }
152
+
153
+ async delete(id: string) {
154
+ return this.productRepository.delete(parseInt(id));
155
+ }
156
+ }
157
+ ```
158
+
159
+ **src/entities/product.entity.ts**
160
+
161
+ ```typescript
162
+ import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
163
+
164
+ @Entity()
165
+ export class Product {
166
+ @PrimaryGeneratedColumn()
167
+ id: number;
168
+
169
+ @Column()
170
+ name: string;
171
+
172
+ @Column("decimal", { precision: 10, scale: 2 })
173
+ price: number;
174
+
175
+ @Column({ nullable: true })
176
+ description: string;
177
+
178
+ @Column({ default: 0 })
179
+ stock: number;
180
+
181
+ @Column({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
182
+ createdAt: Date;
183
+
184
+ @Column({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
185
+ updatedAt: Date;
186
+ }
187
+ ```
188
+
189
+ **Testing the API:**
190
+
191
+ ```bash
192
+ # Start server
193
+ fragment serve
194
+
195
+ # Verify routes are registered
196
+ fragment routes
197
+
198
+ # Test endpoints
199
+ curl http://localhost:3000/products
200
+ curl -X POST http://localhost:3000/products \
201
+ -H "Content-Type: application/json" \
202
+ -d '{"name":"Laptop","price":999.99,"stock":10}'
203
+ curl http://localhost:3000/products/1
204
+ curl -X PUT http://localhost:3000/products/1 \
205
+ -H "Content-Type: application/json" \
206
+ -d '{"price":899.99}'
207
+ curl -X DELETE http://localhost:3000/products/1
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Authentication & Authorization
213
+
214
+ ### Use Case 2: User Authentication System
215
+
216
+ Complete authentication with JWT tokens, password hashing, and role-based access.
217
+
218
+ ```bash
219
+ # Initialize with auth feature
220
+ fragment init auth-api --features=auth,database
221
+ cd auth-api
222
+
223
+ # Generate user resource
224
+ fragment generate resource user
225
+ ```
226
+
227
+ **src/entities/user.entity.ts**
228
+
229
+ ```typescript
230
+ import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
231
+
232
+ @Entity()
233
+ export class User {
234
+ @PrimaryGeneratedColumn()
235
+ id: number;
236
+
237
+ @Column({ unique: true })
238
+ email: string;
239
+
240
+ @Column()
241
+ password: string;
242
+
243
+ @Column()
244
+ name: string;
245
+
246
+ @Column("simple-array", { default: "user" })
247
+ roles: string[];
248
+
249
+ @Column({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
250
+ createdAt: Date;
251
+ }
252
+ ```
253
+
254
+ **src/services/auth.service.ts**
255
+
256
+ ```typescript
257
+ import { Service } from "fragment";
258
+ import { AuthModule, NotFoundError, UnauthorizedError } from "fragment";
259
+ import { UserRepository } from "../repositories/user.repository";
260
+
261
+ @Service()
262
+ export class AuthService {
263
+ constructor(private userRepository: UserRepository) {}
264
+
265
+ async register(email: string, password: string, name: string) {
266
+ // Hash password
267
+ const hashedPassword = await AuthModule.hashPassword(password);
268
+
269
+ // Create user
270
+ const user = await this.userRepository.create({
271
+ email,
272
+ password: hashedPassword,
273
+ name,
274
+ roles: ["user"],
275
+ });
276
+
277
+ // Generate token
278
+ const token = AuthModule.generateToken({
279
+ userId: user.id.toString(),
280
+ email: user.email,
281
+ roles: user.roles,
282
+ });
283
+
284
+ return { user: { id: user.id, email, name }, token };
285
+ }
286
+
287
+ async login(email: string, password: string) {
288
+ // Find user
289
+ const user = await this.userRepository.findByEmail(email);
290
+ if (!user) {
291
+ throw new UnauthorizedError("Invalid credentials");
292
+ }
293
+
294
+ // Verify password
295
+ const isValid = await AuthModule.comparePassword(password, user.password);
296
+ if (!isValid) {
297
+ throw new UnauthorizedError("Invalid credentials");
298
+ }
299
+
300
+ // Generate token
301
+ const token = AuthModule.generateToken({
302
+ userId: user.id.toString(),
303
+ email: user.email,
304
+ roles: user.roles,
305
+ });
306
+
307
+ return { user: { id: user.id, email, name: user.name }, token };
308
+ }
309
+
310
+ async getCurrentUser(userId: string) {
311
+ const user = await this.userRepository.findById(parseInt(userId));
312
+ if (!user) {
313
+ throw new NotFoundError("User not found");
314
+ }
315
+ return { id: user.id, email: user.email, name: user.name };
316
+ }
317
+ }
318
+ ```
319
+
320
+ **src/controllers/auth.controller.ts**
321
+
322
+ ```typescript
323
+ import { Controller, Post, Get, Body, Req } from "fragment";
324
+ import { AuthModule } from "fragment";
325
+ import { AuthService } from "../services/auth.service";
326
+
327
+ @Controller("/auth")
328
+ export class AuthController {
329
+ constructor(private authService: AuthService) {}
330
+
331
+ @Post("/register")
332
+ async register(@Body() body: any) {
333
+ return this.authService.register(body.email, body.password, body.name);
334
+ }
335
+
336
+ @Post("/login")
337
+ async login(@Body() body: any) {
338
+ return this.authService.login(body.email, body.password);
339
+ }
340
+ }
341
+
342
+ @Controller("/api")
343
+ export class ProtectedController {
344
+ constructor(private authService: AuthService) {}
345
+
346
+ // Protected route - requires authentication
347
+ @Get("/me")
348
+ async getProfile(@Req() req: any) {
349
+ // In production, use middleware to attach user to request
350
+ const authHeader = req.headers.authorization;
351
+ if (!authHeader) {
352
+ throw new UnauthorizedError("Missing authorization header");
353
+ }
354
+
355
+ const token = authHeader.replace("Bearer ", "");
356
+ const payload = AuthModule.verifyToken(token);
357
+
358
+ return this.authService.getCurrentUser(payload.userId);
359
+ }
360
+ }
361
+ ```
362
+
363
+ **src/main.ts - Add Auth Middleware**
364
+
365
+ ```typescript
366
+ import "reflect-metadata";
367
+ import { FragmentApplication } from "fragment";
368
+ import { FragmentWebApplication } from "fragment";
369
+ import { AuthModule } from "fragment";
370
+
371
+ @FragmentApplication({
372
+ port: 3000,
373
+ autoScan: true,
374
+ })
375
+ class Application {}
376
+
377
+ async function bootstrap() {
378
+ const app = new FragmentWebApplication();
379
+
380
+ // Apply auth middleware to protected routes
381
+ const expressApp = app.getExpressApp();
382
+ expressApp.use("/api/*", AuthModule.authMiddleware());
383
+
384
+ // Apply role-based guards
385
+ expressApp.use("/admin/*", AuthModule.roleGuard("admin"));
386
+
387
+ await app.bootstrap(Application);
388
+ }
389
+
390
+ bootstrap();
391
+ ```
392
+
393
+ **Testing Authentication:**
394
+
395
+ ```bash
396
+ # Register
397
+ curl -X POST http://localhost:3000/auth/register \
398
+ -H "Content-Type: application/json" \
399
+ -d '{"email":"user@example.com","password":"secret123","name":"John Doe"}'
400
+
401
+ # Response: {"user":{"id":1,"email":"user@example.com","name":"John Doe"},"token":"eyJ..."}
402
+
403
+ # Login
404
+ curl -X POST http://localhost:3000/auth/login \
405
+ -H "Content-Type: application/json" \
406
+ -d '{"email":"user@example.com","password":"secret123"}'
407
+
408
+ # Access protected route
409
+ curl http://localhost:3000/api/me \
410
+ -H "Authorization: Bearer YOUR_TOKEN_HERE"
411
+ ```
412
+
413
+ ---
414
+
415
+ ## Database Operations
416
+
417
+ ### Use Case 3: Advanced Database Migrations
418
+
419
+ ```bash
420
+ # Create migration
421
+ fragment migrate:create AddProductCategories
422
+
423
+ # Run all pending migrations
424
+ fragment migrate:run
425
+
426
+ # Check migration status
427
+ fragment migrate:status
428
+
429
+ # Revert last migration
430
+ fragment migrate:revert
431
+
432
+ # Refresh all migrations (drop and re-run - CAREFUL!)
433
+ fragment migrate:refresh
434
+
435
+ # Sync schema (development only - not for production!)
436
+ fragment schema:sync
437
+
438
+ # Drop all tables (DANGEROUS!)
439
+ fragment schema:drop
440
+ ```
441
+
442
+ **Example Migration: src/migrations/1234567890-AddProductCategories.ts**
443
+
444
+ ```typescript
445
+ import {
446
+ MigrationInterface,
447
+ QueryRunner,
448
+ Table,
449
+ TableForeignKey,
450
+ } from "typeorm";
451
+
452
+ export class AddProductCategories1234567890 implements MigrationInterface {
453
+ async up(queryRunner: QueryRunner): Promise<void> {
454
+ // Create categories table
455
+ await queryRunner.createTable(
456
+ new Table({
457
+ name: "category",
458
+ columns: [
459
+ {
460
+ name: "id",
461
+ type: "int",
462
+ isPrimary: true,
463
+ isGenerated: true,
464
+ generationStrategy: "increment",
465
+ },
466
+ { name: "name", type: "varchar", isUnique: true },
467
+ { name: "description", type: "text", isNullable: true },
468
+ {
469
+ name: "createdAt",
470
+ type: "timestamp",
471
+ default: "CURRENT_TIMESTAMP",
472
+ },
473
+ ],
474
+ }),
475
+ );
476
+
477
+ // Add category column to products
478
+ await queryRunner.query(`ALTER TABLE product ADD COLUMN categoryId INT`);
479
+
480
+ // Add foreign key
481
+ await queryRunner.createForeignKey(
482
+ "product",
483
+ new TableForeignKey({
484
+ columnNames: ["categoryId"],
485
+ referencedTableName: "category",
486
+ referencedColumnNames: ["id"],
487
+ onDelete: "SET NULL",
488
+ }),
489
+ );
490
+ }
491
+
492
+ async down(queryRunner: QueryRunner): Promise<void> {
493
+ // Drop foreign key first
494
+ const table = await queryRunner.getTable("product");
495
+ const foreignKey = table?.foreignKeys.find(
496
+ (fk) => fk.columnNames.indexOf("categoryId") !== -1,
497
+ );
498
+ if (foreignKey) {
499
+ await queryRunner.dropForeignKey("product", foreignKey);
500
+ }
501
+
502
+ // Drop column and table
503
+ await queryRunner.dropColumn("product", "categoryId");
504
+ await queryRunner.dropTable("category");
505
+ }
506
+ }
507
+ ```
508
+
509
+ ### Database Seeding
510
+
511
+ ```bash
512
+ # Create seed
513
+ fragment seed:create InitialData
514
+
515
+ # Run all seeds
516
+ fragment seed
517
+ ```
518
+
519
+ **src/seeds/InitialData.seed.ts**
520
+
521
+ ```typescript
522
+ import { TypeORMModule } from "fragment";
523
+
524
+ export default class InitialDataSeed {
525
+ static async run() {
526
+ const dataSource = TypeORMModule.getDataSource();
527
+
528
+ // Seed categories
529
+ await dataSource.query(`
530
+ INSERT INTO category (name, description) VALUES
531
+ ('Electronics', 'Electronic devices and accessories'),
532
+ ('Clothing', 'Apparel and fashion items'),
533
+ ('Books', 'Physical and digital books')
534
+ `);
535
+
536
+ // Seed products
537
+ await dataSource.query(`
538
+ INSERT INTO product (name, price, stock, categoryId) VALUES
539
+ ('Laptop', 999.99, 50, 1),
540
+ ('T-Shirt', 29.99, 200, 2),
541
+ ('Novel', 14.99, 100, 3)
542
+ `);
543
+
544
+ console.log("✅ Initial data seeded successfully");
545
+ }
546
+ }
547
+ ```
548
+
549
+ ---
550
+
551
+ ## AI-Powered Applications
552
+
553
+ ### Use Case 4: AI Chat Service
554
+
555
+ ```bash
556
+ # Initialize with AI feature
557
+ fragment init ai-app --features=ai
558
+ cd ai-app
559
+
560
+ # Generate AI components
561
+ fragment generate controller chat
562
+ fragment generate service chat
563
+ ```
564
+
565
+ **src/services/chat.service.ts**
566
+
567
+ ```typescript
568
+ import { Service } from "fragment";
569
+ import { AIModule } from "fragment";
570
+
571
+ @Service()
572
+ export class ChatService {
573
+ private aiModule: AIModule;
574
+
575
+ constructor() {
576
+ this.aiModule = new AIModule({
577
+ openaiKey: process.env.OPENAI_API_KEY,
578
+ ollamaUrl: process.env.OLLAMA_URL,
579
+ });
580
+ }
581
+
582
+ async chat(message: string, history: any[] = []) {
583
+ const messages = [
584
+ { role: "system" as const, content: "You are a helpful assistant." },
585
+ ...history,
586
+ { role: "user" as const, content: message },
587
+ ];
588
+
589
+ const response = await this.aiModule.complete(messages, {
590
+ model: "gpt-3.5-turbo",
591
+ temperature: 0.7,
592
+ maxTokens: 500,
593
+ });
594
+
595
+ return {
596
+ response,
597
+ history: [
598
+ ...history,
599
+ { role: "user", content: message },
600
+ { role: "assistant", content: response },
601
+ ],
602
+ };
603
+ }
604
+
605
+ async streamChat(message: string, onChunk: (chunk: string) => void) {
606
+ const messages = [
607
+ { role: "system" as const, content: "You are a helpful assistant." },
608
+ { role: "user" as const, content: message },
609
+ ];
610
+
611
+ await this.aiModule.streamComplete(
612
+ messages,
613
+ { model: "gpt-3.5-turbo" },
614
+ onChunk,
615
+ );
616
+ }
617
+
618
+ async generateEmbeddings(texts: string[]) {
619
+ return this.aiModule.embeddings(texts);
620
+ }
621
+ }
622
+ ```
623
+
624
+ **src/controllers/chat.controller.ts**
625
+
626
+ ```typescript
627
+ import { Controller, Post, Body, Res } from "fragment";
628
+ import { ChatService } from "../services/chat.service";
629
+ import { Response } from "express";
630
+
631
+ @Controller("/chat")
632
+ export class ChatController {
633
+ constructor(private chatService: ChatService) {}
634
+
635
+ @Post("/message")
636
+ async sendMessage(@Body() body: any) {
637
+ return this.chatService.chat(body.message, body.history || []);
638
+ }
639
+
640
+ @Post("/stream")
641
+ async streamMessage(@Body() body: any, @Res() res: Response) {
642
+ res.setHeader("Content-Type", "text/event-stream");
643
+ res.setHeader("Cache-Control", "no-cache");
644
+ res.setHeader("Connection", "keep-alive");
645
+
646
+ await this.chatService.streamChat(body.message, (chunk) => {
647
+ res.write(`data: ${JSON.stringify({ chunk })}\n\n`);
648
+ });
649
+
650
+ res.write("data: [DONE]\n\n");
651
+ res.end();
652
+ }
653
+
654
+ @Post("/embeddings")
655
+ async getEmbeddings(@Body() body: any) {
656
+ const embeddings = await this.chatService.generateEmbeddings(body.texts);
657
+ return { embeddings };
658
+ }
659
+ }
660
+ ```
661
+
662
+ **.env Configuration:**
663
+
664
+ ```env
665
+ NODE_ENV=development
666
+ PORT=3000
667
+ OPENAI_API_KEY=sk-your-key-here
668
+ OLLAMA_URL=http://localhost:11434
669
+ ```
670
+
671
+ **Testing AI Endpoints:**
672
+
673
+ ```bash
674
+ # Chat
675
+ curl -X POST http://localhost:3000/chat/message \
676
+ -H "Content-Type: application/json" \
677
+ -d '{"message":"What is TypeScript?"}'
678
+
679
+ # Stream (watch responses appear in real-time)
680
+ curl -X POST http://localhost:3000/chat/stream \
681
+ -H "Content-Type: application/json" \
682
+ -d '{"message":"Write a short story"}' \
683
+ --no-buffer
684
+
685
+ # Embeddings (vector representations of text)
686
+ curl -X POST http://localhost:3000/chat/embeddings \
687
+ -H "Content-Type: application/json" \
688
+ -d '{"texts":["Hello world","Fragment Framework"]}'
689
+ ```
690
+
691
+ ---
692
+
693
+ ## Dependency Injection Patterns
694
+
695
+ ### Use Case 5: Complex DI with Multiple Services
696
+
697
+ ```typescript
698
+ // src/services/email.service.ts
699
+ import { Service } from "fragment";
700
+
701
+ @Service()
702
+ export class EmailService {
703
+ async sendEmail(to: string, subject: string, body: string) {
704
+ console.log(`Sending email to ${to}: ${subject}`);
705
+ // Email sending logic (SendGrid, Mailgun, etc.)
706
+ return { sent: true };
707
+ }
708
+ }
709
+
710
+ // src/services/notification.service.ts
711
+ import { Service, Autowired } from "fragment";
712
+ import { EmailService } from "./email.service";
713
+
714
+ @Service()
715
+ export class NotificationService {
716
+ // Property injection using @Autowired
717
+ @Autowired()
718
+ private emailService: EmailService;
719
+
720
+ async notifyUser(userId: string, message: string) {
721
+ // Send email notification
722
+ await this.emailService.sendEmail(
723
+ `user${userId}@example.com`,
724
+ "Notification",
725
+ message,
726
+ );
727
+ }
728
+ }
729
+
730
+ // src/services/order.service.ts
731
+ import { Service } from "fragment";
732
+ import { NotificationService } from "./notification.service";
733
+ import { ProductRepository } from "../repositories/product.repository";
734
+
735
+ @Service()
736
+ export class OrderService {
737
+ // Constructor injection
738
+ constructor(
739
+ private notificationService: NotificationService,
740
+ private productRepository: ProductRepository,
741
+ ) {}
742
+
743
+ async createOrder(userId: string, productId: number, quantity: number) {
744
+ const product = await this.productRepository.findById(productId);
745
+
746
+ if (!product || product.stock < quantity) {
747
+ throw new Error("Insufficient stock");
748
+ }
749
+
750
+ // Update stock
751
+ await this.productRepository.update(productId, {
752
+ stock: product.stock - quantity,
753
+ });
754
+
755
+ // Notify user
756
+ await this.notificationService.notifyUser(
757
+ userId,
758
+ `Your order for ${quantity}x ${product.name} has been placed!`,
759
+ );
760
+
761
+ return { orderId: Date.now(), product, quantity };
762
+ }
763
+ }
764
+ ```
765
+
766
+ ---
767
+
768
+ ## Advanced Routing
769
+
770
+ ### Use Case 6: Complex Route Parameters
771
+
772
+ ```typescript
773
+ import {
774
+ Controller,
775
+ Get,
776
+ Post,
777
+ Param,
778
+ Query,
779
+ Header,
780
+ Body,
781
+ Req,
782
+ Res,
783
+ } from "fragment";
784
+ import { Request, Response } from "express";
785
+
786
+ @Controller("/api/v1/users")
787
+ export class UserController {
788
+ // Nested route parameters
789
+ // Route: GET /api/v1/users/:userId/orders/:orderId
790
+ @Get("/:userId/orders/:orderId")
791
+ async getUserOrder(
792
+ @Param("userId") userId: string,
793
+ @Param("orderId") orderId: string,
794
+ ) {
795
+ return { userId, orderId };
796
+ }
797
+
798
+ // Query parameters
799
+ // Route: GET /api/v1/users?page=1&limit=10&sort=name
800
+ @Get()
801
+ async getUsers(
802
+ @Query("page") page: string,
803
+ @Query("limit") limit: string,
804
+ @Query("sort") sort: string,
805
+ ) {
806
+ return {
807
+ page: parseInt(page) || 1,
808
+ limit: parseInt(limit) || 10,
809
+ sort: sort || "id",
810
+ users: [],
811
+ };
812
+ }
813
+
814
+ // Header extraction
815
+ @Get("/profile")
816
+ async getProfile(@Header("Authorization") auth: string) {
817
+ return { authorized: !!auth };
818
+ }
819
+
820
+ // Complex body handling
821
+ @Post("/bulk")
822
+ async bulkCreate(@Body() body: any) {
823
+ const users = body.users || [];
824
+ return { created: users.length };
825
+ }
826
+
827
+ // Full request/response access
828
+ @Get("/advanced")
829
+ async advancedRoute(@Req() req: Request, @Res() res: Response) {
830
+ res.status(200).json({
831
+ method: req.method,
832
+ path: req.path,
833
+ headers: req.headers,
834
+ });
835
+ }
836
+ }
837
+ ```
838
+
839
+ ---
840
+
841
+ ## Custom Middleware
842
+
843
+ ### Use Case 7: Request Logging Middleware
844
+
845
+ ```typescript
846
+ // src/middlewares/logger.middleware.ts
847
+ import { Request, Response, NextFunction } from "express";
848
+
849
+ export class LoggerMiddleware {
850
+ use(req: Request, res: Response, next: NextFunction) {
851
+ const start = Date.now();
852
+
853
+ res.on("finish", () => {
854
+ const duration = Date.now() - start;
855
+ console.log(
856
+ `${req.method} ${req.path} - ${res.statusCode} - ${duration}ms`,
857
+ );
858
+ });
859
+
860
+ next();
861
+ }
862
+ }
863
+
864
+ // src/main.ts
865
+ import "reflect-metadata";
866
+ import { FragmentApplication, FragmentWebApplication } from "fragment";
867
+ import { LoggerMiddleware } from "./middlewares/logger.middleware";
868
+
869
+ @FragmentApplication({
870
+ port: 3000,
871
+ autoScan: true,
872
+ })
873
+ class Application {}
874
+
875
+ async function bootstrap() {
876
+ const app = new FragmentWebApplication();
877
+ const expressApp = app.getExpressApp();
878
+
879
+ // Apply middleware
880
+ const logger = new LoggerMiddleware();
881
+ expressApp.use(logger.use.bind(logger));
882
+
883
+ await app.bootstrap(Application);
884
+ }
885
+
886
+ bootstrap();
887
+ ```
888
+
889
+ ---
890
+
891
+ ## Testing
892
+
893
+ ### Use Case 8: Comprehensive Testing
894
+
895
+ ```bash
896
+ # Generate test file alongside controller
897
+ fragment generate controller users
898
+ ```
899
+
900
+ **test/users.spec.ts**
901
+
902
+ ```typescript
903
+ import { describe, it, expect } from "fragment";
904
+ import { DIContainer } from "fragment";
905
+ import { UserService } from "../src/services/user.service";
906
+
907
+ describe("UserService", () => {
908
+ let userService: UserService;
909
+
910
+ beforeEach(() => {
911
+ const container = DIContainer.getInstance();
912
+ userService = container.resolve<UserService>(UserService);
913
+ });
914
+
915
+ it("should create a user", async () => {
916
+ const user = await userService.create({
917
+ email: "test@example.com",
918
+ name: "Test User",
919
+ password: "password123",
920
+ });
921
+
922
+ expect(user).toBeTruthy();
923
+ expect(user.email).toBe("test@example.com");
924
+ expect(user.name).toBe("Test User");
925
+ });
926
+
927
+ it("should find user by id", async () => {
928
+ const user = await userService.findOne("1");
929
+ expect(user).toBeTruthy();
930
+ expect(user.id).toBe(1);
931
+ });
932
+
933
+ it("should throw error for non-existent user", async () => {
934
+ expect(() => userService.findOne("99999")).toThrow();
935
+ });
936
+
937
+ it("should update user", async () => {
938
+ const updated = await userService.update("1", { name: "Updated Name" });
939
+ expect(updated.name).toBe("Updated Name");
940
+ });
941
+ });
942
+ ```
943
+
944
+ ```bash
945
+ # Run tests
946
+ fragment test
947
+
948
+ # Run with coverage
949
+ fragment test --coverage
950
+
951
+ # Run specific test file
952
+ fragment test test/users.spec.ts
953
+ ```
954
+
955
+ ---
956
+
957
+ ## Production Deployment
958
+
959
+ ### Use Case 9: Deploy to Production
960
+
961
+ **Build and Deploy**
962
+
963
+ ```bash
964
+ # Build for production
965
+ fragment build
966
+
967
+ # Verify build
968
+ ls dist/
969
+
970
+ # Set production environment variables
971
+ export NODE_ENV=production
972
+ export PORT=8080
973
+ export DATABASE_URL=postgresql://user:pass@host:5432/db
974
+ export JWT_SECRET=super-secret-production-key
975
+
976
+ # Run migrations
977
+ fragment migrate:run
978
+
979
+ # Start production server
980
+ npm start
981
+ ```
982
+
983
+ **Docker Deployment**
984
+
985
+ **Dockerfile:**
986
+
987
+ ```dockerfile
988
+ FROM node:18-alpine
989
+
990
+ WORKDIR /app
991
+
992
+ # Copy package files
993
+ COPY package*.json ./
994
+
995
+ # Install production dependencies
996
+ RUN npm ci --only=production
997
+
998
+ # Copy source code
999
+ COPY . .
1000
+
1001
+ # Build TypeScript
1002
+ RUN npm run build
1003
+
1004
+ # Expose port
1005
+ EXPOSE 3000
1006
+
1007
+ # Health check
1008
+ HEALTHCHECK --interval=30s --timeout=3s \
1009
+ CMD node -e "require('http').get('http://localhost:3000/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"
1010
+
1011
+ # Start application
1012
+ CMD ["npm", "start"]
1013
+ ```
1014
+
1015
+ **docker-compose.yml:**
1016
+
1017
+ ```yaml
1018
+ version: "3.8"
1019
+
1020
+ services:
1021
+ app:
1022
+ build: .
1023
+ ports:
1024
+ - "3000:3000"
1025
+ environment:
1026
+ - NODE_ENV=production
1027
+ - DATABASE_URL=postgresql://postgres:password@db:5432/myapp
1028
+ - JWT_SECRET=your-secret-key
1029
+ depends_on:
1030
+ - db
1031
+ restart: unless-stopped
1032
+
1033
+ db:
1034
+ image: postgres:15-alpine
1035
+ environment:
1036
+ - POSTGRES_DB=myapp
1037
+ - POSTGRES_USER=postgres
1038
+ - POSTGRES_PASSWORD=password
1039
+ volumes:
1040
+ - db-data:/var/lib/postgresql/data
1041
+ restart: unless-stopped
1042
+
1043
+ volumes:
1044
+ db-data:
1045
+ ```
1046
+
1047
+ ```bash
1048
+ # Build and start services
1049
+ docker-compose up -d
1050
+
1051
+ # View logs
1052
+ docker-compose logs -f app
1053
+
1054
+ # Run migrations in container
1055
+ docker-compose exec app fragment migrate:run
1056
+
1057
+ # Stop services
1058
+ docker-compose down
1059
+
1060
+ # Stop and remove volumes
1061
+ docker-compose down -v
1062
+ ```
1063
+
1064
+ ---
1065
+
1066
+ ## CLI Reference
1067
+
1068
+ ### Complete CLI Command Reference
1069
+
1070
+ **Project Management**
1071
+
1072
+ ```bash
1073
+ fragment init [dir] # Initialize new project
1074
+ fragment init . --features=auth # Initialize with features in current dir
1075
+ fragment serve # Start development server
1076
+ fragment serve --port=4000 # Start on custom port
1077
+ fragment serve --no-watch # Disable hot reload
1078
+ fragment build # Build for production
1079
+ ```
1080
+
1081
+ **Code Generation**
1082
+
1083
+ ```bash
1084
+ fragment generate <type> <name> # Generate component
1085
+ fragment g <type> <name> # Shorthand
1086
+
1087
+ # Types:
1088
+ fragment generate controller users
1089
+ fragment generate service auth
1090
+ fragment generate entity product
1091
+ fragment generate repository users
1092
+ fragment generate dto create-user
1093
+ fragment generate resource product # Generates all of the above
1094
+
1095
+ # With options:
1096
+ fragment generate service users --with-repository
1097
+ ```
1098
+
1099
+ **Database Operations**
1100
+
1101
+ ```bash
1102
+ fragment migrate # Run pending migrations
1103
+ fragment migrate:create <name> # Create new migration
1104
+ fragment migrate:run # Run migrations
1105
+ fragment migrate:revert # Revert last migration
1106
+ fragment migrate:refresh # Drop and re-run all migrations
1107
+ fragment migrate:status # Show migration status
1108
+ fragment schema:sync # Sync schema (dev only)
1109
+ fragment schema:drop # Drop all tables
1110
+ fragment seed # Run seeds
1111
+ fragment seed:create <name> # Create seed file
1112
+ ```
1113
+
1114
+ **Diagnostics**
1115
+
1116
+ ```bash
1117
+ fragment routes # List all routes (auto-detect mode)
1118
+ fragment routes --env=dev # List routes from TypeScript src/
1119
+ fragment routes --env=prod # List routes from compiled dist/
1120
+ fragment beans # List all beans
1121
+ fragment beans --tree # Show beans as tree
1122
+ fragment info # Show app information
1123
+ fragment config # Show configuration
1124
+ fragment version # Show Fragment version
1125
+ ```
1126
+
1127
+ ### Diagnostics & Debugging
1128
+
1129
+ **Environment-Specific Diagnostics**
1130
+
1131
+ ```bash
1132
+ # Auto-detect (prefers src/ if available, falls back to dist/)
1133
+ fragment routes
1134
+ fragment beans
1135
+
1136
+ # Force development mode (use TypeScript source)
1137
+ fragment routes --env=dev
1138
+ fragment beans --env=dev --tree
1139
+
1140
+ # Force production mode (use compiled JavaScript)
1141
+ fragment routes --env=prod
1142
+ fragment beans --env=prod
1143
+
1144
+ # Show application info
1145
+ fragment info
1146
+ # Output:
1147
+ # 📊 Application Information:
1148
+ # Name: my-app
1149
+ # Version: 1.0.0
1150
+ # Node: v18.17.0
1151
+ # Platform: darwin
1152
+ # Architecture: arm64
1153
+ # Environment: development
1154
+ # Source: ✓ src/
1155
+ # Built: ✓ dist/
1156
+
1157
+ # View configuration
1158
+ fragment config
1159
+ # Shows contents of fragment.json
1160
+
1161
+ # Check version
1162
+ fragment version
1163
+ # ✨ Fragment Framework v1.0.0
1164
+ ```
1165
+
1166
+ ---
1167
+
1168
+ ## Best Practices
1169
+
1170
+ ### Development
1171
+
1172
+ 1. **Always use decorators** - Leverage `@Controller`, `@Service`, `@Injectable` for clean architecture
1173
+ 2. **Keep services focused** - One responsibility per service (Single Responsibility Principle)
1174
+ 3. **Use DTOs** - Define Data Transfer Objects for request/response validation
1175
+ 4. **Type everything** - Take advantage of TypeScript's type system
1176
+ 5. **Use environment variables** - Never hardcode secrets or configuration
1177
+
1178
+ ### Database
1179
+
1180
+ 1. **Use migrations in production** - Never use `synchronize: true` in production
1181
+ 2. **Version your migrations** - Keep migration files in version control
1182
+ 3. **Test migrations** - Always test both `up` and `down` migrations
1183
+ 4. **Use transactions** - Wrap related operations in database transactions
1184
+ 5. **Index strategically** - Add indexes for frequently queried columns
1185
+
1186
+ ### Security
1187
+
1188
+ 1. **Hash passwords** - Always use `AuthModule.hashPassword()`
1189
+ 2. **Validate input** - Use DTOs with class-validator
1190
+ 3. **Rate limiting** - Implement rate limiting on public endpoints
1191
+ 4. **CORS configuration** - Configure CORS appropriately for your frontend
1192
+ 5. **Environment-specific secrets** - Use different secrets for dev/prod
1193
+
1194
+ ### Testing
1195
+
1196
+ 1. **Test business logic** - Focus on service and repository tests
1197
+ 2. **Mock external dependencies** - Don't hit real databases or APIs in tests
1198
+ 3. **Test edge cases** - Test error conditions and boundary cases
1199
+ 4. **Use descriptive test names** - Make test failures easy to understand
1200
+
1201
+ ### Deployment
1202
+
1203
+ 1. **Use Docker** - Containerize your application for consistent deployments
1204
+ 2. **Health checks** - Implement health check endpoints
1205
+ 3. **Logging** - Use structured logging for production
1206
+ 4. **Monitoring** - Set up monitoring and alerting
1207
+ 5. **Backup strategy** - Regular database backups
1208
+
1209
+ ---
1210
+
1211
+ ## Troubleshooting
1212
+
1213
+ ### Common Issues and Solutions
1214
+
1215
+ #### Issue: "Cannot find module"
1216
+
1217
+ ```bash
1218
+ # Solution: Rebuild the project
1219
+ npm run build
1220
+ fragment serve
1221
+ ```
1222
+
1223
+ #### Issue: "Port already in use"
1224
+
1225
+ ```bash
1226
+ # Solution 1: Use different port
1227
+ fragment serve --port=4000
1228
+
1229
+ # Solution 2: Kill process using port (macOS/Linux)
1230
+ lsof -ti:3000 | xargs kill -9
1231
+
1232
+ # Solution 3: Kill process using port (Windows)
1233
+ netstat -ano | findstr :3000
1234
+ taskkill /PID <PID> /F
1235
+ ```
1236
+
1237
+ #### Issue: "Database connection failed"
1238
+
1239
+ ```bash
1240
+ # Check configuration
1241
+ fragment config
1242
+
1243
+ # Test connection
1244
+ fragment migrate:status
1245
+
1246
+ # Verify DATABASE_URL
1247
+ echo $DATABASE_URL
1248
+
1249
+ # Common fixes:
1250
+ # - Ensure database server is running
1251
+ # - Check username/password
1252
+ # - Verify database name exists
1253
+ # - Check network connectivity
1254
+ ```
1255
+
1256
+ #### Issue: "Decorators not working"
1257
+
1258
+ ```bash
1259
+ # Ensure tsconfig.json has these settings:
1260
+ {
1261
+ "compilerOptions": {
1262
+ "experimentalDecorators": true,
1263
+ "emitDecoratorMetadata": true
1264
+ }
1265
+ }
1266
+
1267
+ # Rebuild after changes
1268
+ npm run build
1269
+ ```
1270
+
1271
+ #### Issue: "Routes not registering"
1272
+
1273
+ ```bash
1274
+ # Check if components are being scanned
1275
+ fragment routes
1276
+
1277
+ # If no routes shown:
1278
+ # 1. Ensure files follow naming convention (*.controller.ts)
1279
+ # 2. Verify decorators are applied correctly
1280
+ # 3. Check if autoScan is enabled in @FragmentApplication
1281
+ # 4. Try manual import in main.ts
1282
+
1283
+ # Force specific environment
1284
+ fragment routes --env=dev
1285
+ fragment routes --env=prod
1286
+ ```
1287
+
1288
+ #### Issue: "Circular dependency detected"
1289
+
1290
+ ```bash
1291
+ # Error: Circular dependency detected: UserService
1292
+
1293
+ # Solution: Use property injection instead of constructor injection
1294
+ # Before (circular):
1295
+ @Service()
1296
+ class UserService {
1297
+ constructor(private authService: AuthService) {}
1298
+ }
1299
+ @Service()
1300
+ class AuthService {
1301
+ constructor(private userService: UserService) {} // Circular!
1302
+ }
1303
+
1304
+ # After (fixed):
1305
+ @Service()
1306
+ class UserService {
1307
+ @Autowired()
1308
+ private authService: AuthService; // Property injection breaks cycle
1309
+ }
1310
+ ```
1311
+
1312
+ #### Issue: "Hot reload not working"
1313
+
1314
+ ```bash
1315
+ # Check if chokidar is installed
1316
+ npm install --save-dev chokidar
1317
+
1318
+ # Restart with watch mode explicitly enabled
1319
+ fragment serve --watch
1320
+
1321
+ # Check file watch patterns in serve command
1322
+ ```
1323
+
1324
+ #### Issue: "Migration fails"
1325
+
1326
+ ```bash
1327
+ # Revert last migration
1328
+ fragment migrate:revert
1329
+
1330
+ # Check migration status
1331
+ fragment migrate:status
1332
+
1333
+ # Fix migration file and re-run
1334
+ fragment migrate:run
1335
+
1336
+ # If all else fails, drop and recreate (DEV ONLY!)
1337
+ fragment schema:drop
1338
+ fragment migrate:run
1339
+ ```
1340
+
1341
+ #### Issue: "TypeScript compilation errors"
1342
+
1343
+ ```bash
1344
+ # Check TypeScript version compatibility
1345
+ npm list typescript
1346
+
1347
+ # Clear build artifacts
1348
+ rm -rf dist/
1349
+ npm run build
1350
+
1351
+ # Check for conflicting type definitions
1352
+ npm list @types
1353
+ ```
1354
+
1355
+ ---
1356
+
1357
+ ## Performance Tips
1358
+
1359
+ ### Optimize Database Queries
1360
+
1361
+ ```typescript
1362
+ // Use eager loading to avoid N+1 queries
1363
+ const users = await userRepository.find({
1364
+ relations: ["posts", "comments"],
1365
+ });
1366
+
1367
+ // Use indexes for frequently queried columns
1368
+ @Entity()
1369
+ export class User {
1370
+ @Index()
1371
+ @Column({ unique: true })
1372
+ email: string;
1373
+ }
1374
+
1375
+ // Use pagination for large datasets
1376
+ const [users, total] = await userRepository.findAndCount({
1377
+ skip: (page - 1) * limit,
1378
+ take: limit,
1379
+ });
1380
+ ```
1381
+
1382
+ ### Caching Strategies
1383
+
1384
+ ```typescript
1385
+ // In-memory cache for frequently accessed data
1386
+ @Service()
1387
+ export class CacheService {
1388
+ private cache = new Map<string, any>();
1389
+
1390
+ get(key: string) {
1391
+ return this.cache.get(key);
1392
+ }
1393
+
1394
+ set(key: string, value: any, ttl: number = 3600000) {
1395
+ this.cache.set(key, value);
1396
+ setTimeout(() => this.cache.delete(key), ttl);
1397
+ }
1398
+ }
1399
+ ```
1400
+
1401
+ ### Connection Pooling
1402
+
1403
+ ```json
1404
+ // fragment.json
1405
+ {
1406
+ "database": {
1407
+ "poolSize": 10,
1408
+ "maxQueryExecutionTime": 1000
1409
+ }
1410
+ }
1411
+ ```
1412
+
1413
+ ---
1414
+
1415
+ ## Summary
1416
+
1417
+ Fragment Framework provides:
1418
+
1419
+ - ✅ **Quick project initialization** - `fragment init .` or `fragment init my-app`
1420
+ - ✅ **Hot reload development** - Automatic server restart on file changes
1421
+ - ✅ **Comprehensive CLI** - Code generation, migrations, diagnostics
1422
+ - ✅ **Built-in authentication** - JWT, password hashing, role guards
1423
+ - ✅ **Database migrations** - TypeORM integration with full migration support
1424
+ - ✅ **AI integrations** - OpenAI, Ollama, and custom providers
1425
+ - ✅ **Production-ready** - Docker, health checks, logging
1426
+ - ✅ **Type-safe DI** - Automatic dependency injection
1427
+ - ✅ **Convention over configuration** - Sensible defaults, minimal setup
1428
+ - ✅ **Environment flexibility** - Dev/prod modes with `--env` flag
1429
+
1430
+ **Start building your next TypeScript application with Fragment today!**
1431
+
1432
+ ```bash
1433
+ npm install -g fragment
1434
+ fragment init my-app
1435
+ cd my-app
1436
+ fragment serve
1437
+ ```
1438
+
1439
+ Visit [https://fragment.digitwhale.com](https://fragment.digitwhale.com) for more documentation and examples.