@akanjs/cli 0.0.142 → 0.0.144

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 (349) hide show
  1. package/README.md +8 -0
  2. package/cjs/index.js +2437 -3204
  3. package/cjs/src/guidelines/___library/sharedUiStructureDescription.en.md +786 -0
  4. package/cjs/src/guidelines/___library/utilUiStructureDescription.en.md +395 -0
  5. package/cjs/src/guidelines/___lint/lintRuleDescription.en.md +64 -0
  6. package/cjs/src/guidelines/___module/moduleStructureDescription.en.md +80 -0
  7. package/cjs/src/guidelines/componentRule/componentRule.instruction.md +732 -0
  8. package/cjs/src/guidelines/databaseModule/databaseModule.instruction.md +691 -0
  9. package/cjs/src/guidelines/enumConstant/enumConstant.instruction.md +232 -0
  10. package/cjs/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +611 -0
  11. package/cjs/src/guidelines/framework/framework.instruction.md +1112 -0
  12. package/cjs/src/guidelines/modelConstant/modelConstant.instruction.md +958 -0
  13. package/cjs/src/guidelines/modelDictionary/modelDictionary.instruction.md +583 -0
  14. package/cjs/src/guidelines/modelDocument/modelDocument.instruction.md +683 -0
  15. package/cjs/src/guidelines/modelService/modelService.instruction.md +935 -0
  16. package/cjs/src/guidelines/modelSignal/modelSignal.instruction.md +588 -0
  17. package/cjs/src/guidelines/modelStore/modelStore.instruction.md +591 -0
  18. package/cjs/src/guidelines/modelTemplate/modelTemplate.instruction.md +577 -0
  19. package/cjs/src/guidelines/modelUnit/modelUnit.instruction.md +833 -0
  20. package/cjs/src/guidelines/modelUtil/modelUtil.instruction.md +752 -0
  21. package/cjs/src/guidelines/modelView/modelView.instruction.md +1005 -0
  22. package/cjs/src/guidelines/modelZone/modelZone.instruction.md +528 -0
  23. package/cjs/src/guidelines/scalarConstant/scalarConstant.instruction.md +489 -0
  24. package/cjs/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +347 -0
  25. package/cjs/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +318 -0
  26. package/cjs/src/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
  27. package/cjs/src/templates/module/__model__.dictionary.js +4 -5
  28. package/esm/index.js +2524 -3286
  29. package/esm/src/guidelines/___library/sharedUiStructureDescription.en.md +786 -0
  30. package/esm/src/guidelines/___library/utilUiStructureDescription.en.md +395 -0
  31. package/esm/src/guidelines/___lint/lintRuleDescription.en.md +64 -0
  32. package/esm/src/guidelines/___module/moduleStructureDescription.en.md +80 -0
  33. package/esm/src/guidelines/componentRule/componentRule.instruction.md +732 -0
  34. package/esm/src/guidelines/databaseModule/databaseModule.instruction.md +691 -0
  35. package/esm/src/guidelines/enumConstant/enumConstant.instruction.md +232 -0
  36. package/esm/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +611 -0
  37. package/esm/src/guidelines/framework/framework.instruction.md +1112 -0
  38. package/esm/src/guidelines/modelConstant/modelConstant.instruction.md +958 -0
  39. package/esm/src/guidelines/modelDictionary/modelDictionary.instruction.md +583 -0
  40. package/esm/src/guidelines/modelDocument/modelDocument.instruction.md +683 -0
  41. package/esm/src/guidelines/modelService/modelService.instruction.md +935 -0
  42. package/esm/src/guidelines/modelSignal/modelSignal.instruction.md +588 -0
  43. package/esm/src/guidelines/modelStore/modelStore.instruction.md +591 -0
  44. package/esm/src/guidelines/modelTemplate/modelTemplate.instruction.md +577 -0
  45. package/esm/src/guidelines/modelUnit/modelUnit.instruction.md +833 -0
  46. package/esm/src/guidelines/modelUtil/modelUtil.instruction.md +752 -0
  47. package/esm/src/guidelines/modelView/modelView.instruction.md +1005 -0
  48. package/esm/src/guidelines/modelZone/modelZone.instruction.md +528 -0
  49. package/esm/src/guidelines/scalarConstant/scalarConstant.instruction.md +489 -0
  50. package/esm/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +347 -0
  51. package/esm/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +318 -0
  52. package/esm/src/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
  53. package/esm/src/templates/module/__model__.dictionary.js +4 -5
  54. package/package.json +3 -1
  55. package/src/guideline/guideline.command.d.ts +7 -0
  56. package/src/guideline/guideline.prompt.d.ts +15 -0
  57. package/src/guideline/guideline.runner.d.ts +5 -0
  58. package/src/guideline/guideline.script.d.ts +6 -0
  59. package/src/guidelines/___library/sharedUiStructureDescription.en.md +786 -0
  60. package/src/guidelines/___library/utilUiStructureDescription.en.md +395 -0
  61. package/src/guidelines/___lint/lintRuleDescription.en.md +64 -0
  62. package/src/guidelines/___module/moduleStructureDescription.en.md +80 -0
  63. package/src/guidelines/componentRule/componentRule.instruction.md +732 -0
  64. package/src/guidelines/databaseModule/databaseModule.instruction.md +691 -0
  65. package/src/guidelines/enumConstant/enumConstant.instruction.md +232 -0
  66. package/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +611 -0
  67. package/src/guidelines/framework/framework.instruction.md +1112 -0
  68. package/src/guidelines/modelConstant/modelConstant.instruction.md +958 -0
  69. package/src/guidelines/modelDictionary/modelDictionary.instruction.md +583 -0
  70. package/src/guidelines/modelDocument/modelDocument.instruction.md +683 -0
  71. package/src/guidelines/modelService/modelService.instruction.md +935 -0
  72. package/src/guidelines/modelSignal/modelSignal.instruction.md +588 -0
  73. package/src/guidelines/modelStore/modelStore.instruction.md +591 -0
  74. package/src/guidelines/modelTemplate/modelTemplate.instruction.md +577 -0
  75. package/src/guidelines/modelUnit/modelUnit.instruction.md +833 -0
  76. package/src/guidelines/modelUtil/modelUtil.instruction.md +752 -0
  77. package/src/guidelines/modelView/modelView.instruction.md +1005 -0
  78. package/src/guidelines/modelZone/modelZone.instruction.md +528 -0
  79. package/src/guidelines/scalarConstant/scalarConstant.instruction.md +489 -0
  80. package/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +347 -0
  81. package/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +318 -0
  82. package/src/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
  83. package/src/module/module.command.d.ts +6 -8
  84. package/src/module/module.prompt.d.ts +2 -15
  85. package/src/module/module.request.d.ts +22 -18
  86. package/src/module/module.runner.d.ts +4 -20
  87. package/src/module/module.script.d.ts +6 -7
  88. package/src/scalar/scalar.command.d.ts +7 -0
  89. package/src/scalar/scalar.prompt.d.ts +23 -0
  90. package/src/scalar/scalar.runner.d.ts +13 -0
  91. package/src/scalar/scalar.script.d.ts +6 -0
  92. package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/forgotpassword/page.js +0 -47
  93. package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/page.js +0 -128
  94. package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/privacy/page.js +0 -42
  95. package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/signin/page.js +0 -50
  96. package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/termsofservice/page.js +0 -41
  97. package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/unknown/page.js +0 -51
  98. package/cjs/src/templates/app/app/[lang]/(__appName__)/(user)/layout.js +0 -43
  99. package/cjs/src/templates/app/app/[lang]/(__appName__)/(user)/self/page.js +0 -60
  100. package/cjs/src/templates/app/app/[lang]/(__appName__)/layout.js +0 -54
  101. package/cjs/src/templates/app/app/[lang]/(__appName__)/styles.css.template +0 -19
  102. package/cjs/src/templates/app/app/[lang]/admin/layout.js +0 -54
  103. package/cjs/src/templates/app/app/[lang]/admin/page.js +0 -63
  104. package/cjs/src/templates/app/app/csr.js +0 -34
  105. package/cjs/src/templates/app/app/index.html.template +0 -13
  106. package/cjs/src/templates/app/app/layout.js +0 -38
  107. package/cjs/src/templates/app/capacitor.config.ts.template +0 -8
  108. package/cjs/src/templates/app/env/env.client.debug.ts.template +0 -7
  109. package/cjs/src/templates/app/env/env.client.develop.ts.template +0 -7
  110. package/cjs/src/templates/app/env/env.client.local.ts.template +0 -7
  111. package/cjs/src/templates/app/env/env.client.main.ts.template +0 -7
  112. package/cjs/src/templates/app/env/env.client.testing.ts.template +0 -7
  113. package/cjs/src/templates/app/env/env.server.debug.ts.template +0 -15
  114. package/cjs/src/templates/app/env/env.server.develop.ts.template +0 -15
  115. package/cjs/src/templates/app/env/env.server.local.ts.template +0 -15
  116. package/cjs/src/templates/app/env/env.server.main.ts.template +0 -15
  117. package/cjs/src/templates/app/env/env.server.testing.ts.template +0 -7
  118. package/cjs/src/templates/app/lib/setting/Setting.Template.js +0 -57
  119. package/cjs/src/templates/app/lib/setting/Setting.Unit.js +0 -38
  120. package/cjs/src/templates/app/lib/setting/Setting.Util.js +0 -34
  121. package/cjs/src/templates/app/lib/setting/Setting.View.js +0 -51
  122. package/cjs/src/templates/app/lib/setting/Setting.Zone.js +0 -80
  123. package/cjs/src/templates/app/lib/setting/index.js +0 -61
  124. package/cjs/src/templates/app/lib/summary/Summary.Template.js +0 -43
  125. package/cjs/src/templates/app/lib/summary/Summary.Unit.js +0 -38
  126. package/cjs/src/templates/app/lib/summary/Summary.Util.js +0 -33
  127. package/cjs/src/templates/app/lib/summary/Summary.View.js +0 -51
  128. package/cjs/src/templates/app/lib/summary/Summary.Zone.js +0 -62
  129. package/cjs/src/templates/app/lib/summary/index.js +0 -67
  130. package/cjs/src/templates/app/lib/user/User.Template.js +0 -65
  131. package/cjs/src/templates/app/lib/user/User.Unit.js +0 -38
  132. package/cjs/src/templates/app/lib/user/User.Util.js +0 -94
  133. package/cjs/src/templates/app/lib/user/User.View.js +0 -66
  134. package/cjs/src/templates/app/lib/user/User.Zone.js +0 -74
  135. package/cjs/src/templates/app/lib/user/index.js +0 -61
  136. package/cjs/src/templates/app/page.test.ts.template +0 -10
  137. package/cjs/src/templates/app/playwright.config.ts.template +0 -6
  138. package/cjs/src/templates/app/postcss.config.js.template +0 -10
  139. package/cjs/src/templates/app/public/manifest.json.template +0 -67
  140. package/cjs/src/templates/app/tsconfig.json.template +0 -22
  141. package/cjs/src/templates/app/tsconfig.spec.json.template +0 -7
  142. package/cjs/src/templates/app/ui/Footer.js +0 -67
  143. package/cjs/src/templates/app/ui/MainHeader.js +0 -131
  144. package/cjs/src/templates/crudPages/[__model__Id]/edit/page.js +0 -73
  145. package/cjs/src/templates/crudPages/[__model__Id]/page.js +0 -83
  146. package/cjs/src/templates/crudPages/new/page.js +0 -70
  147. package/cjs/src/templates/crudPages/page.js +0 -71
  148. package/cjs/src/templates/libRoot/.gitignore.template +0 -15
  149. package/cjs/src/templates/libRoot/env/env.server.example.ts.template +0 -7
  150. package/cjs/src/templates/libRoot/env/env.server.testing.ts.template +0 -7
  151. package/cjs/src/templates/libRoot/lib/setting/Setting.Template.js +0 -57
  152. package/cjs/src/templates/libRoot/lib/setting/Setting.Unit.js +0 -38
  153. package/cjs/src/templates/libRoot/lib/setting/Setting.Util.js +0 -34
  154. package/cjs/src/templates/libRoot/lib/setting/Setting.View.js +0 -51
  155. package/cjs/src/templates/libRoot/lib/setting/Setting.Zone.js +0 -80
  156. package/cjs/src/templates/libRoot/lib/setting/index.js +0 -61
  157. package/cjs/src/templates/libRoot/lib/summary/Summary.Template.js +0 -43
  158. package/cjs/src/templates/libRoot/lib/summary/Summary.Unit.js +0 -38
  159. package/cjs/src/templates/libRoot/lib/summary/Summary.Util.js +0 -33
  160. package/cjs/src/templates/libRoot/lib/summary/Summary.View.js +0 -51
  161. package/cjs/src/templates/libRoot/lib/summary/Summary.Zone.js +0 -62
  162. package/cjs/src/templates/libRoot/lib/summary/index.js +0 -67
  163. package/cjs/src/templates/libRoot/lib/user/User.Template.js +0 -65
  164. package/cjs/src/templates/libRoot/lib/user/User.Unit.js +0 -38
  165. package/cjs/src/templates/libRoot/lib/user/User.Util.js +0 -94
  166. package/cjs/src/templates/libRoot/lib/user/User.View.js +0 -66
  167. package/cjs/src/templates/libRoot/lib/user/User.Zone.js +0 -74
  168. package/cjs/src/templates/libRoot/lib/user/index.js +0 -61
  169. package/cjs/src/templates/libRoot/package.json.template +0 -4
  170. package/cjs/src/templates/libRoot/tsconfig.json.template +0 -13
  171. package/cjs/src/templates/libRoot/tsconfig.spec.json.template +0 -7
  172. package/cjs/src/templates/localDev/docker-compose.yaml.template +0 -36
  173. package/cjs/src/templates/module/__Model__.Template.js +0 -54
  174. package/cjs/src/templates/module/__Model__.Unit.js +0 -42
  175. package/cjs/src/templates/module/__Model__.Util.js +0 -70
  176. package/cjs/src/templates/module/__Model__.View.js +0 -48
  177. package/cjs/src/templates/module/__Model__.Zone.js +0 -83
  178. package/cjs/src/templates/module/index.js +0 -61
  179. package/cjs/src/templates/pkgRoot/tsconfig.json.template +0 -15
  180. package/cjs/src/templates/workspaceRoot/.env.template +0 -20
  181. package/cjs/src/templates/workspaceRoot/.gitignore.template +0 -118
  182. package/cjs/src/templates/workspaceRoot/.prettierignore.template +0 -10
  183. package/cjs/src/templates/workspaceRoot/.prettierrc.json.template +0 -6
  184. package/cjs/src/templates/workspaceRoot/.swcrc.template +0 -9
  185. package/cjs/src/templates/workspaceRoot/.vscode/settings.json.template +0 -13
  186. package/cjs/src/templates/workspaceRoot/README.md.template +0 -37
  187. package/cjs/src/templates/workspaceRoot/eslint.config.ts.template +0 -3
  188. package/cjs/src/templates/workspaceRoot/package.json.template +0 -43
  189. package/cjs/src/templates/workspaceRoot/tsconfig.json.template +0 -29
  190. package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/forgotpassword/page.js +0 -27
  191. package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/page.js +0 -108
  192. package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/privacy/page.js +0 -22
  193. package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/signin/page.js +0 -30
  194. package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/termsofservice/page.js +0 -21
  195. package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/unknown/page.js +0 -31
  196. package/esm/src/templates/app/app/[lang]/(__appName__)/(user)/layout.js +0 -23
  197. package/esm/src/templates/app/app/[lang]/(__appName__)/(user)/self/page.js +0 -40
  198. package/esm/src/templates/app/app/[lang]/(__appName__)/layout.js +0 -34
  199. package/esm/src/templates/app/app/[lang]/(__appName__)/styles.css.template +0 -19
  200. package/esm/src/templates/app/app/[lang]/admin/layout.js +0 -34
  201. package/esm/src/templates/app/app/[lang]/admin/page.js +0 -43
  202. package/esm/src/templates/app/app/csr.js +0 -14
  203. package/esm/src/templates/app/app/index.html.template +0 -13
  204. package/esm/src/templates/app/app/layout.js +0 -18
  205. package/esm/src/templates/app/capacitor.config.ts.template +0 -8
  206. package/esm/src/templates/app/env/env.client.debug.ts.template +0 -7
  207. package/esm/src/templates/app/env/env.client.develop.ts.template +0 -7
  208. package/esm/src/templates/app/env/env.client.local.ts.template +0 -7
  209. package/esm/src/templates/app/env/env.client.main.ts.template +0 -7
  210. package/esm/src/templates/app/env/env.client.testing.ts.template +0 -7
  211. package/esm/src/templates/app/env/env.server.debug.ts.template +0 -15
  212. package/esm/src/templates/app/env/env.server.develop.ts.template +0 -15
  213. package/esm/src/templates/app/env/env.server.local.ts.template +0 -15
  214. package/esm/src/templates/app/env/env.server.main.ts.template +0 -15
  215. package/esm/src/templates/app/env/env.server.testing.ts.template +0 -7
  216. package/esm/src/templates/app/lib/setting/Setting.Template.js +0 -37
  217. package/esm/src/templates/app/lib/setting/Setting.Unit.js +0 -18
  218. package/esm/src/templates/app/lib/setting/Setting.Util.js +0 -14
  219. package/esm/src/templates/app/lib/setting/Setting.View.js +0 -31
  220. package/esm/src/templates/app/lib/setting/Setting.Zone.js +0 -60
  221. package/esm/src/templates/app/lib/setting/index.js +0 -41
  222. package/esm/src/templates/app/lib/summary/Summary.Template.js +0 -23
  223. package/esm/src/templates/app/lib/summary/Summary.Unit.js +0 -18
  224. package/esm/src/templates/app/lib/summary/Summary.Util.js +0 -13
  225. package/esm/src/templates/app/lib/summary/Summary.View.js +0 -31
  226. package/esm/src/templates/app/lib/summary/Summary.Zone.js +0 -42
  227. package/esm/src/templates/app/lib/summary/index.js +0 -47
  228. package/esm/src/templates/app/lib/user/User.Template.js +0 -45
  229. package/esm/src/templates/app/lib/user/User.Unit.js +0 -18
  230. package/esm/src/templates/app/lib/user/User.Util.js +0 -74
  231. package/esm/src/templates/app/lib/user/User.View.js +0 -46
  232. package/esm/src/templates/app/lib/user/User.Zone.js +0 -54
  233. package/esm/src/templates/app/lib/user/index.js +0 -41
  234. package/esm/src/templates/app/page.test.ts.template +0 -10
  235. package/esm/src/templates/app/playwright.config.ts.template +0 -6
  236. package/esm/src/templates/app/postcss.config.js.template +0 -10
  237. package/esm/src/templates/app/public/manifest.json.template +0 -67
  238. package/esm/src/templates/app/tsconfig.json.template +0 -22
  239. package/esm/src/templates/app/tsconfig.spec.json.template +0 -7
  240. package/esm/src/templates/app/ui/Footer.js +0 -47
  241. package/esm/src/templates/app/ui/MainHeader.js +0 -111
  242. package/esm/src/templates/crudPages/[__model__Id]/edit/page.js +0 -53
  243. package/esm/src/templates/crudPages/[__model__Id]/page.js +0 -63
  244. package/esm/src/templates/crudPages/new/page.js +0 -50
  245. package/esm/src/templates/crudPages/page.js +0 -51
  246. package/esm/src/templates/libRoot/.gitignore.template +0 -15
  247. package/esm/src/templates/libRoot/env/env.server.example.ts.template +0 -7
  248. package/esm/src/templates/libRoot/env/env.server.testing.ts.template +0 -7
  249. package/esm/src/templates/libRoot/lib/setting/Setting.Template.js +0 -37
  250. package/esm/src/templates/libRoot/lib/setting/Setting.Unit.js +0 -18
  251. package/esm/src/templates/libRoot/lib/setting/Setting.Util.js +0 -14
  252. package/esm/src/templates/libRoot/lib/setting/Setting.View.js +0 -31
  253. package/esm/src/templates/libRoot/lib/setting/Setting.Zone.js +0 -60
  254. package/esm/src/templates/libRoot/lib/setting/index.js +0 -41
  255. package/esm/src/templates/libRoot/lib/summary/Summary.Template.js +0 -23
  256. package/esm/src/templates/libRoot/lib/summary/Summary.Unit.js +0 -18
  257. package/esm/src/templates/libRoot/lib/summary/Summary.Util.js +0 -13
  258. package/esm/src/templates/libRoot/lib/summary/Summary.View.js +0 -31
  259. package/esm/src/templates/libRoot/lib/summary/Summary.Zone.js +0 -42
  260. package/esm/src/templates/libRoot/lib/summary/index.js +0 -47
  261. package/esm/src/templates/libRoot/lib/user/User.Template.js +0 -45
  262. package/esm/src/templates/libRoot/lib/user/User.Unit.js +0 -18
  263. package/esm/src/templates/libRoot/lib/user/User.Util.js +0 -74
  264. package/esm/src/templates/libRoot/lib/user/User.View.js +0 -46
  265. package/esm/src/templates/libRoot/lib/user/User.Zone.js +0 -54
  266. package/esm/src/templates/libRoot/lib/user/index.js +0 -41
  267. package/esm/src/templates/libRoot/package.json.template +0 -4
  268. package/esm/src/templates/libRoot/tsconfig.json.template +0 -13
  269. package/esm/src/templates/libRoot/tsconfig.spec.json.template +0 -7
  270. package/esm/src/templates/localDev/docker-compose.yaml.template +0 -36
  271. package/esm/src/templates/module/__Model__.Template.js +0 -34
  272. package/esm/src/templates/module/__Model__.Unit.js +0 -22
  273. package/esm/src/templates/module/__Model__.Util.js +0 -50
  274. package/esm/src/templates/module/__Model__.View.js +0 -28
  275. package/esm/src/templates/module/__Model__.Zone.js +0 -63
  276. package/esm/src/templates/module/index.js +0 -41
  277. package/esm/src/templates/pkgRoot/tsconfig.json.template +0 -15
  278. package/esm/src/templates/workspaceRoot/.env.template +0 -20
  279. package/esm/src/templates/workspaceRoot/.gitignore.template +0 -118
  280. package/esm/src/templates/workspaceRoot/.prettierignore.template +0 -10
  281. package/esm/src/templates/workspaceRoot/.prettierrc.json.template +0 -6
  282. package/esm/src/templates/workspaceRoot/.swcrc.template +0 -9
  283. package/esm/src/templates/workspaceRoot/.vscode/settings.json.template +0 -13
  284. package/esm/src/templates/workspaceRoot/README.md.template +0 -37
  285. package/esm/src/templates/workspaceRoot/eslint.config.ts.template +0 -3
  286. package/esm/src/templates/workspaceRoot/package.json.template +0 -43
  287. package/esm/src/templates/workspaceRoot/tsconfig.json.template +0 -29
  288. package/src/application/application.prompt.d.ts +0 -2
  289. package/src/templates/app/app/[lang]/(__appName__)/(public)/forgotpassword/page.d.ts +0 -9
  290. package/src/templates/app/app/[lang]/(__appName__)/(public)/page.d.ts +0 -9
  291. package/src/templates/app/app/[lang]/(__appName__)/(public)/privacy/page.d.ts +0 -9
  292. package/src/templates/app/app/[lang]/(__appName__)/(public)/signin/page.d.ts +0 -9
  293. package/src/templates/app/app/[lang]/(__appName__)/(public)/termsofservice/page.d.ts +0 -10
  294. package/src/templates/app/app/[lang]/(__appName__)/(public)/unknown/page.d.ts +0 -9
  295. package/src/templates/app/app/[lang]/(__appName__)/(user)/layout.d.ts +0 -9
  296. package/src/templates/app/app/[lang]/(__appName__)/(user)/self/page.d.ts +0 -9
  297. package/src/templates/app/app/[lang]/(__appName__)/layout.d.ts +0 -9
  298. package/src/templates/app/app/[lang]/admin/layout.d.ts +0 -9
  299. package/src/templates/app/app/[lang]/admin/page.d.ts +0 -9
  300. package/src/templates/app/app/csr.d.ts +0 -9
  301. package/src/templates/app/app/layout.d.ts +0 -9
  302. package/src/templates/app/lib/setting/Setting.Template.d.ts +0 -9
  303. package/src/templates/app/lib/setting/Setting.Unit.d.ts +0 -9
  304. package/src/templates/app/lib/setting/Setting.Util.d.ts +0 -9
  305. package/src/templates/app/lib/setting/Setting.View.d.ts +0 -9
  306. package/src/templates/app/lib/setting/Setting.Zone.d.ts +0 -9
  307. package/src/templates/app/lib/setting/index.d.ts +0 -9
  308. package/src/templates/app/lib/summary/Summary.Template.d.ts +0 -9
  309. package/src/templates/app/lib/summary/Summary.Unit.d.ts +0 -9
  310. package/src/templates/app/lib/summary/Summary.Util.d.ts +0 -9
  311. package/src/templates/app/lib/summary/Summary.View.d.ts +0 -9
  312. package/src/templates/app/lib/summary/Summary.Zone.d.ts +0 -9
  313. package/src/templates/app/lib/summary/index.d.ts +0 -9
  314. package/src/templates/app/lib/user/User.Template.d.ts +0 -9
  315. package/src/templates/app/lib/user/User.Unit.d.ts +0 -9
  316. package/src/templates/app/lib/user/User.Util.d.ts +0 -9
  317. package/src/templates/app/lib/user/User.View.d.ts +0 -9
  318. package/src/templates/app/lib/user/User.Zone.d.ts +0 -9
  319. package/src/templates/app/lib/user/index.d.ts +0 -9
  320. package/src/templates/app/ui/Footer.d.ts +0 -9
  321. package/src/templates/app/ui/MainHeader.d.ts +0 -10
  322. package/src/templates/crudPages/[__model__Id]/edit/page.d.ts +0 -11
  323. package/src/templates/crudPages/[__model__Id]/page.d.ts +0 -11
  324. package/src/templates/crudPages/new/page.d.ts +0 -11
  325. package/src/templates/crudPages/page.d.ts +0 -11
  326. package/src/templates/libRoot/lib/setting/Setting.Template.d.ts +0 -9
  327. package/src/templates/libRoot/lib/setting/Setting.Unit.d.ts +0 -9
  328. package/src/templates/libRoot/lib/setting/Setting.Util.d.ts +0 -9
  329. package/src/templates/libRoot/lib/setting/Setting.View.d.ts +0 -9
  330. package/src/templates/libRoot/lib/setting/Setting.Zone.d.ts +0 -9
  331. package/src/templates/libRoot/lib/setting/index.d.ts +0 -9
  332. package/src/templates/libRoot/lib/summary/Summary.Template.d.ts +0 -9
  333. package/src/templates/libRoot/lib/summary/Summary.Unit.d.ts +0 -9
  334. package/src/templates/libRoot/lib/summary/Summary.Util.d.ts +0 -9
  335. package/src/templates/libRoot/lib/summary/Summary.View.d.ts +0 -9
  336. package/src/templates/libRoot/lib/summary/Summary.Zone.d.ts +0 -9
  337. package/src/templates/libRoot/lib/summary/index.d.ts +0 -9
  338. package/src/templates/libRoot/lib/user/User.Template.d.ts +0 -9
  339. package/src/templates/libRoot/lib/user/User.Unit.d.ts +0 -9
  340. package/src/templates/libRoot/lib/user/User.Util.d.ts +0 -9
  341. package/src/templates/libRoot/lib/user/User.View.d.ts +0 -9
  342. package/src/templates/libRoot/lib/user/User.Zone.d.ts +0 -9
  343. package/src/templates/libRoot/lib/user/index.d.ts +0 -9
  344. package/src/templates/module/__Model__.Template.d.ts +0 -11
  345. package/src/templates/module/__Model__.Unit.d.ts +0 -11
  346. package/src/templates/module/__Model__.Util.d.ts +0 -11
  347. package/src/templates/module/__Model__.View.d.ts +0 -11
  348. package/src/templates/module/__Model__.Zone.d.ts +0 -11
  349. package/src/templates/module/index.d.ts +0 -11
@@ -0,0 +1,683 @@
1
+ # Akan.js Model Document Implementation Guide
2
+
3
+ ## Purpose and Role of model.document.ts Files
4
+
5
+ `model.document.ts` files are essential components in the Akan.js framework that define MongoDB data models and their associated behaviors. These files serve as the bridge between your application's data structure and MongoDB, providing:
6
+
7
+ 1. **Schema Definition** - Define the structure and validation for MongoDB documents
8
+ 2. **Business Logic** - Implement domain-specific operations through document methods
9
+ 3. **Query Patterns** - Create reusable database queries with model statics
10
+ 4. **Lifecycle Hooks** - Add middleware for handling events during document operations
11
+ 5. **Performance Optimization** - Configure indexes and implement DataLoader for efficient querying
12
+ 6. **Caching Integration** - Seamlessly integrate with Redis for high-performance data access
13
+ 7. **Search Capabilities** - Connect with Meilisearch for full-text search functionality
14
+
15
+ ## File Structure
16
+
17
+ A `model.document.ts` file is structured into four distinct classes, each with a specific responsibility:
18
+
19
+ ### 1. Input Class
20
+
21
+ Defines the data structure for create/update operations:
22
+
23
+ ```typescript
24
+ @Database.Input(() => cnst.ExampleInput)
25
+ export class ExampleInput extends by(cnst.ExampleInput) {}
26
+ ```
27
+
28
+ ### 2. Document Class
29
+
30
+ Represents a MongoDB document with instance methods:
31
+
32
+ ```typescript
33
+ @Database.Document(() => cnst.Example)
34
+ export class Example extends by(cnst.Example) {
35
+ // Document methods here
36
+ }
37
+ ```
38
+
39
+ ### 3. Model Class
40
+
41
+ Represents the MongoDB collection with static methods:
42
+
43
+ ```typescript
44
+ @Database.Model(() => cnst.Example)
45
+ export class ExampleModel extends into(Example, cnst.exampleCnst) {
46
+ // Model statics here
47
+ }
48
+ ```
49
+
50
+ ### 4. Middleware Class
51
+
52
+ Defines schema hooks and indexes:
53
+
54
+ ```typescript
55
+ @Database.Middleware(() => cnst.Example)
56
+ export class ExampleMiddleware extends beyond(ExampleModel, Example) {
57
+ onSchema(schema) {
58
+ // Middleware and indexes here
59
+ }
60
+ }
61
+ ```
62
+
63
+ ## How to Use Document Methods
64
+
65
+ Document methods operate on individual document instances and typically follow these patterns:
66
+
67
+ ### Characteristics of Document Methods:
68
+
69
+ - They operate on the current document instance (`this`)
70
+ - They typically return `this` to enable method chaining
71
+ - They're often synchronous, but can be asynchronous when needed
72
+ - They handle document-level operations and transformations
73
+
74
+ ### Example of Document Methods:
75
+
76
+ ```typescript
77
+ @Database.Document(() => cnst.User)
78
+ export class User extends by(cnst.User) {
79
+ // Simple transformation method (synchronous)
80
+ addRole(role: string) {
81
+ if (!this.roles.includes(role)) {
82
+ this.roles = [...this.roles, role];
83
+ }
84
+ return this;
85
+ }
86
+
87
+ // Remove item method (synchronous)
88
+ removeRole(role: string) {
89
+ this.roles = this.roles.filter((r) => r !== role);
90
+ return this;
91
+ }
92
+
93
+ // Complex operation with save (asynchronous)
94
+ async updateProfile(data: Partial<UserProfile>) {
95
+ Object.assign(this.profile, data);
96
+ this.lastUpdatedAt = new Date();
97
+ return await this.save();
98
+ }
99
+ }
100
+ ```
101
+
102
+ ## How to Use Model Statics
103
+
104
+ Model statics operate on the entire collection and are typically asynchronous. They implement reusable query patterns and business operations.
105
+
106
+ ### Characteristics of Model Statics:
107
+
108
+ - They operate on the entire collection, not a single document
109
+ - They're almost always asynchronous, returning Promises
110
+ - They often use built-in Mongoose methods like `find`, `findOne`, etc.
111
+ - They can implement complex business logic involving multiple documents
112
+
113
+ ### Example of Model Statics:
114
+
115
+ ```typescript
116
+ @Database.Model(() => cnst.Order)
117
+ export class OrderModel extends into(Order, cnst.orderCnst) {
118
+ // Query by specific criteria
119
+ async findPendingOrders(userId: string) {
120
+ return this.Order.find({
121
+ user: userId,
122
+ status: "pending",
123
+ }).sort({ createdAt: -1 });
124
+ }
125
+
126
+ // Complex operation with multiple steps
127
+ async processRefund(orderId: string, amount: number) {
128
+ const order = await this.Order.pickById(orderId);
129
+
130
+ if (order.status !== "completed") {
131
+ throw new Error("Cannot refund an incomplete order");
132
+ }
133
+
134
+ if (order.totalAmount < amount) {
135
+ throw new Error("Refund amount exceeds order total");
136
+ }
137
+
138
+ return await order
139
+ .set({
140
+ refundAmount: amount,
141
+ status: "refunded",
142
+ })
143
+ .save();
144
+ }
145
+
146
+ // Aggregation example
147
+ async getOrderStatsByUser(userId: string) {
148
+ const result = await this.Order.aggregate([
149
+ { $match: { user: userId } },
150
+ {
151
+ $group: {
152
+ _id: "$status",
153
+ count: { $sum: 1 },
154
+ totalAmount: { $sum: "$totalAmount" },
155
+ },
156
+ },
157
+ ]);
158
+
159
+ return result.reduce((acc, item) => {
160
+ acc[item._id] = {
161
+ count: item.count,
162
+ totalAmount: item.totalAmount,
163
+ };
164
+ return acc;
165
+ }, {});
166
+ }
167
+ }
168
+ ```
169
+
170
+ ## Built-in Model Functions
171
+
172
+ Akan.js provides several built-in methods that are available on all models:
173
+
174
+ ```typescript
175
+ // Direct access to Mongoose model
176
+ await userModel.User.find({...});
177
+
178
+ // Common operations
179
+ const user = await userModel.getUser(userId); // Get by ID or throw error
180
+ const maybeUser = await userModel.loadUser(userId); // Get by ID or return null
181
+ const users = await userModel.loadUserMany([userId1, userId2]); // Get multiple by IDs
182
+
183
+ // CRUD operations
184
+ const newUser = await userModel.createUser(userData); // Create new document
185
+ const updated = await userModel.updateUser(userId, userData); // Update document
186
+ const removed = await userModel.removeUser(userId); // Soft delete (sets removedAt)
187
+
188
+ // Search operations (when Meilisearch is configured)
189
+ const { docs, count } = await userModel.searchUser("john"); // Full-text search
190
+ const users = await userModel.searchDocsUser("john"); // Just get documents
191
+ const total = await userModel.searchCountUser("john"); // Just get count
192
+ ```
193
+
194
+ ## How to Apply Middleware
195
+
196
+ Middleware allows you to intercept and modify document operations at various lifecycle stages.
197
+
198
+ ### Common Middleware Hooks:
199
+
200
+ - `pre('save')` - Before saving a document
201
+ - `post('save')` - After saving a document
202
+ - `pre('remove')` - Before removing a document
203
+ - `pre('validate')` - Before validation
204
+ - `pre('findOneAndUpdate')` - Before findOneAndUpdate operations
205
+
206
+ ### Example Middleware Implementation:
207
+
208
+ ```typescript
209
+ @Database.Middleware(() => cnst.User)
210
+ export class UserMiddleware extends beyond(UserModel, User) {
211
+ onSchema(schema: SchemaOf<UserModel, User>) {
212
+ // Pre-save hook for password hashing
213
+ schema.pre<User>("save", async function (next) {
214
+ // Only hash the password if it's modified
215
+ if (this.isModified("password") && this.password) {
216
+ try {
217
+ this.password = await hashPassword(this.password);
218
+ next();
219
+ } catch (error) {
220
+ next(error);
221
+ }
222
+ } else {
223
+ next();
224
+ }
225
+ });
226
+
227
+ // Post-save hook for logging
228
+ schema.post<User>("save", function (doc) {
229
+ console.log(`User ${doc.id} was saved`);
230
+ });
231
+
232
+ // Pre-remove hook for cleanup
233
+ schema.pre<User>("remove", async function (next) {
234
+ try {
235
+ // Perform cleanup operations
236
+ await someCleanupFunction(this.id);
237
+ next();
238
+ } catch (error) {
239
+ next(error);
240
+ }
241
+ });
242
+ }
243
+ }
244
+ ```
245
+
246
+ ## How to Apply Indexes
247
+
248
+ Indexes are crucial for query performance. Define them in the Middleware's `onSchema` method:
249
+
250
+ ### Types of Indexes:
251
+
252
+ - **Single field index** - Optimize queries on a single field
253
+ - **Compound index** - Optimize queries that filter or sort on multiple fields
254
+ - **Text index** - Enable full-text search on specified fields
255
+ - **Unique index** - Ensure field values are unique across the collection
256
+ - **Sparse index** - Only include documents that have the indexed field
257
+
258
+ ### Example Index Implementation:
259
+
260
+ ```typescript
261
+ @Database.Middleware(() => cnst.Product)
262
+ export class ProductMiddleware extends beyond(ProductModel, Product) {
263
+ onSchema(schema: SchemaOf<ProductModel, Product>) {
264
+ // Single field index (1=ascending, -1=descending)
265
+ schema.index({ createdAt: -1 });
266
+
267
+ // Compound index
268
+ schema.index({ category: 1, price: -1 });
269
+
270
+ // Unique index
271
+ schema.index({ sku: 1 }, { unique: true });
272
+
273
+ // Text search index
274
+ schema.index({ name: "text", description: "text" });
275
+
276
+ // Sparse index (only indexes docs with the field)
277
+ schema.index(
278
+ { promotionCode: 1 },
279
+ {
280
+ sparse: true,
281
+ }
282
+ );
283
+
284
+ // Partial index with filter expression
285
+ schema.index(
286
+ { status: 1 },
287
+ {
288
+ partialFilterExpression: { status: { $exists: true } },
289
+ }
290
+ );
291
+
292
+ // Time-to-live index (auto-expire documents)
293
+ schema.index(
294
+ { expiresAt: 1 },
295
+ {
296
+ expireAfterSeconds: 0,
297
+ }
298
+ );
299
+ }
300
+ }
301
+ ```
302
+
303
+ ## How to Use MongoDB Model
304
+
305
+ The Akan.js framework provides direct access to the Mongoose model, allowing you to perform standard MongoDB operations:
306
+
307
+ ```typescript
308
+ // Find operations
309
+ const product = await productModel.Product.findById(id);
310
+ const activeProducts = await productModel.Product.find({ status: "active" });
311
+
312
+ // Update operations
313
+ await productModel.Product.updateMany({ category: "electronics" }, { $set: { onSale: true } });
314
+
315
+ // Aggregation
316
+ const stats = await productModel.Product.aggregate([
317
+ { $match: { status: "active" } },
318
+ {
319
+ $group: {
320
+ _id: "$category",
321
+ count: { $sum: 1 },
322
+ avgPrice: { $avg: "$price" },
323
+ },
324
+ },
325
+ ]);
326
+
327
+ // Advanced querying
328
+ const products = await productModel.Product.find({
329
+ price: { $gte: 100, $lte: 500 },
330
+ category: { $in: ["electronics", "gadgets"] },
331
+ })
332
+ .sort({ rating: -1 })
333
+ .limit(10);
334
+ ```
335
+
336
+ ## How to Use DataLoader
337
+
338
+ DataLoader batches and caches database requests to optimize performance, especially for resolving relationships between documents.
339
+
340
+ ### Types of Loaders:
341
+
342
+ - `@Loader.ByField(fieldName)` - Load documents by a specific field value
343
+ - `@Loader.ByArrayField(fieldName)` - Load documents that contain a value in an array field
344
+ - `@Loader.ByQuery(queryKeys)` - Load documents by complex query criteria
345
+
346
+ ### Example DataLoader Implementation:
347
+
348
+ ```typescript
349
+ @Database.Model(() => cnst.Order)
350
+ export class OrderModel extends into(Order, cnst.orderCnst) {
351
+ // Load orders by user ID
352
+ @Loader.ByField("userId")
353
+ userOrdersLoader: Loader<string, Order[]>;
354
+
355
+ // Load orders by status
356
+ @Loader.ByField("status")
357
+ statusOrdersLoader: Loader<string, Order[]>;
358
+
359
+ // Load orders by tag (array field)
360
+ @Loader.ByArrayField("tags")
361
+ tagOrdersLoader: Loader<string, Order[]>;
362
+
363
+ // Load order by complex query
364
+ @Loader.ByQuery(["userId", "orderNumber"])
365
+ specificOrderLoader: Loader<{ userId: string; orderNumber: string }, Order>;
366
+ }
367
+
368
+ // Usage:
369
+ const userOrders = await orderModel.userOrdersLoader.load(userId);
370
+ const pendingOrders = await orderModel.statusOrdersLoader.load("pending");
371
+ const taggedOrders = await orderModel.tagOrdersLoader.load("priority");
372
+ const specificOrder = await orderModel.specificOrderLoader.load({
373
+ userId: "user123",
374
+ orderNumber: "ORD-12345",
375
+ });
376
+ ```
377
+
378
+ ## How to Use Cache with Redis
379
+
380
+ Akan.js integrates Redis caching through the model's cache instance, providing simple methods for storing and retrieving data:
381
+
382
+ ```typescript
383
+ // Set cache
384
+ await userModel.UserCache.set(
385
+ "session", // Topic/category
386
+ userId, // Key
387
+ sessionData, // Value
388
+ { expireAt: dayjs().add(1, "hour") } // Options
389
+ );
390
+
391
+ // Get cache
392
+ const session = await userModel.UserCache.get("session", userId);
393
+
394
+ // Delete cache
395
+ await userModel.UserCache.delete("session", userId);
396
+
397
+ // Example: Caching expensive computation
398
+ async function getUserStats(userId: string) {
399
+ // Try to get from cache first
400
+ const cachedStats = await userModel.UserCache.get("stats", userId);
401
+ if (cachedStats) return JSON.parse(cachedStats);
402
+
403
+ // If not in cache, compute and store
404
+ const stats = await computeExpensiveUserStats(userId);
405
+ await userModel.UserCache.set("stats", userId, JSON.stringify(stats), { expireAt: dayjs().add(30, "minute") });
406
+
407
+ return stats;
408
+ }
409
+ ```
410
+
411
+ ## How to Use Search with Meilisearch
412
+
413
+ Akan.js provides Meilisearch integration for full-text search capabilities:
414
+
415
+ ```typescript
416
+ // Basic search with pagination
417
+ const { docs, count } = await productModel.searchProduct("wireless headphones", {
418
+ skip: 0,
419
+ limit: 10,
420
+ });
421
+
422
+ // Search with filtering
423
+ const { docs, count } = await productModel.searchProduct("wireless headphones", {
424
+ filter: "category=electronics AND price<=100",
425
+ });
426
+
427
+ // Search with sorting
428
+ const { docs, count } = await productModel.searchProduct("wireless headphones", {
429
+ sort: ["rating:desc", "price:asc"],
430
+ });
431
+
432
+ // Just get the documents
433
+ const products = await productModel.searchDocsProduct("wireless headphones");
434
+
435
+ // Just get the count
436
+ const resultCount = await productModel.searchCountProduct("wireless headphones");
437
+ ```
438
+
439
+ ## Best Practices
440
+
441
+ ### 1. Document Methods vs. Model Statics
442
+
443
+ - Use **document methods** for operations on a single document
444
+ - Use **model statics** for operations on multiple documents or complex business logic
445
+
446
+ ### 2. Efficient Querying
447
+
448
+ - Add indexes for frequently used queries
449
+ - Use projection (`select`) to limit fields returned
450
+ - Use `lean()` when you don't need full Mongoose documents
451
+ - Implement DataLoader for relationship fields
452
+
453
+ ### 3. Error Handling
454
+
455
+ - Use `pickOne` and `pickById` when you expect a document to exist
456
+ - Implement custom error classes for domain-specific errors
457
+ - Validate inputs before database operations
458
+
459
+ ### 4. Transactions
460
+
461
+ Use transactions for operations that need to be atomic:
462
+
463
+ ```typescript
464
+ @Database.Model(() => cnst.Order)
465
+ export class OrderModel extends into(Order, cnst.orderCnst) {
466
+ @Transaction()
467
+ async createOrderWithItems(orderData, items) {
468
+ const order = await this.createOrder(orderData);
469
+ await Promise.all(items.map((item) => itemModel.createItem({ ...item, orderId: order.id })));
470
+ return order;
471
+ }
472
+ }
473
+ ```
474
+
475
+ ### 5. Soft Deletes
476
+
477
+ Akan.js implements soft deletes by default:
478
+
479
+ ```typescript
480
+ // Soft delete (sets removedAt field)
481
+ await userModel.removeUser(userId);
482
+
483
+ // To query only non-deleted documents
484
+ const users = await userModel.User.find({ removedAt: { $exists: false } });
485
+
486
+ // To permanently delete (rarely needed)
487
+ await userModel.User.findByIdAndDelete(userId);
488
+ ```
489
+
490
+ ## Complete Example
491
+
492
+ Here's a complete example integrating multiple features:
493
+
494
+ ```typescript
495
+ // product.document.ts
496
+ import { dayjs } from "@akanjs/base";
497
+ import { beyond, by, Database, into, Loader, SchemaOf } from "@akanjs/document";
498
+ import { cnst } from "../cnst";
499
+
500
+ @Database.Input(() => cnst.ProductInput)
501
+ export class ProductInput extends by(cnst.ProductInput) {}
502
+
503
+ @Database.Document(() => cnst.Product)
504
+ export class Product extends by(cnst.Product) {
505
+ applyDiscount(percentage: number) {
506
+ if (percentage < 0 || percentage > 100) {
507
+ throw new Error("Discount percentage must be between 0 and 100");
508
+ }
509
+
510
+ const discount = (this.price * percentage) / 100;
511
+ this.discountedPrice = this.price - discount;
512
+ this.discountPercentage = percentage;
513
+
514
+ return this;
515
+ }
516
+
517
+ isInStock() {
518
+ return this.stockCount > 0;
519
+ }
520
+
521
+ decreaseStock(quantity = 1) {
522
+ if (this.stockCount < quantity) {
523
+ throw new Error("Not enough stock");
524
+ }
525
+
526
+ this.stockCount -= quantity;
527
+
528
+ return this;
529
+ }
530
+ }
531
+
532
+ @Database.Model(() => cnst.Product)
533
+ export class ProductModel extends into(Product, cnst.productCnst) {
534
+ @Loader.ByField("category")
535
+ categoryProductsLoader: Loader<string, Product[]>;
536
+
537
+ @Loader.ByArrayField("tags")
538
+ tagProductsLoader: Loader<string, Product[]>;
539
+
540
+ async findPopularProducts(limit = 10) {
541
+ return this.Product.find({
542
+ status: "active",
543
+ popularity: { $gte: 4 },
544
+ })
545
+ .sort({ popularity: -1 })
546
+ .limit(limit);
547
+ }
548
+
549
+ async updatePrices(categoryId: string, increasePercentage: number) {
550
+ const products = await this.Product.find({ category: categoryId });
551
+
552
+ const updates = products.map((product) => {
553
+ const newPrice = product.price * (1 + increasePercentage / 100);
554
+ return product.set({ price: newPrice }).save();
555
+ });
556
+
557
+ return Promise.all(updates);
558
+ }
559
+
560
+ async getCategoryStats() {
561
+ const result = await this.Product.aggregate([
562
+ { $match: { status: "active" } },
563
+ {
564
+ $group: {
565
+ _id: "$category",
566
+ count: { $sum: 1 },
567
+ avgPrice: { $avg: "$price" },
568
+ minPrice: { $min: "$price" },
569
+ maxPrice: { $max: "$price" },
570
+ },
571
+ },
572
+ { $sort: { count: -1 } },
573
+ ]);
574
+
575
+ // Cache the results
576
+ await this.ProductCache.set("stats", "categories", JSON.stringify(result), { expireAt: dayjs().add(1, "hour") });
577
+
578
+ return result;
579
+ }
580
+ }
581
+
582
+ @Database.Middleware(() => cnst.Product)
583
+ export class ProductMiddleware extends beyond(ProductModel, Product) {
584
+ onSchema(schema: SchemaOf<ProductModel, Product>) {
585
+ // Update stock status on save
586
+ schema.pre<Product>("save", function (next) {
587
+ if (this.isModified("stockCount")) {
588
+ this.stockStatus = this.stockCount > 0 ? "in_stock" : "out_of_stock";
589
+ }
590
+ next();
591
+ });
592
+
593
+ // Create slug from name
594
+ schema.pre<Product>("save", function (next) {
595
+ if (this.isNew || this.isModified("name")) {
596
+ this.slug = this.name
597
+ .toLowerCase()
598
+ .replace(/[^a-z0-9]+/g, "-")
599
+ .replace(/^-|-$/g, "");
600
+ }
601
+ next();
602
+ });
603
+
604
+ // Indexes
605
+ schema.index({ category: 1, status: 1 });
606
+ schema.index({ name: "text", description: "text" });
607
+ schema.index({ slug: 1 }, { unique: true });
608
+ schema.index({ createdAt: -1 });
609
+ schema.index({ price: 1 });
610
+ schema.index({ "meta.specifications.key": 1, "meta.specifications.value": 1 });
611
+ }
612
+ }
613
+ ```
614
+
615
+ ## Integration with NestJS
616
+
617
+ When using Akan.js with NestJS, models are injected using the service provider system:
618
+
619
+ ```typescript
620
+ // product.service.ts
621
+ import { Injectable } from "@nestjs/common";
622
+ import { getModel } from "@akanjs/nest";
623
+ import { ProductModel } from "./product.document";
624
+
625
+ @Injectable()
626
+ export class ProductService {
627
+ private productModel = getModel(ProductModel);
628
+
629
+ async getProductById(id: string) {
630
+ return this.productModel.getProduct(id);
631
+ }
632
+
633
+ async searchProducts(query: string, options = {}) {
634
+ return this.productModel.searchProduct(query, options);
635
+ }
636
+
637
+ async createProduct(data) {
638
+ return this.productModel.createProduct(data);
639
+ }
640
+
641
+ async applyDiscount(productId: string, percentage: number) {
642
+ const product = await this.productModel.getProduct(productId);
643
+ return product.applyDiscount(percentage).save();
644
+ }
645
+ }
646
+ ```
647
+
648
+ ## Client-Side Usage
649
+
650
+ On the client side, you'll typically interact with models through GraphQL or REST APIs:
651
+
652
+ ```typescript
653
+ // Using model-generated GraphQL operations
654
+ const { data } = await client.query({
655
+ query: gql`
656
+ query GetProduct($id: ID!) {
657
+ getProduct(id: $id) {
658
+ id
659
+ name
660
+ price
661
+ description
662
+ category
663
+ status
664
+ stockCount
665
+ }
666
+ }
667
+ `,
668
+ variables: { id: productId },
669
+ });
670
+ ```
671
+
672
+ ## Summary
673
+
674
+ The `model.document.ts` files in Akan.js provide a comprehensive system for defining and working with MongoDB data. By properly implementing these files, you can:
675
+
676
+ 1. Define clear data structures with validation
677
+ 2. Implement business logic at both document and collection levels
678
+ 3. Optimize database performance with indexes and DataLoader
679
+ 4. Leverage caching for high-performance operations
680
+ 5. Implement full-text search capabilities
681
+ 6. Create a maintainable and scalable data layer
682
+
683
+ Following the patterns and best practices outlined in this guide will help you build robust and efficient data-driven applications with Akan.js.