@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,833 @@
1
+ # Model.Unit.tsx Files in Akan.js - Implementation Guide
2
+
3
+ ## Purpose and Role of Model.Unit.tsx Files
4
+
5
+ Model.Unit.tsx files are foundational server components in the Akan.js framework that provide reusable presentation elements for domain models. They serve several critical purposes:
6
+
7
+ 1. **Consistent Model Representation**: Create standardized visual representations of domain entities
8
+ 2. **UI Building Blocks**: Serve as atomic components for building complex interfaces
9
+ 3. **Presentation Layer**: Encapsulate rendering logic for `cnst.LightModel` data objects
10
+ 4. **Cross-Component Reuse**: Enable consistent usage across pages, zones, templates, and utilities
11
+ 5. **Server-Side Rendering**: Optimize for Next.js server components architecture
12
+
13
+ Key characteristics:
14
+
15
+ - **Server Components**: Do not use client-side hooks (useState, useEffect, etc.)
16
+ - **Model-Focused**: Primarily render `cnst.LightModel` data structures
17
+ - **Presentation-Only**: Contain no business logic, state management, or data fetching
18
+ - **Prop-Configurable**: Accept standardized props for customization
19
+ - **Composable**: Designed to work seamlessly with other Akan.js components
20
+
21
+ ## How to Create Model.Unit.tsx Files
22
+
23
+ ### 1. File Location and Naming
24
+
25
+ Model Unit files follow strict naming conventions:
26
+
27
+ ```
28
+ libs/
29
+ your-lib/
30
+ lib/
31
+ feature-name/
32
+ FeatureName.Unit.tsx # PascalCase for file name
33
+ ```
34
+
35
+ ### 2. Basic Structure and Exports
36
+
37
+ A typical Model.Unit.tsx file exports multiple component variations:
38
+
39
+ ```tsx
40
+ import { clsx } from "clsx";
41
+ import { cnst } from "@your-lib/client";
42
+ import { Image, Link } from "@util/ui";
43
+
44
+ // Compact representation (minimal details)
45
+ export const Abstract = ({
46
+ product,
47
+ className,
48
+ href,
49
+ }: {
50
+ product: cnst.LightProduct;
51
+ className?: string;
52
+ href?: string;
53
+ }) => {
54
+ const Content = (
55
+ <div className={clsx("flex items-center gap-3 rounded border p-2", className)}>
56
+ {product.thumbnail && <Image file={product.thumbnail} className="h-12 w-12 rounded" alt={product.name} />}
57
+ <div>
58
+ <h3 className="font-medium">{product.name}</h3>
59
+ <p className="text-sm text-gray-500">{product.price.toLocaleString()} KRW</p>
60
+ </div>
61
+ </div>
62
+ );
63
+
64
+ return href ? <Link href={href}>{Content}</Link> : Content;
65
+ };
66
+
67
+ // Medium detail representation (card style)
68
+ export const Card = ({ product, className }: { product: cnst.LightProduct; className?: string }) => (
69
+ <div className={clsx("card bg-base-100 shadow-sm", className)}>
70
+ {product.image && (
71
+ <figure>
72
+ <Image file={product.image} className="h-48 w-full object-cover" alt={product.name} />
73
+ </figure>
74
+ )}
75
+ <div className="card-body p-4">
76
+ <h2 className="card-title text-lg">{product.name}</h2>
77
+ <p className="line-clamp-2 text-sm">{product.description}</p>
78
+ <div className="mt-2 flex items-center justify-between">
79
+ <span className="font-bold">{product.price.toLocaleString()} KRW</span>
80
+ <span className={clsx("badge", product.inStock ? "badge-success" : "badge-error")}>
81
+ {product.inStock ? "In Stock" : "Out of Stock"}
82
+ </span>
83
+ </div>
84
+ </div>
85
+ </div>
86
+ );
87
+
88
+ // Full detailed representation
89
+ export const Full = ({ product, className }: { product: cnst.LightProduct; className?: string }) => (
90
+ <div className={clsx("overflow-hidden rounded-lg border", className)}>
91
+ {product.image && <Image file={product.image} className="h-64 w-full object-cover" alt={product.name} />}
92
+ <div className="p-4">
93
+ <div className="mb-2 flex justify-between">
94
+ <h2 className="text-xl font-bold">{product.name}</h2>
95
+ <span className="text-lg font-bold">{product.price.toLocaleString()} KRW</span>
96
+ </div>
97
+ <p className="my-3">{product.description}</p>
98
+ <div className="grid grid-cols-2 gap-2 text-sm">
99
+ <div>
100
+ Category: <span className="font-medium">{product.category}</span>
101
+ </div>
102
+ <div>
103
+ SKU: <span className="font-medium">{product.sku}</span>
104
+ </div>
105
+ <div>
106
+ Manufacturer: <span className="font-medium">{product.manufacturer}</span>
107
+ </div>
108
+ <div>
109
+ Stock: <span className="font-medium">{product.stockQuantity}</span>
110
+ </div>
111
+ </div>
112
+ {product.tags?.length > 0 && (
113
+ <div className="mt-3 flex flex-wrap gap-1">
114
+ {product.tags.map((tag) => (
115
+ <span key={tag} className="badge badge-outline">
116
+ {tag}
117
+ </span>
118
+ ))}
119
+ </div>
120
+ )}
121
+ </div>
122
+ </div>
123
+ );
124
+
125
+ // Additional specialized variations as needed
126
+ export const Row = ({ product, className }: { product: cnst.LightProduct; className?: string }) => (
127
+ <div className={clsx("flex items-center justify-between border-b p-3", className)}>
128
+ <div className="flex items-center gap-3">
129
+ {product.thumbnail && <Image file={product.thumbnail} className="h-10 w-10 rounded" alt={product.name} />}
130
+ <div>
131
+ <h3 className="font-medium">{product.name}</h3>
132
+ <div className="text-xs text-gray-500">SKU: {product.sku}</div>
133
+ </div>
134
+ </div>
135
+ <div className="text-right">
136
+ <div className="font-bold">{product.price.toLocaleString()} KRW</div>
137
+ <div className={clsx("text-xs", product.inStock ? "text-green-600" : "text-red-600")}>
138
+ {product.inStock ? `${product.stockQuantity} in stock` : "Out of stock"}
139
+ </div>
140
+ </div>
141
+ </div>
142
+ );
143
+ ```
144
+
145
+ ### 3. Integration with LightModel Types
146
+
147
+ Model Units work with LightModel types defined in constant files:
148
+
149
+ ```tsx
150
+ // In your constant.ts file
151
+ @Model.Light("LightProduct")
152
+ export class LightProduct extends via(ProductObject, ["name", "price", "sku", "inStock"] as const) {
153
+ get displayPrice() {
154
+ return `${this.price.toLocaleString()} KRW`;
155
+ }
156
+ }
157
+
158
+ // In your Unit.tsx file
159
+ import { cnst } from "@your-lib/client";
160
+
161
+ export const Abstract = ({ product }: { product: cnst.LightProduct }) => (
162
+ <div>
163
+ <h3>{product.name}</h3>
164
+ <p>{product.displayPrice}</p>
165
+ </div>
166
+ );
167
+ ```
168
+
169
+ ### 4. Implementation Guidelines
170
+
171
+ 1. **Server Component Requirements**:
172
+
173
+ - No client-side hooks (`useState`, `useEffect`, `useRouter`, etc.)
174
+ - No browser-only APIs (`localStorage`, `window`, etc.)
175
+ - No `"use client"` directive in the file
176
+
177
+ 2. **Props Design**:
178
+
179
+ - Primary prop should be the model object (e.g., `product`, `user`, `story`)
180
+ - Always include `className` prop for styling customization
181
+ - Include `href` prop when the component might be used for navigation
182
+ - Keep prop interface consistent across export variations
183
+
184
+ 3. **Component Variations**:
185
+
186
+ - `Abstract`: Compact representation with minimal information
187
+ - `Card`: Medium-detail representation in a card format
188
+ - `Full`: Complete representation with all relevant details
189
+ - Additional variations as needed (List, Row, Grid, etc.)
190
+
191
+ 4. **Accessibility**:
192
+ - Use semantic HTML elements (`<article>`, `<section>`, `<h2>`, etc.)
193
+ - Include appropriate ARIA attributes
194
+ - Ensure proper image alt text
195
+ - Maintain keyboard navigability
196
+
197
+ ## How to Use Model.Unit.tsx Files
198
+
199
+ ### In Pages
200
+
201
+ ```tsx
202
+ // apps/your-app/app/products/page.tsx
203
+ import { Product } from "@shared/client";
204
+ import { getProducts } from "@shared/lib/product/product.service";
205
+
206
+ export default async function ProductsPage() {
207
+ const products = await getProducts();
208
+
209
+ return (
210
+ <div className="container mx-auto">
211
+ <h1 className="mb-6 text-2xl font-bold">Products</h1>
212
+ <div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
213
+ {products.map((product) => (
214
+ <Product.Unit.Card key={product.id} product={product} href={`/products/${product.id}`} />
215
+ ))}
216
+ </div>
217
+ </div>
218
+ );
219
+ }
220
+ ```
221
+
222
+ ### In Utils
223
+
224
+ ```tsx
225
+ // libs/shared/lib/product/Product.Util.tsx
226
+ "use client";
227
+ import { useState } from "react";
228
+ import { Product } from "@shared/client";
229
+ import { cnst } from "@shared/client";
230
+
231
+ export const ProductSelector = ({
232
+ products,
233
+ onSelect,
234
+ }: {
235
+ products: cnst.LightProduct[];
236
+ onSelect: (product: cnst.LightProduct) => void;
237
+ }) => {
238
+ const [selectedId, setSelectedId] = useState<string | null>(null);
239
+
240
+ const handleSelect = (product: cnst.LightProduct) => {
241
+ setSelectedId(product.id);
242
+ onSelect(product);
243
+ };
244
+
245
+ return (
246
+ <div className="space-y-2">
247
+ {products.map((product) => (
248
+ <button key={product.id} onClick={() => handleSelect(product)} className="w-full text-left">
249
+ <Product.Unit.Abstract product={product} className={selectedId === product.id ? "border-primary" : ""} />
250
+ </button>
251
+ ))}
252
+ </div>
253
+ );
254
+ };
255
+ ```
256
+
257
+ ### In Templates
258
+
259
+ ```tsx
260
+ // libs/shared/lib/product/Product.Template.tsx
261
+ "use client";
262
+ import { useState } from "react";
263
+ import { Product } from "@shared/client";
264
+ import { cnst } from "@shared/client";
265
+ import { sig } from "@shared/client";
266
+
267
+ export const ProductList = ({ initialProducts }: { initialProducts: cnst.LightProduct[] }) => {
268
+ const [products, setProducts] = useState(initialProducts);
269
+ const [loading, setLoading] = useState(false);
270
+
271
+ const loadMore = async () => {
272
+ if (loading) return;
273
+ setLoading(true);
274
+ try {
275
+ const nextPage = await sig.product.getProducts({
276
+ skip: products.length,
277
+ limit: 10,
278
+ });
279
+ setProducts([...products, ...nextPage.products]);
280
+ } catch (error) {
281
+ console.error("Failed to load more products", error);
282
+ } finally {
283
+ setLoading(false);
284
+ }
285
+ };
286
+
287
+ return (
288
+ <div>
289
+ <div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
290
+ {products.map((product) => (
291
+ <Product.Unit.Card key={product.id} product={product} />
292
+ ))}
293
+ </div>
294
+
295
+ {products.length >= 10 && (
296
+ <button className="btn btn-outline mx-auto mt-6 block" onClick={loadMore} disabled={loading}>
297
+ {loading ? "Loading..." : "Load More"}
298
+ </button>
299
+ )}
300
+ </div>
301
+ );
302
+ };
303
+ ```
304
+
305
+ ### In Zones
306
+
307
+ ```tsx
308
+ // libs/shared/lib/product/Product.Zone.tsx
309
+ "use client";
310
+ import { useState, useEffect } from "react";
311
+ import { cnst } from "@shared/client";
312
+ import { sig } from "@shared/client";
313
+ import { Product } from "@shared/client";
314
+ import { Zone, Tabs } from "@util/ui";
315
+
316
+ export const ProductManager = () => {
317
+ const [products, setProducts] = useState<cnst.LightProduct[]>([]);
318
+ const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
319
+
320
+ useEffect(() => {
321
+ const loadProducts = async () => {
322
+ const data = await sig.product.getProducts({
323
+ filter: selectedCategory ? { byCategory: selectedCategory } : undefined,
324
+ });
325
+ setProducts(data.products);
326
+ };
327
+
328
+ loadProducts();
329
+ }, [selectedCategory]);
330
+
331
+ return (
332
+ <Zone title="Product Management">
333
+ <Zone.Section title="Categories">
334
+ <Tabs
335
+ tabs={[
336
+ { key: null, label: "All" },
337
+ { key: "electronics", label: "Electronics" },
338
+ { key: "clothing", label: "Clothing" },
339
+ { key: "food", label: "Food" },
340
+ ]}
341
+ activeTab={selectedCategory}
342
+ onChange={(tab) => setSelectedCategory(tab)}
343
+ />
344
+ </Zone.Section>
345
+
346
+ <Zone.Section title="Products">
347
+ <div className="space-y-2">
348
+ {products.map((product) => (
349
+ <Product.Unit.Row key={product.id} product={product} />
350
+ ))}
351
+ </div>
352
+ </Zone.Section>
353
+ </Zone>
354
+ );
355
+ };
356
+ ```
357
+
358
+ ## Best Practices
359
+
360
+ ### 1. Component Variations and Consistent Exports
361
+
362
+ Define multiple components for different presentation contexts:
363
+
364
+ ```tsx
365
+ // User.Unit.tsx - Consistent naming pattern
366
+ export const Abstract = ({ user }) => {}; // Minimal view
367
+ export const Card = ({ user }) => {}; // Card view
368
+ export const Full = ({ user }) => {}; // Complete view
369
+ export const Row = ({ user }) => {}; // Table row view
370
+ export const Avatar = ({ user }) => {}; // Avatar-only view
371
+ ```
372
+
373
+ ### 2. Prop Handling and Styling
374
+
375
+ ```tsx
376
+ // Best practice: Accept and forward className
377
+ export const Abstract = ({
378
+ user,
379
+ className,
380
+ ...props
381
+ }: {
382
+ user: cnst.LightUser;
383
+ className?: string;
384
+ [key: string]: any;
385
+ }) => (
386
+ <div className={clsx("user-abstract rounded border p-3", className)} {...props}>
387
+ {/* content */}
388
+ </div>
389
+ );
390
+
391
+ // Best practice: Conditional rendering based on available data
392
+ export const Card = ({ user, className }: { user: cnst.LightUser; className?: string }) => (
393
+ <div className={clsx("card", className)}>
394
+ <div className="card-body">
395
+ <h3 className="card-title">{user.name}</h3>
396
+ {user.title && <p className="text-sm text-gray-600">{user.title}</p>}
397
+ {user.bio && <p className="mt-2">{user.bio}</p>}
398
+ {user.tags?.length > 0 && (
399
+ <div className="mt-2 flex gap-1">
400
+ {user.tags.map((tag) => (
401
+ <span key={tag} className="badge">
402
+ {tag}
403
+ </span>
404
+ ))}
405
+ </div>
406
+ )}
407
+ </div>
408
+ </div>
409
+ );
410
+ ```
411
+
412
+ ### 3. Image Handling
413
+
414
+ Always use the optimized `Image` component from `@util/ui` with proper attributes:
415
+
416
+ ```tsx
417
+ import { Image } from "@util/ui";
418
+
419
+ export const Card = ({ product }: { product: cnst.LightProduct }) => (
420
+ <div className="card">
421
+ {product.image ? (
422
+ <Image
423
+ file={product.image}
424
+ alt={product.name}
425
+ className="h-40 w-full object-cover"
426
+ sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
427
+ />
428
+ ) : (
429
+ <div className="flex h-40 w-full items-center justify-center bg-gray-200">
430
+ <span className="text-gray-400">No image</span>
431
+ </div>
432
+ )}
433
+ {/* Other content */}
434
+ </div>
435
+ );
436
+ ```
437
+
438
+ ### 4. Conditional Rendering and Link Handling
439
+
440
+ ```tsx
441
+ export const Abstract = ({ post, href, className }: { post: cnst.LightPost; href?: string; className?: string }) => {
442
+ const Content = (
443
+ <div className={clsx("post-abstract p-3", className)}>
444
+ <h3 className="font-bold">{post.title}</h3>
445
+ <p className="line-clamp-2 text-sm text-gray-600">{post.summary}</p>
446
+ </div>
447
+ );
448
+
449
+ // Conditionally wrap with Link if href is provided
450
+ return href ? (
451
+ <Link href={href} className="block transition hover:bg-gray-50">
452
+ {Content}
453
+ </Link>
454
+ ) : (
455
+ Content
456
+ );
457
+ };
458
+ ```
459
+
460
+ ### 5. Responsive Design
461
+
462
+ ```tsx
463
+ export const Card = ({ event }: { event: cnst.LightEvent }) => (
464
+ <div className="card">
465
+ <div className="card-body">
466
+ <h3 className="text-lg font-bold md:text-xl">{event.title}</h3>
467
+ <div className="flex flex-col sm:flex-row sm:justify-between">
468
+ <div className="text-sm">{formatDate(event.startDate)}</div>
469
+ <div className="mt-1 text-sm sm:mt-0">{event.location}</div>
470
+ </div>
471
+ <p className="mt-2 line-clamp-3 text-sm md:text-base">{event.description}</p>
472
+ </div>
473
+ </div>
474
+ );
475
+ ```
476
+
477
+ ## Common Component Patterns and Variations
478
+
479
+ ### 1. Hierarchical Components
480
+
481
+ ```tsx
482
+ // Department.Unit.tsx
483
+ export const Tree = ({ department }: { department: cnst.LightDepartment }) => (
484
+ <div className="rounded border p-3">
485
+ <h3 className="font-bold">{department.name}</h3>
486
+ {department.children?.length > 0 && (
487
+ <div className="mt-2 border-l pl-4">
488
+ {department.children.map((child) => (
489
+ <Tree key={child.id} department={child} />
490
+ ))}
491
+ </div>
492
+ )}
493
+ </div>
494
+ );
495
+ ```
496
+
497
+ ### 2. Status-Based Styling
498
+
499
+ ```tsx
500
+ // Order.Unit.tsx
501
+ export const Card = ({ order }: { order: cnst.LightOrder }) => (
502
+ <div className="rounded border p-4">
503
+ <div className="flex justify-between">
504
+ <h3 className="font-bold">#{order.orderNumber}</h3>
505
+ <span
506
+ className={clsx(
507
+ "badge",
508
+ order.status === "completed" && "badge-success",
509
+ order.status === "processing" && "badge-info",
510
+ order.status === "cancelled" && "badge-error",
511
+ order.status === "pending" && "badge-warning"
512
+ )}
513
+ >
514
+ {order.status}
515
+ </span>
516
+ </div>
517
+ <div className="mt-2">
518
+ <div>Customer: {order.customerName}</div>
519
+ <div>Items: {order.itemCount}</div>
520
+ <div>Total: {order.totalAmount.toLocaleString()} KRW</div>
521
+ </div>
522
+ </div>
523
+ );
524
+ ```
525
+
526
+ ### 3. Detail and Summary Pattern
527
+
528
+ ```tsx
529
+ // FAQ.Unit.tsx
530
+ export const Item = ({ faq }: { faq: cnst.LightFAQ }) => (
531
+ <details className="mb-2 overflow-hidden rounded border">
532
+ <summary className="cursor-pointer bg-gray-50 p-3 font-medium hover:bg-gray-100">{faq.question}</summary>
533
+ <div className="mt-2 p-3 pt-0">{faq.answer}</div>
534
+ </details>
535
+ );
536
+ ```
537
+
538
+ ### 4. Grid and List Variations
539
+
540
+ ```tsx
541
+ // Product.Unit.tsx
542
+ // For grid layouts
543
+ export const Grid = ({ product }: { product: cnst.LightProduct }) => (
544
+ <div className="overflow-hidden rounded border">
545
+ {product.image && <Image file={product.image} className="h-40 w-full object-cover" alt={product.name} />}
546
+ <div className="p-3">
547
+ <h3 className="truncate font-bold">{product.name}</h3>
548
+ <p className="mt-1 font-bold">{product.price.toLocaleString()} KRW</p>
549
+ </div>
550
+ </div>
551
+ );
552
+
553
+ // For list layouts
554
+ export const List = ({ product }: { product: cnst.LightProduct }) => (
555
+ <div className="flex border-b py-3">
556
+ {product.thumbnail && <Image file={product.thumbnail} className="h-16 w-16 object-cover" alt={product.name} />}
557
+ <div className="ml-3 flex-grow">
558
+ <h3 className="font-medium">{product.name}</h3>
559
+ <p className="line-clamp-1 text-sm text-gray-600">{product.description}</p>
560
+ </div>
561
+ <div className="ml-3 text-right">
562
+ <p className="font-bold">{product.price.toLocaleString()} KRW</p>
563
+ <p className="text-xs text-gray-500">SKU: {product.sku}</p>
564
+ </div>
565
+ </div>
566
+ );
567
+ ```
568
+
569
+ ## Performance Optimization
570
+
571
+ ### 1. Efficient Rendering with Memoization
572
+
573
+ When using Model.Unit components in lists, consider memoizing them in client components:
574
+
575
+ ```tsx
576
+ // In a client component file
577
+ "use client";
578
+ import { memo } from "react";
579
+ import { Product } from "@shared/client";
580
+
581
+ // Create memoized versions to prevent unnecessary re-renders
582
+ const ProductCard = memo(Product.Unit.Card);
583
+ const ProductRow = memo(Product.Unit.Row);
584
+
585
+ export const ProductList = ({ products, view = "grid" }) => {
586
+ return (
587
+ <div className={view === "grid" ? "grid grid-cols-3 gap-4" : "space-y-2"}>
588
+ {products.map((product) =>
589
+ view === "grid" ? (
590
+ <ProductCard key={product.id} product={product} />
591
+ ) : (
592
+ <ProductRow key={product.id} product={product} />
593
+ )
594
+ )}
595
+ </div>
596
+ );
597
+ };
598
+ ```
599
+
600
+ ### 2. Virtualization for Long Lists
601
+
602
+ ```tsx
603
+ "use client";
604
+ import { useVirtualizer } from "@tanstack/react-virtual";
605
+ import { useRef } from "react";
606
+ import { Product } from "@shared/client";
607
+
608
+ export const VirtualProductList = ({ products }) => {
609
+ const parentRef = useRef(null);
610
+
611
+ const virtualizer = useVirtualizer({
612
+ count: products.length,
613
+ getScrollElement: () => parentRef.current,
614
+ estimateSize: () => 80, // Approximate height of each row
615
+ });
616
+
617
+ return (
618
+ <div ref={parentRef} className="h-[600px] overflow-auto">
619
+ <div className="relative w-full" style={{ height: `${virtualizer.getTotalSize()}px` }}>
620
+ {virtualizer.getVirtualItems().map((virtualItem) => (
621
+ <div
622
+ key={virtualItem.key}
623
+ className="absolute top-0 left-0 w-full"
624
+ style={{
625
+ height: `${virtualItem.size}px`,
626
+ transform: `translateY(${virtualItem.start}px)`,
627
+ }}
628
+ >
629
+ <Product.Unit.Row product={products[virtualItem.index]} />
630
+ </div>
631
+ ))}
632
+ </div>
633
+ </div>
634
+ );
635
+ };
636
+ ```
637
+
638
+ ### 3. Image Optimization Techniques
639
+
640
+ ```tsx
641
+ import { Image } from "@util/ui";
642
+
643
+ export const Card = ({ product }: { product: cnst.LightProduct }) => (
644
+ <div className="card">
645
+ {product.image && (
646
+ <Image
647
+ file={product.image}
648
+ alt={product.name}
649
+ className="h-40 w-full object-cover"
650
+ priority={false}
651
+ loading="lazy"
652
+ sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
653
+ />
654
+ )}
655
+ {/* Other content */}
656
+ </div>
657
+ );
658
+ ```
659
+
660
+ ### 4. Conditional Loading of Complex Units
661
+
662
+ For complex units with heavy rendering needs:
663
+
664
+ ```tsx
665
+ export const Full = ({ product, detailed = false }: { product: cnst.LightProduct; detailed?: boolean }) => (
666
+ <div className="product-full rounded border p-4">
667
+ <h2 className="text-xl font-bold">{product.name}</h2>
668
+ <p className="mt-2">{product.price.toLocaleString()} KRW</p>
669
+
670
+ {/* Only render detailed content when needed */}
671
+ {detailed && (
672
+ <>
673
+ <div className="mt-4 grid grid-cols-2 gap-2">
674
+ <div>SKU: {product.sku}</div>
675
+ <div>Category: {product.category}</div>
676
+ <div>Stock: {product.stockQuantity}</div>
677
+ <div>Weight: {product.weight}kg</div>
678
+ </div>
679
+
680
+ <div className="mt-4">
681
+ <h3 className="font-bold">Specifications</h3>
682
+ <table className="mt-2 w-full border">
683
+ <tbody>
684
+ {product.specifications?.map((spec) => (
685
+ <tr key={spec.key} className="border-b">
686
+ <td className="p-2 font-medium">{spec.key}</td>
687
+ <td className="p-2">{spec.value}</td>
688
+ </tr>
689
+ ))}
690
+ </tbody>
691
+ </table>
692
+ </div>
693
+ </>
694
+ )}
695
+ </div>
696
+ );
697
+ ```
698
+
699
+ ## Troubleshooting Common Issues
700
+
701
+ ### 1. Server Component Errors
702
+
703
+ ```
704
+ Error: useState is not defined in Model.Unit.tsx
705
+ ```
706
+
707
+ **Solution**: Keep Model.Unit.tsx as server components without client-side hooks:
708
+
709
+ ```tsx
710
+ // ❌ INCORRECT: Don't use client hooks in Unit components
711
+ export const Card = ({ product }) => {
712
+ const [expanded, setExpanded] = useState(false); // Error: client hook in server component
713
+ return (/* ... */);
714
+ };
715
+
716
+ // ✅ CORRECT: Keep Unit components as pure presentation components
717
+ export const Card = ({ product, expanded = false }) => {
718
+ return (/* Render based on expanded prop */);
719
+ };
720
+
721
+ // If you need interactivity, handle it in a client component that wraps the Unit:
722
+ // In a client component file:
723
+ "use client";
724
+ import { useState } from "react";
725
+ import { Product } from "@shared/client";
726
+
727
+ export const ExpandableProductCard = ({ product }) => {
728
+ const [expanded, setExpanded] = useState(false);
729
+ return (
730
+ <div>
731
+ <Product.Unit.Card product={product} expanded={expanded} />
732
+ <button onClick={() => setExpanded(!expanded)}>
733
+ {expanded ? "Show Less" : "Show More"}
734
+ </button>
735
+ </div>
736
+ );
737
+ };
738
+ ```
739
+
740
+ ### 2. Image Handling Errors
741
+
742
+ ```
743
+ Error: Image component requires "alt" prop
744
+ ```
745
+
746
+ **Solution**: Always include alt text for images:
747
+
748
+ ```tsx
749
+ // ❌ INCORRECT
750
+ <Image file={product.image} className="w-full" />
751
+
752
+ // ✅ CORRECT
753
+ <Image
754
+ file={product.image}
755
+ alt={product.name || "Product image"}
756
+ className="w-full"
757
+ />
758
+ ```
759
+
760
+ ### 3. Conditional Rendering Issues
761
+
762
+ ```
763
+ Error: Cannot read properties of undefined (reading 'url')
764
+ ```
765
+
766
+ **Solution**: Always check for existence before accessing nested properties:
767
+
768
+ ```tsx
769
+ // ❌ INCORRECT
770
+ <Image file={user.avatar.url} alt={user.name} />;
771
+
772
+ // ✅ CORRECT
773
+ {
774
+ user.avatar?.url && <Image file={user.avatar} alt={user.name} />;
775
+ }
776
+
777
+ // Alternative approach with default/fallback
778
+ {
779
+ user.avatar?.url ? (
780
+ <Image file={user.avatar} alt={user.name} />
781
+ ) : (
782
+ <div className="avatar-placeholder">{user.name.charAt(0).toUpperCase()}</div>
783
+ );
784
+ }
785
+ ```
786
+
787
+ ### 4. Type Safety Issues
788
+
789
+ ```
790
+ Type error: Property 'description' does not exist on type 'LightProduct'
791
+ ```
792
+
793
+ **Solution**: Ensure you're only accessing properties defined in the LightModel:
794
+
795
+ ```tsx
796
+ // In constant.ts
797
+ @Model.Light("LightProduct")
798
+ export class LightProduct extends via(ProductObject, ["name", "price", "sku"] as const) {
799
+ // Only these fields are guaranteed to be available
800
+ }
801
+
802
+ // ❌ INCORRECT: Accessing properties not in the LightModel
803
+ export const Card = ({ product }: { product: cnst.LightProduct }) => (
804
+ <div>
805
+ <h3>{product.name}</h3>
806
+ <p>{product.description}</p> // Error: description is not in LightProduct
807
+ </div>
808
+ );
809
+
810
+ // ✅ CORRECT: Check for optional properties
811
+ export const Card = ({ product }: { product: cnst.LightProduct }) => (
812
+ <div>
813
+ <h3>{product.name}</h3>
814
+ {/* Use optional chaining for properties that might not exist */}
815
+ {product.description && <p>{product.description}</p>}
816
+ </div>
817
+ );
818
+ ```
819
+
820
+ ## Conclusion
821
+
822
+ Model.Unit.tsx files are essential building blocks in the Akan.js framework, providing consistent, reusable presentation components for your domain models. By following these guidelines, you'll create well-structured, performant, and maintainable UI components that work seamlessly across your application.
823
+
824
+ Key takeaways:
825
+
826
+ - Create multiple component variations (Abstract, Card, Full, etc.) for different use cases
827
+ - Keep components as server components without client-side hooks
828
+ - Focus on presentation only, leaving business logic to Service files
829
+ - Follow consistent prop patterns with className and href support
830
+ - Optimize for performance with proper image handling and conditional rendering
831
+ - Ensure type safety by respecting LightModel type definitions
832
+
833
+ Well-designed Model.Unit components improve development velocity, maintain UI consistency, and enable seamless component reuse throughout your Akan.js applications.