moai-adk 0.35.1__py3-none-any.whl

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.

Potentially problematic release.


This version of moai-adk might be problematic. Click here for more details.

Files changed (502) hide show
  1. moai_adk/__init__.py +10 -0
  2. moai_adk/__main__.py +199 -0
  3. moai_adk/cli/__init__.py +6 -0
  4. moai_adk/cli/commands/__init__.py +17 -0
  5. moai_adk/cli/commands/analyze.py +116 -0
  6. moai_adk/cli/commands/doctor.py +272 -0
  7. moai_adk/cli/commands/init.py +372 -0
  8. moai_adk/cli/commands/language.py +248 -0
  9. moai_adk/cli/commands/status.py +104 -0
  10. moai_adk/cli/commands/update.py +2686 -0
  11. moai_adk/cli/main.py +13 -0
  12. moai_adk/cli/prompts/__init__.py +5 -0
  13. moai_adk/cli/prompts/init_prompts.py +219 -0
  14. moai_adk/cli/spec_status.py +263 -0
  15. moai_adk/cli/ui/__init__.py +44 -0
  16. moai_adk/cli/ui/progress.py +422 -0
  17. moai_adk/cli/ui/prompts.py +389 -0
  18. moai_adk/cli/ui/theme.py +129 -0
  19. moai_adk/cli/worktree/__init__.py +27 -0
  20. moai_adk/cli/worktree/__main__.py +31 -0
  21. moai_adk/cli/worktree/cli.py +683 -0
  22. moai_adk/cli/worktree/exceptions.py +89 -0
  23. moai_adk/cli/worktree/manager.py +493 -0
  24. moai_adk/cli/worktree/models.py +65 -0
  25. moai_adk/cli/worktree/registry.py +422 -0
  26. moai_adk/core/PHASE2_OPTIMIZATIONS.md +467 -0
  27. moai_adk/core/__init__.py +1 -0
  28. moai_adk/core/analysis/__init__.py +9 -0
  29. moai_adk/core/analysis/session_analyzer.py +400 -0
  30. moai_adk/core/claude_integration.py +393 -0
  31. moai_adk/core/command_helpers.py +270 -0
  32. moai_adk/core/comprehensive_monitoring_system.py +1183 -0
  33. moai_adk/core/config/__init__.py +19 -0
  34. moai_adk/core/config/auto_spec_config.py +340 -0
  35. moai_adk/core/config/migration.py +244 -0
  36. moai_adk/core/config/unified.py +436 -0
  37. moai_adk/core/context_manager.py +273 -0
  38. moai_adk/core/diagnostics/__init__.py +19 -0
  39. moai_adk/core/diagnostics/slash_commands.py +159 -0
  40. moai_adk/core/enterprise_features.py +1404 -0
  41. moai_adk/core/error_recovery_system.py +1902 -0
  42. moai_adk/core/event_driven_hook_system.py +1371 -0
  43. moai_adk/core/git/__init__.py +31 -0
  44. moai_adk/core/git/branch.py +25 -0
  45. moai_adk/core/git/branch_manager.py +129 -0
  46. moai_adk/core/git/checkpoint.py +134 -0
  47. moai_adk/core/git/commit.py +67 -0
  48. moai_adk/core/git/conflict_detector.py +413 -0
  49. moai_adk/core/git/event_detector.py +79 -0
  50. moai_adk/core/git/manager.py +216 -0
  51. moai_adk/core/hooks/post_tool_auto_spec_completion.py +901 -0
  52. moai_adk/core/input_validation_middleware.py +1006 -0
  53. moai_adk/core/integration/__init__.py +22 -0
  54. moai_adk/core/integration/engine.py +157 -0
  55. moai_adk/core/integration/integration_tester.py +226 -0
  56. moai_adk/core/integration/models.py +88 -0
  57. moai_adk/core/integration/utils.py +211 -0
  58. moai_adk/core/issue_creator.py +305 -0
  59. moai_adk/core/jit_context_loader.py +956 -0
  60. moai_adk/core/jit_enhanced_hook_manager.py +1987 -0
  61. moai_adk/core/language_config.py +202 -0
  62. moai_adk/core/language_config_resolver.py +572 -0
  63. moai_adk/core/language_validator.py +543 -0
  64. moai_adk/core/mcp/setup.py +116 -0
  65. moai_adk/core/merge/__init__.py +9 -0
  66. moai_adk/core/merge/analyzer.py +605 -0
  67. moai_adk/core/migration/__init__.py +18 -0
  68. moai_adk/core/migration/alfred_to_moai_migrator.py +383 -0
  69. moai_adk/core/migration/backup_manager.py +277 -0
  70. moai_adk/core/migration/custom_element_scanner.py +358 -0
  71. moai_adk/core/migration/file_migrator.py +209 -0
  72. moai_adk/core/migration/interactive_checkbox_ui.py +488 -0
  73. moai_adk/core/migration/selective_restorer.py +470 -0
  74. moai_adk/core/migration/template_utils.py +74 -0
  75. moai_adk/core/migration/user_selection_ui.py +338 -0
  76. moai_adk/core/migration/version_detector.py +139 -0
  77. moai_adk/core/migration/version_migrator.py +228 -0
  78. moai_adk/core/performance/__init__.py +6 -0
  79. moai_adk/core/performance/cache_system.py +316 -0
  80. moai_adk/core/performance/parallel_processor.py +116 -0
  81. moai_adk/core/phase_optimized_hook_scheduler.py +879 -0
  82. moai_adk/core/project/__init__.py +1 -0
  83. moai_adk/core/project/backup_utils.py +70 -0
  84. moai_adk/core/project/checker.py +300 -0
  85. moai_adk/core/project/detector.py +293 -0
  86. moai_adk/core/project/initializer.py +387 -0
  87. moai_adk/core/project/phase_executor.py +716 -0
  88. moai_adk/core/project/validator.py +139 -0
  89. moai_adk/core/quality/__init__.py +6 -0
  90. moai_adk/core/quality/trust_checker.py +377 -0
  91. moai_adk/core/quality/validators/__init__.py +6 -0
  92. moai_adk/core/quality/validators/base_validator.py +19 -0
  93. moai_adk/core/realtime_monitoring_dashboard.py +1724 -0
  94. moai_adk/core/robust_json_parser.py +611 -0
  95. moai_adk/core/rollback_manager.py +918 -0
  96. moai_adk/core/session_manager.py +651 -0
  97. moai_adk/core/skill_loading_system.py +579 -0
  98. moai_adk/core/spec/confidence_scoring.py +680 -0
  99. moai_adk/core/spec/ears_template_engine.py +1247 -0
  100. moai_adk/core/spec/quality_validator.py +687 -0
  101. moai_adk/core/spec_status_manager.py +478 -0
  102. moai_adk/core/template/__init__.py +7 -0
  103. moai_adk/core/template/backup.py +174 -0
  104. moai_adk/core/template/config.py +191 -0
  105. moai_adk/core/template/languages.py +43 -0
  106. moai_adk/core/template/merger.py +233 -0
  107. moai_adk/core/template/processor.py +1200 -0
  108. moai_adk/core/template_engine.py +310 -0
  109. moai_adk/core/template_variable_synchronizer.py +417 -0
  110. moai_adk/core/unified_permission_manager.py +745 -0
  111. moai_adk/core/user_behavior_analytics.py +851 -0
  112. moai_adk/core/version_sync.py +429 -0
  113. moai_adk/foundation/__init__.py +56 -0
  114. moai_adk/foundation/backend.py +1027 -0
  115. moai_adk/foundation/database.py +1115 -0
  116. moai_adk/foundation/devops.py +1585 -0
  117. moai_adk/foundation/ears.py +431 -0
  118. moai_adk/foundation/frontend.py +870 -0
  119. moai_adk/foundation/git/commit_templates.py +557 -0
  120. moai_adk/foundation/git.py +376 -0
  121. moai_adk/foundation/langs.py +484 -0
  122. moai_adk/foundation/ml_ops.py +1162 -0
  123. moai_adk/foundation/testing.py +1524 -0
  124. moai_adk/foundation/trust/trust_principles.py +676 -0
  125. moai_adk/foundation/trust/validation_checklist.py +1573 -0
  126. moai_adk/project/__init__.py +0 -0
  127. moai_adk/project/configuration.py +1084 -0
  128. moai_adk/project/documentation.py +566 -0
  129. moai_adk/project/schema.py +447 -0
  130. moai_adk/statusline/__init__.py +38 -0
  131. moai_adk/statusline/alfred_detector.py +105 -0
  132. moai_adk/statusline/config.py +376 -0
  133. moai_adk/statusline/enhanced_output_style_detector.py +372 -0
  134. moai_adk/statusline/git_collector.py +190 -0
  135. moai_adk/statusline/main.py +322 -0
  136. moai_adk/statusline/metrics_tracker.py +78 -0
  137. moai_adk/statusline/renderer.py +343 -0
  138. moai_adk/statusline/update_checker.py +129 -0
  139. moai_adk/statusline/version_reader.py +741 -0
  140. moai_adk/templates/.claude/agents/moai/ai-nano-banana.md +714 -0
  141. moai_adk/templates/.claude/agents/moai/builder-agent.md +474 -0
  142. moai_adk/templates/.claude/agents/moai/builder-command.md +1172 -0
  143. moai_adk/templates/.claude/agents/moai/builder-plugin.md +637 -0
  144. moai_adk/templates/.claude/agents/moai/builder-skill.md +666 -0
  145. moai_adk/templates/.claude/agents/moai/expert-backend.md +899 -0
  146. moai_adk/templates/.claude/agents/moai/expert-database.md +777 -0
  147. moai_adk/templates/.claude/agents/moai/expert-debug.md +401 -0
  148. moai_adk/templates/.claude/agents/moai/expert-devops.md +720 -0
  149. moai_adk/templates/.claude/agents/moai/expert-frontend.md +734 -0
  150. moai_adk/templates/.claude/agents/moai/expert-performance.md +657 -0
  151. moai_adk/templates/.claude/agents/moai/expert-security.md +513 -0
  152. moai_adk/templates/.claude/agents/moai/expert-testing.md +733 -0
  153. moai_adk/templates/.claude/agents/moai/expert-uiux.md +1041 -0
  154. moai_adk/templates/.claude/agents/moai/manager-claude-code.md +432 -0
  155. moai_adk/templates/.claude/agents/moai/manager-docs.md +573 -0
  156. moai_adk/templates/.claude/agents/moai/manager-git.md +1060 -0
  157. moai_adk/templates/.claude/agents/moai/manager-project.md +891 -0
  158. moai_adk/templates/.claude/agents/moai/manager-quality.md +624 -0
  159. moai_adk/templates/.claude/agents/moai/manager-spec.md +809 -0
  160. moai_adk/templates/.claude/agents/moai/manager-strategy.md +780 -0
  161. moai_adk/templates/.claude/agents/moai/manager-tdd.md +784 -0
  162. moai_adk/templates/.claude/agents/moai/mcp-context7.md +458 -0
  163. moai_adk/templates/.claude/agents/moai/mcp-figma.md +1607 -0
  164. moai_adk/templates/.claude/agents/moai/mcp-notion.md +789 -0
  165. moai_adk/templates/.claude/agents/moai/mcp-playwright.md +469 -0
  166. moai_adk/templates/.claude/agents/moai/mcp-sequential-thinking.md +1032 -0
  167. moai_adk/templates/.claude/commands/moai/0-project.md +1386 -0
  168. moai_adk/templates/.claude/commands/moai/1-plan.md +1427 -0
  169. moai_adk/templates/.claude/commands/moai/2-run.md +943 -0
  170. moai_adk/templates/.claude/commands/moai/3-sync.md +1324 -0
  171. moai_adk/templates/.claude/commands/moai/9-feedback.md +314 -0
  172. moai_adk/templates/.claude/hooks/__init__.py +8 -0
  173. moai_adk/templates/.claude/hooks/moai/__init__.py +8 -0
  174. moai_adk/templates/.claude/hooks/moai/lib/__init__.py +85 -0
  175. moai_adk/templates/.claude/hooks/moai/lib/checkpoint.py +244 -0
  176. moai_adk/templates/.claude/hooks/moai/lib/common.py +131 -0
  177. moai_adk/templates/.claude/hooks/moai/lib/config_manager.py +446 -0
  178. moai_adk/templates/.claude/hooks/moai/lib/config_validator.py +639 -0
  179. moai_adk/templates/.claude/hooks/moai/lib/example_config.json +104 -0
  180. moai_adk/templates/.claude/hooks/moai/lib/git_operations_manager.py +590 -0
  181. moai_adk/templates/.claude/hooks/moai/lib/language_validator.py +317 -0
  182. moai_adk/templates/.claude/hooks/moai/lib/models.py +102 -0
  183. moai_adk/templates/.claude/hooks/moai/lib/path_utils.py +28 -0
  184. moai_adk/templates/.claude/hooks/moai/lib/project.py +768 -0
  185. moai_adk/templates/.claude/hooks/moai/lib/test_hooks_improvements.py +443 -0
  186. moai_adk/templates/.claude/hooks/moai/lib/timeout.py +160 -0
  187. moai_adk/templates/.claude/hooks/moai/lib/unified_timeout_manager.py +530 -0
  188. moai_adk/templates/.claude/hooks/moai/session_end__auto_cleanup.py +862 -0
  189. moai_adk/templates/.claude/hooks/moai/session_start__show_project_info.py +1083 -0
  190. moai_adk/templates/.claude/output-styles/moai/r2d2.md +560 -0
  191. moai_adk/templates/.claude/output-styles/moai/yoda.md +359 -0
  192. moai_adk/templates/.claude/settings.json +172 -0
  193. moai_adk/templates/.claude/skills/moai-ai-nano-banana/SKILL.md +307 -0
  194. moai_adk/templates/.claude/skills/moai-ai-nano-banana/examples.md +431 -0
  195. moai_adk/templates/.claude/skills/moai-ai-nano-banana/scripts/batch_generate.py +560 -0
  196. moai_adk/templates/.claude/skills/moai-ai-nano-banana/scripts/generate_image.py +362 -0
  197. moai_adk/templates/.claude/skills/moai-docs-generation/SKILL.md +249 -0
  198. moai_adk/templates/.claude/skills/moai-docs-generation/examples.md +406 -0
  199. moai_adk/templates/.claude/skills/moai-docs-generation/modules/README.md +44 -0
  200. moai_adk/templates/.claude/skills/moai-docs-generation/modules/api-documentation.md +130 -0
  201. moai_adk/templates/.claude/skills/moai-docs-generation/modules/code-documentation.md +152 -0
  202. moai_adk/templates/.claude/skills/moai-docs-generation/modules/multi-format-output.md +178 -0
  203. moai_adk/templates/.claude/skills/moai-docs-generation/modules/user-guides.md +147 -0
  204. moai_adk/templates/.claude/skills/moai-docs-generation/reference.md +328 -0
  205. moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +320 -0
  206. moai_adk/templates/.claude/skills/moai-domain-backend/examples.md +718 -0
  207. moai_adk/templates/.claude/skills/moai-domain-backend/reference.md +464 -0
  208. moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +323 -0
  209. moai_adk/templates/.claude/skills/moai-domain-database/examples.md +830 -0
  210. moai_adk/templates/.claude/skills/moai-domain-database/modules/README.md +53 -0
  211. moai_adk/templates/.claude/skills/moai-domain-database/modules/mongodb.md +231 -0
  212. moai_adk/templates/.claude/skills/moai-domain-database/modules/postgresql.md +169 -0
  213. moai_adk/templates/.claude/skills/moai-domain-database/modules/redis.md +262 -0
  214. moai_adk/templates/.claude/skills/moai-domain-database/reference.md +545 -0
  215. moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +497 -0
  216. moai_adk/templates/.claude/skills/moai-domain-frontend/examples.md +968 -0
  217. moai_adk/templates/.claude/skills/moai-domain-frontend/reference.md +664 -0
  218. moai_adk/templates/.claude/skills/moai-domain-uiux/SKILL.md +455 -0
  219. moai_adk/templates/.claude/skills/moai-domain-uiux/examples.md +560 -0
  220. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/accessibility-wcag.md +260 -0
  221. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/component-architecture.md +228 -0
  222. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/icon-libraries.md +401 -0
  223. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/theming-system.md +373 -0
  224. moai_adk/templates/.claude/skills/moai-domain-uiux/reference.md +243 -0
  225. moai_adk/templates/.claude/skills/moai-formats-data/SKILL.md +492 -0
  226. moai_adk/templates/.claude/skills/moai-formats-data/examples.md +804 -0
  227. moai_adk/templates/.claude/skills/moai-formats-data/modules/README.md +98 -0
  228. moai_adk/templates/.claude/skills/moai-formats-data/modules/SKILL-MODULARIZATION-TEMPLATE.md +278 -0
  229. moai_adk/templates/.claude/skills/moai-formats-data/modules/caching-performance.md +459 -0
  230. moai_adk/templates/.claude/skills/moai-formats-data/modules/data-validation.md +485 -0
  231. moai_adk/templates/.claude/skills/moai-formats-data/modules/json-optimization.md +374 -0
  232. moai_adk/templates/.claude/skills/moai-formats-data/modules/toon-encoding.md +308 -0
  233. moai_adk/templates/.claude/skills/moai-formats-data/reference.md +585 -0
  234. moai_adk/templates/.claude/skills/moai-foundation-claude/SKILL.md +202 -0
  235. moai_adk/templates/.claude/skills/moai-foundation-claude/examples.md +732 -0
  236. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/best-practices-checklist.md +616 -0
  237. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-custom-slash-commands-official.md +729 -0
  238. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-hooks-official.md +560 -0
  239. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-iam-official.md +635 -0
  240. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-memory-official.md +543 -0
  241. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-settings-official.md +663 -0
  242. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-skills-official.md +113 -0
  243. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sub-agents-official.md +238 -0
  244. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/complete-configuration-guide.md +175 -0
  245. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-examples.md +1674 -0
  246. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-formatting-guide.md +729 -0
  247. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-examples.md +1513 -0
  248. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-formatting-guide.md +1086 -0
  249. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-integration-patterns.md +1100 -0
  250. moai_adk/templates/.claude/skills/moai-foundation-claude/reference.md +209 -0
  251. moai_adk/templates/.claude/skills/moai-foundation-context/SKILL.md +441 -0
  252. moai_adk/templates/.claude/skills/moai-foundation-context/examples.md +1048 -0
  253. moai_adk/templates/.claude/skills/moai-foundation-context/reference.md +246 -0
  254. moai_adk/templates/.claude/skills/moai-foundation-core/SKILL.md +420 -0
  255. moai_adk/templates/.claude/skills/moai-foundation-core/examples.md +358 -0
  256. moai_adk/templates/.claude/skills/moai-foundation-core/modules/README.md +296 -0
  257. moai_adk/templates/.claude/skills/moai-foundation-core/modules/agents-reference.md +359 -0
  258. moai_adk/templates/.claude/skills/moai-foundation-core/modules/commands-reference.md +432 -0
  259. moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-patterns.md +757 -0
  260. moai_adk/templates/.claude/skills/moai-foundation-core/modules/execution-rules.md +687 -0
  261. moai_adk/templates/.claude/skills/moai-foundation-core/modules/modular-system.md +665 -0
  262. moai_adk/templates/.claude/skills/moai-foundation-core/modules/progressive-disclosure.md +649 -0
  263. moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-first-tdd.md +864 -0
  264. moai_adk/templates/.claude/skills/moai-foundation-core/modules/token-optimization.md +708 -0
  265. moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-framework.md +981 -0
  266. moai_adk/templates/.claude/skills/moai-foundation-core/reference.md +478 -0
  267. moai_adk/templates/.claude/skills/moai-foundation-philosopher/SKILL.md +315 -0
  268. moai_adk/templates/.claude/skills/moai-foundation-philosopher/examples.md +228 -0
  269. moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/assumption-matrix.md +80 -0
  270. moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/cognitive-bias.md +199 -0
  271. moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/first-principles.md +140 -0
  272. moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/trade-off-analysis.md +154 -0
  273. moai_adk/templates/.claude/skills/moai-foundation-philosopher/reference.md +157 -0
  274. moai_adk/templates/.claude/skills/moai-foundation-quality/SKILL.md +364 -0
  275. moai_adk/templates/.claude/skills/moai-foundation-quality/examples.md +1232 -0
  276. moai_adk/templates/.claude/skills/moai-foundation-quality/modules/best-practices.md +261 -0
  277. moai_adk/templates/.claude/skills/moai-foundation-quality/modules/integration-patterns.md +194 -0
  278. moai_adk/templates/.claude/skills/moai-foundation-quality/modules/proactive-analysis.md +229 -0
  279. moai_adk/templates/.claude/skills/moai-foundation-quality/modules/trust5-validation.md +169 -0
  280. moai_adk/templates/.claude/skills/moai-foundation-quality/reference.md +1266 -0
  281. moai_adk/templates/.claude/skills/moai-foundation-quality/scripts/quality-gate.sh +668 -0
  282. moai_adk/templates/.claude/skills/moai-foundation-quality/templates/github-actions-quality.yml +481 -0
  283. moai_adk/templates/.claude/skills/moai-foundation-quality/templates/quality-config.yaml +519 -0
  284. moai_adk/templates/.claude/skills/moai-lang-cpp/SKILL.md +649 -0
  285. moai_adk/templates/.claude/skills/moai-lang-csharp/SKILL.md +478 -0
  286. moai_adk/templates/.claude/skills/moai-lang-elixir/SKILL.md +612 -0
  287. moai_adk/templates/.claude/skills/moai-lang-flutter/SKILL.md +477 -0
  288. moai_adk/templates/.claude/skills/moai-lang-flutter/examples.md +1090 -0
  289. moai_adk/templates/.claude/skills/moai-lang-flutter/reference.md +686 -0
  290. moai_adk/templates/.claude/skills/moai-lang-go/SKILL.md +376 -0
  291. moai_adk/templates/.claude/skills/moai-lang-go/examples.md +919 -0
  292. moai_adk/templates/.claude/skills/moai-lang-go/reference.md +737 -0
  293. moai_adk/templates/.claude/skills/moai-lang-java/SKILL.md +385 -0
  294. moai_adk/templates/.claude/skills/moai-lang-java/examples.md +864 -0
  295. moai_adk/templates/.claude/skills/moai-lang-java/reference.md +291 -0
  296. moai_adk/templates/.claude/skills/moai-lang-kotlin/SKILL.md +382 -0
  297. moai_adk/templates/.claude/skills/moai-lang-kotlin/examples.md +1006 -0
  298. moai_adk/templates/.claude/skills/moai-lang-kotlin/reference.md +562 -0
  299. moai_adk/templates/.claude/skills/moai-lang-php/SKILL.md +644 -0
  300. moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +481 -0
  301. moai_adk/templates/.claude/skills/moai-lang-python/examples.md +977 -0
  302. moai_adk/templates/.claude/skills/moai-lang-python/reference.md +804 -0
  303. moai_adk/templates/.claude/skills/moai-lang-r/SKILL.md +579 -0
  304. moai_adk/templates/.claude/skills/moai-lang-ruby/SKILL.md +687 -0
  305. moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +372 -0
  306. moai_adk/templates/.claude/skills/moai-lang-rust/examples.md +659 -0
  307. moai_adk/templates/.claude/skills/moai-lang-rust/reference.md +504 -0
  308. moai_adk/templates/.claude/skills/moai-lang-scala/SKILL.md +497 -0
  309. moai_adk/templates/.claude/skills/moai-lang-scala/examples.md +633 -0
  310. moai_adk/templates/.claude/skills/moai-lang-scala/reference.md +423 -0
  311. moai_adk/templates/.claude/skills/moai-lang-swift/SKILL.md +497 -0
  312. moai_adk/templates/.claude/skills/moai-lang-swift/examples.md +918 -0
  313. moai_adk/templates/.claude/skills/moai-lang-swift/reference.md +672 -0
  314. moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +368 -0
  315. moai_adk/templates/.claude/skills/moai-lang-typescript/examples.md +1089 -0
  316. moai_adk/templates/.claude/skills/moai-lang-typescript/reference.md +731 -0
  317. moai_adk/templates/.claude/skills/moai-library-mermaid/SKILL.md +300 -0
  318. moai_adk/templates/.claude/skills/moai-library-mermaid/advanced-patterns.md +465 -0
  319. moai_adk/templates/.claude/skills/moai-library-mermaid/examples.md +270 -0
  320. moai_adk/templates/.claude/skills/moai-library-mermaid/optimization.md +440 -0
  321. moai_adk/templates/.claude/skills/moai-library-mermaid/reference.md +228 -0
  322. moai_adk/templates/.claude/skills/moai-library-nextra/SKILL.md +319 -0
  323. moai_adk/templates/.claude/skills/moai-library-nextra/advanced-patterns.md +336 -0
  324. moai_adk/templates/.claude/skills/moai-library-nextra/examples.md +592 -0
  325. moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-deployment-patterns.md +182 -0
  326. moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-patterns.md +17 -0
  327. moai_adk/templates/.claude/skills/moai-library-nextra/modules/configuration.md +57 -0
  328. moai_adk/templates/.claude/skills/moai-library-nextra/modules/content-architecture-optimization.md +162 -0
  329. moai_adk/templates/.claude/skills/moai-library-nextra/modules/deployment.md +52 -0
  330. moai_adk/templates/.claude/skills/moai-library-nextra/modules/framework-core-configuration.md +186 -0
  331. moai_adk/templates/.claude/skills/moai-library-nextra/modules/i18n-setup.md +55 -0
  332. moai_adk/templates/.claude/skills/moai-library-nextra/modules/mdx-components.md +52 -0
  333. moai_adk/templates/.claude/skills/moai-library-nextra/optimization.md +303 -0
  334. moai_adk/templates/.claude/skills/moai-library-nextra/reference.md +379 -0
  335. moai_adk/templates/.claude/skills/moai-library-shadcn/SKILL.md +372 -0
  336. moai_adk/templates/.claude/skills/moai-library-shadcn/examples.md +575 -0
  337. moai_adk/templates/.claude/skills/moai-library-shadcn/modules/advanced-patterns.md +394 -0
  338. moai_adk/templates/.claude/skills/moai-library-shadcn/modules/optimization.md +278 -0
  339. moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-components.md +457 -0
  340. moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-theming.md +373 -0
  341. moai_adk/templates/.claude/skills/moai-library-shadcn/reference.md +74 -0
  342. moai_adk/templates/.claude/skills/moai-mcp-figma/SKILL.md +402 -0
  343. moai_adk/templates/.claude/skills/moai-mcp-figma/advanced-patterns.md +607 -0
  344. moai_adk/templates/.claude/skills/moai-mcp-notion/SKILL.md +300 -0
  345. moai_adk/templates/.claude/skills/moai-mcp-notion/advanced-patterns.md +537 -0
  346. moai_adk/templates/.claude/skills/moai-platform-auth0/SKILL.md +291 -0
  347. moai_adk/templates/.claude/skills/moai-platform-clerk/SKILL.md +390 -0
  348. moai_adk/templates/.claude/skills/moai-platform-convex/SKILL.md +398 -0
  349. moai_adk/templates/.claude/skills/moai-platform-firebase-auth/SKILL.md +379 -0
  350. moai_adk/templates/.claude/skills/moai-platform-firestore/SKILL.md +358 -0
  351. moai_adk/templates/.claude/skills/moai-platform-neon/SKILL.md +467 -0
  352. moai_adk/templates/.claude/skills/moai-platform-railway/SKILL.md +377 -0
  353. moai_adk/templates/.claude/skills/moai-platform-supabase/SKILL.md +466 -0
  354. moai_adk/templates/.claude/skills/moai-platform-vercel/SKILL.md +482 -0
  355. moai_adk/templates/.claude/skills/moai-plugin-builder/SKILL.md +474 -0
  356. moai_adk/templates/.claude/skills/moai-plugin-builder/examples.md +621 -0
  357. moai_adk/templates/.claude/skills/moai-plugin-builder/migration.md +341 -0
  358. moai_adk/templates/.claude/skills/moai-plugin-builder/reference.md +463 -0
  359. moai_adk/templates/.claude/skills/moai-plugin-builder/validation.md +373 -0
  360. moai_adk/templates/.claude/skills/moai-security-auth0/SKILL.md +275 -0
  361. moai_adk/templates/.claude/skills/moai-security-auth0/modules/adaptive-mfa.md +233 -0
  362. moai_adk/templates/.claude/skills/moai-security-auth0/modules/akamai-integration.md +215 -0
  363. moai_adk/templates/.claude/skills/moai-security-auth0/modules/application-credentials.md +280 -0
  364. moai_adk/templates/.claude/skills/moai-security-auth0/modules/attack-protection-log-events.md +225 -0
  365. moai_adk/templates/.claude/skills/moai-security-auth0/modules/attack-protection-overview.md +140 -0
  366. moai_adk/templates/.claude/skills/moai-security-auth0/modules/bot-detection.md +144 -0
  367. moai_adk/templates/.claude/skills/moai-security-auth0/modules/breached-password-detection.md +187 -0
  368. moai_adk/templates/.claude/skills/moai-security-auth0/modules/brute-force-protection.md +189 -0
  369. moai_adk/templates/.claude/skills/moai-security-auth0/modules/certifications.md +282 -0
  370. moai_adk/templates/.claude/skills/moai-security-auth0/modules/compliance-overview.md +263 -0
  371. moai_adk/templates/.claude/skills/moai-security-auth0/modules/continuous-session-protection.md +307 -0
  372. moai_adk/templates/.claude/skills/moai-security-auth0/modules/customize-mfa.md +178 -0
  373. moai_adk/templates/.claude/skills/moai-security-auth0/modules/dpop-implementation.md +283 -0
  374. moai_adk/templates/.claude/skills/moai-security-auth0/modules/fapi-implementation.md +259 -0
  375. moai_adk/templates/.claude/skills/moai-security-auth0/modules/gdpr-compliance.md +313 -0
  376. moai_adk/templates/.claude/skills/moai-security-auth0/modules/guardian-configuration.md +269 -0
  377. moai_adk/templates/.claude/skills/moai-security-auth0/modules/highly-regulated-identity.md +272 -0
  378. moai_adk/templates/.claude/skills/moai-security-auth0/modules/jwt-fundamentals.md +248 -0
  379. moai_adk/templates/.claude/skills/moai-security-auth0/modules/mdl-verification.md +211 -0
  380. moai_adk/templates/.claude/skills/moai-security-auth0/modules/mfa-api-management.md +278 -0
  381. moai_adk/templates/.claude/skills/moai-security-auth0/modules/mfa-factors.md +226 -0
  382. moai_adk/templates/.claude/skills/moai-security-auth0/modules/mfa-overview.md +174 -0
  383. moai_adk/templates/.claude/skills/moai-security-auth0/modules/mtls-sender-constraining.md +316 -0
  384. moai_adk/templates/.claude/skills/moai-security-auth0/modules/ropg-flow-mfa.md +217 -0
  385. moai_adk/templates/.claude/skills/moai-security-auth0/modules/security-center.md +325 -0
  386. moai_adk/templates/.claude/skills/moai-security-auth0/modules/security-guidance.md +277 -0
  387. moai_adk/templates/.claude/skills/moai-security-auth0/modules/state-parameters.md +178 -0
  388. moai_adk/templates/.claude/skills/moai-security-auth0/modules/step-up-authentication.md +251 -0
  389. moai_adk/templates/.claude/skills/moai-security-auth0/modules/suspicious-ip-throttling.md +240 -0
  390. moai_adk/templates/.claude/skills/moai-security-auth0/modules/tenant-access-control.md +180 -0
  391. moai_adk/templates/.claude/skills/moai-security-auth0/modules/webauthn-fido.md +235 -0
  392. moai_adk/templates/.claude/skills/moai-workflow-jit-docs/SKILL.md +449 -0
  393. moai_adk/templates/.claude/skills/moai-workflow-jit-docs/advanced-patterns.md +379 -0
  394. moai_adk/templates/.claude/skills/moai-workflow-jit-docs/examples.md +544 -0
  395. moai_adk/templates/.claude/skills/moai-workflow-jit-docs/optimization.md +286 -0
  396. moai_adk/templates/.claude/skills/moai-workflow-jit-docs/reference.md +307 -0
  397. moai_adk/templates/.claude/skills/moai-workflow-project/README.md +190 -0
  398. moai_adk/templates/.claude/skills/moai-workflow-project/SKILL.md +390 -0
  399. moai_adk/templates/.claude/skills/moai-workflow-project/__init__.py +520 -0
  400. moai_adk/templates/.claude/skills/moai-workflow-project/complete_workflow_demo_fixed.py +574 -0
  401. moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_project_setup.py +317 -0
  402. moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_workflow_demo.py +663 -0
  403. moai_adk/templates/.claude/skills/moai-workflow-project/examples/config-migration-example.json +190 -0
  404. moai_adk/templates/.claude/skills/moai-workflow-project/examples/question-examples.json +175 -0
  405. moai_adk/templates/.claude/skills/moai-workflow-project/examples/quick_start.py +196 -0
  406. moai_adk/templates/.claude/skills/moai-workflow-project/examples.md +547 -0
  407. moai_adk/templates/.claude/skills/moai-workflow-project/modules/__init__.py +17 -0
  408. moai_adk/templates/.claude/skills/moai-workflow-project/modules/advanced-patterns.md +158 -0
  409. moai_adk/templates/.claude/skills/moai-workflow-project/modules/ask_user_integration.py +340 -0
  410. moai_adk/templates/.claude/skills/moai-workflow-project/modules/batch_questions.py +713 -0
  411. moai_adk/templates/.claude/skills/moai-workflow-project/modules/config_manager.py +538 -0
  412. moai_adk/templates/.claude/skills/moai-workflow-project/modules/documentation_manager.py +1336 -0
  413. moai_adk/templates/.claude/skills/moai-workflow-project/modules/language_initializer.py +730 -0
  414. moai_adk/templates/.claude/skills/moai-workflow-project/modules/migration_manager.py +608 -0
  415. moai_adk/templates/.claude/skills/moai-workflow-project/modules/template_optimizer.py +1005 -0
  416. moai_adk/templates/.claude/skills/moai-workflow-project/reference.md +275 -0
  417. moai_adk/templates/.claude/skills/moai-workflow-project/schemas/config-schema.json +316 -0
  418. moai_adk/templates/.claude/skills/moai-workflow-project/schemas/tab_schema.json +1434 -0
  419. moai_adk/templates/.claude/skills/moai-workflow-project/templates/config-template.json +71 -0
  420. moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/product-template.md +44 -0
  421. moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/structure-template.md +48 -0
  422. moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/tech-template.md +92 -0
  423. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/config-manager-setup.json +109 -0
  424. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/language-initializer.json +228 -0
  425. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/menu-project-config.json +130 -0
  426. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/project-batch-questions.json +97 -0
  427. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/spec-workflow-setup.json +150 -0
  428. moai_adk/templates/.claude/skills/moai-workflow-project/test_integration_simple.py +436 -0
  429. moai_adk/templates/.claude/skills/moai-workflow-spec/SKILL.md +534 -0
  430. moai_adk/templates/.claude/skills/moai-workflow-spec/examples.md +900 -0
  431. moai_adk/templates/.claude/skills/moai-workflow-spec/reference.md +704 -0
  432. moai_adk/templates/.claude/skills/moai-workflow-templates/SKILL.md +377 -0
  433. moai_adk/templates/.claude/skills/moai-workflow-templates/examples.md +552 -0
  434. moai_adk/templates/.claude/skills/moai-workflow-templates/modules/code-templates.md +124 -0
  435. moai_adk/templates/.claude/skills/moai-workflow-templates/modules/feedback-templates.md +100 -0
  436. moai_adk/templates/.claude/skills/moai-workflow-templates/modules/template-optimizer.md +138 -0
  437. moai_adk/templates/.claude/skills/moai-workflow-templates/reference.md +346 -0
  438. moai_adk/templates/.claude/skills/moai-workflow-testing/LICENSE.txt +202 -0
  439. moai_adk/templates/.claude/skills/moai-workflow-testing/SKILL.md +456 -0
  440. moai_adk/templates/.claude/skills/moai-workflow-testing/advanced-patterns.md +576 -0
  441. moai_adk/templates/.claude/skills/moai-workflow-testing/examples/ai-powered-testing.py +294 -0
  442. moai_adk/templates/.claude/skills/moai-workflow-testing/examples/console_logging.py +35 -0
  443. moai_adk/templates/.claude/skills/moai-workflow-testing/examples/element_discovery.py +40 -0
  444. moai_adk/templates/.claude/skills/moai-workflow-testing/examples/static_html_automation.py +34 -0
  445. moai_adk/templates/.claude/skills/moai-workflow-testing/examples.md +672 -0
  446. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/README.md +220 -0
  447. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/ai-debugging.md +845 -0
  448. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review.md +1416 -0
  449. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization.md +1234 -0
  450. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/smart-refactoring.md +1243 -0
  451. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7.md +1260 -0
  452. moai_adk/templates/.claude/skills/moai-workflow-testing/optimization.md +505 -0
  453. moai_adk/templates/.claude/skills/moai-workflow-testing/reference/playwright-best-practices.md +57 -0
  454. moai_adk/templates/.claude/skills/moai-workflow-testing/reference.md +440 -0
  455. moai_adk/templates/.claude/skills/moai-workflow-testing/scripts/with_server.py +218 -0
  456. moai_adk/templates/.claude/skills/moai-workflow-testing/templates/alfred-integration.md +376 -0
  457. moai_adk/templates/.claude/skills/moai-workflow-testing/workflows/enterprise-testing-workflow.py +571 -0
  458. moai_adk/templates/.claude/skills/moai-worktree/SKILL.md +411 -0
  459. moai_adk/templates/.claude/skills/moai-worktree/examples.md +606 -0
  460. moai_adk/templates/.claude/skills/moai-worktree/modules/integration-patterns.md +982 -0
  461. moai_adk/templates/.claude/skills/moai-worktree/modules/parallel-development.md +778 -0
  462. moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-commands.md +646 -0
  463. moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-management.md +782 -0
  464. moai_adk/templates/.claude/skills/moai-worktree/reference.md +357 -0
  465. moai_adk/templates/.git-hooks/pre-commit +128 -0
  466. moai_adk/templates/.git-hooks/pre-push +365 -0
  467. moai_adk/templates/.github/workflows/ci-universal.yml +513 -0
  468. moai_adk/templates/.github/workflows/security-secrets-check.yml +179 -0
  469. moai_adk/templates/.github/workflows/spec-issue-sync.yml +337 -0
  470. moai_adk/templates/.gitignore +222 -0
  471. moai_adk/templates/.mcp.json +13 -0
  472. moai_adk/templates/.moai/config/config.yaml +58 -0
  473. moai_adk/templates/.moai/config/questions/_schema.yaml +174 -0
  474. moai_adk/templates/.moai/config/questions/tab0-init.yaml +251 -0
  475. moai_adk/templates/.moai/config/questions/tab1-user.yaml +107 -0
  476. moai_adk/templates/.moai/config/questions/tab2-project.yaml +79 -0
  477. moai_adk/templates/.moai/config/questions/tab3-git.yaml +632 -0
  478. moai_adk/templates/.moai/config/questions/tab4-quality.yaml +182 -0
  479. moai_adk/templates/.moai/config/questions/tab5-system.yaml +96 -0
  480. moai_adk/templates/.moai/config/sections/git-strategy.yaml +116 -0
  481. moai_adk/templates/.moai/config/sections/language.yaml +11 -0
  482. moai_adk/templates/.moai/config/sections/project.yaml +13 -0
  483. moai_adk/templates/.moai/config/sections/quality.yaml +17 -0
  484. moai_adk/templates/.moai/config/sections/system.yaml +24 -0
  485. moai_adk/templates/.moai/config/sections/user.yaml +5 -0
  486. moai_adk/templates/.moai/config/statusline-config.yaml +92 -0
  487. moai_adk/templates/.moai/scripts/setup-glm.py +136 -0
  488. moai_adk/templates/CLAUDE.md +642 -0
  489. moai_adk/utils/__init__.py +30 -0
  490. moai_adk/utils/banner.py +38 -0
  491. moai_adk/utils/common.py +294 -0
  492. moai_adk/utils/link_validator.py +241 -0
  493. moai_adk/utils/logger.py +147 -0
  494. moai_adk/utils/safe_file_reader.py +206 -0
  495. moai_adk/utils/timeout.py +160 -0
  496. moai_adk/utils/toon_utils.py +256 -0
  497. moai_adk/version.py +22 -0
  498. moai_adk-0.35.1.dist-info/METADATA +3018 -0
  499. moai_adk-0.35.1.dist-info/RECORD +502 -0
  500. moai_adk-0.35.1.dist-info/WHEEL +4 -0
  501. moai_adk-0.35.1.dist-info/entry_points.txt +3 -0
  502. moai_adk-0.35.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,1006 @@
1
+ # Kotlin Production Examples
2
+
3
+ ## Complete REST API with Ktor
4
+
5
+ ### Application Setup
6
+
7
+ ```kotlin
8
+ // Application.kt
9
+ fun main() {
10
+ embeddedServer(Netty, port = 8080, host = "0.0.0.0") {
11
+ configureKoin()
12
+ configureSecurity()
13
+ configureRouting()
14
+ configureContentNegotiation()
15
+ configureStatusPages()
16
+ configureMonitoring()
17
+ }.start(wait = true)
18
+ }
19
+
20
+ fun Application.configureKoin() {
21
+ install(Koin) {
22
+ modules(appModule)
23
+ }
24
+ }
25
+
26
+ val appModule = module {
27
+ single<Database> { DatabaseFactory.create() }
28
+ single<UserRepository> { UserRepositoryImpl(get()) }
29
+ single<OrderRepository> { OrderRepositoryImpl(get()) }
30
+ single<UserService> { UserServiceImpl(get(), get()) }
31
+ single<JwtService> { JwtServiceImpl() }
32
+ }
33
+
34
+ fun Application.configureSecurity() {
35
+ install(Authentication) {
36
+ jwt("auth-jwt") {
37
+ realm = "User API"
38
+ verifier(JwtConfig.verifier)
39
+ validate { credential ->
40
+ if (credential.payload.audience.contains("api"))
41
+ JWTPrincipal(credential.payload)
42
+ else null
43
+ }
44
+ challenge { _, _ ->
45
+ call.respond(HttpStatusCode.Unauthorized, ErrorResponse("Token invalid or expired"))
46
+ }
47
+ }
48
+ }
49
+ }
50
+
51
+ fun Application.configureContentNegotiation() {
52
+ install(ContentNegotiation) {
53
+ json(Json {
54
+ prettyPrint = true
55
+ isLenient = true
56
+ ignoreUnknownKeys = true
57
+ encodeDefaults = true
58
+ })
59
+ }
60
+ }
61
+
62
+ fun Application.configureStatusPages() {
63
+ install(StatusPages) {
64
+ exception<ValidationException> { call, cause ->
65
+ call.respond(HttpStatusCode.BadRequest, ErrorResponse(cause.message ?: "Validation failed"))
66
+ }
67
+ exception<NotFoundException> { call, cause ->
68
+ call.respond(HttpStatusCode.NotFound, ErrorResponse(cause.message ?: "Resource not found"))
69
+ }
70
+ exception<DuplicateException> { call, cause ->
71
+ call.respond(HttpStatusCode.Conflict, ErrorResponse(cause.message ?: "Resource already exists"))
72
+ }
73
+ exception<AuthenticationException> { call, cause ->
74
+ call.respond(HttpStatusCode.Unauthorized, ErrorResponse(cause.message ?: "Authentication failed"))
75
+ }
76
+ exception<Throwable> { call, cause ->
77
+ call.application.log.error("Unhandled exception", cause)
78
+ call.respond(HttpStatusCode.InternalServerError, ErrorResponse("Internal server error"))
79
+ }
80
+ }
81
+ }
82
+
83
+ fun Application.configureMonitoring() {
84
+ install(CallLogging) {
85
+ level = Level.INFO
86
+ filter { call -> call.request.path().startsWith("/api") }
87
+ format { call ->
88
+ val status = call.response.status()
89
+ val method = call.request.httpMethod.value
90
+ val path = call.request.path()
91
+ val duration = call.processingTimeMillis()
92
+ "$method $path - $status (${duration}ms)"
93
+ }
94
+ }
95
+ }
96
+ ```
97
+
98
+ ### Complete User Routes
99
+
100
+ ```kotlin
101
+ // UserRoutes.kt
102
+ fun Application.configureRouting() {
103
+ val userService by inject<UserService>()
104
+ val jwtService by inject<JwtService>()
105
+
106
+ routing {
107
+ route("/api/v1") {
108
+ // Health check
109
+ get("/health") {
110
+ call.respond(mapOf("status" to "healthy", "timestamp" to Instant.now().toString()))
111
+ }
112
+
113
+ // Public authentication routes
114
+ route("/auth") {
115
+ post("/register") {
116
+ val request = call.receive<CreateUserRequest>()
117
+ request.validate()
118
+ val user = userService.create(request)
119
+ call.respond(HttpStatusCode.Created, user.toDto())
120
+ }
121
+
122
+ post("/login") {
123
+ val request = call.receive<LoginRequest>()
124
+ val user = userService.authenticate(request.email, request.password)
125
+ val token = jwtService.generateToken(user)
126
+ call.respond(TokenResponse(token, user.toDto()))
127
+ }
128
+
129
+ post("/refresh") {
130
+ val request = call.receive<RefreshRequest>()
131
+ val newToken = jwtService.refreshToken(request.token)
132
+ call.respond(TokenResponse(newToken, null))
133
+ }
134
+ }
135
+
136
+ // Protected user routes
137
+ authenticate("auth-jwt") {
138
+ route("/users") {
139
+ get {
140
+ val page = call.parameters["page"]?.toIntOrNull() ?: 0
141
+ val size = call.parameters["size"]?.toIntOrNull()?.coerceIn(1, 100) ?: 20
142
+ val search = call.parameters["search"]
143
+
144
+ val users = if (search != null) {
145
+ userService.search(search, page, size)
146
+ } else {
147
+ userService.findAll(page, size)
148
+ }
149
+ call.respond(users.map { it.toDto() })
150
+ }
151
+
152
+ get("/{id}") {
153
+ val id = call.parameters["id"]?.toLongOrNull()
154
+ ?: throw ValidationException("Invalid user ID")
155
+ val user = userService.findById(id)
156
+ ?: throw NotFoundException("User not found")
157
+ call.respond(user.toDto())
158
+ }
159
+
160
+ get("/me") {
161
+ val userId = call.principal<JWTPrincipal>()!!
162
+ .payload.getClaim("userId").asLong()
163
+ val user = userService.findById(userId)
164
+ ?: throw NotFoundException("User not found")
165
+ call.respond(user.toDto())
166
+ }
167
+
168
+ put("/{id}") {
169
+ val id = call.parameters["id"]?.toLongOrNull()
170
+ ?: throw ValidationException("Invalid user ID")
171
+ val request = call.receive<UpdateUserRequest>()
172
+ request.validate()
173
+ val user = userService.update(id, request)
174
+ ?: throw NotFoundException("User not found")
175
+ call.respond(user.toDto())
176
+ }
177
+
178
+ delete("/{id}") {
179
+ val id = call.parameters["id"]?.toLongOrNull()
180
+ ?: throw ValidationException("Invalid user ID")
181
+ if (userService.delete(id)) {
182
+ call.respond(HttpStatusCode.NoContent)
183
+ } else {
184
+ throw NotFoundException("User not found")
185
+ }
186
+ }
187
+
188
+ // User's orders
189
+ get("/{id}/orders") {
190
+ val id = call.parameters["id"]?.toLongOrNull()
191
+ ?: throw ValidationException("Invalid user ID")
192
+ val orders = userService.getUserOrders(id)
193
+ call.respond(orders.map { it.toDto() })
194
+ }
195
+ }
196
+ }
197
+ }
198
+ }
199
+ }
200
+ ```
201
+
202
+ ### Service Layer with Coroutines
203
+
204
+ ```kotlin
205
+ // UserService.kt
206
+ interface UserService {
207
+ suspend fun findAll(page: Int, size: Int): List<User>
208
+ suspend fun findById(id: Long): User?
209
+ suspend fun search(query: String, page: Int, size: Int): List<User>
210
+ suspend fun create(request: CreateUserRequest): User
211
+ suspend fun update(id: Long, request: UpdateUserRequest): User?
212
+ suspend fun delete(id: Long): Boolean
213
+ suspend fun authenticate(email: String, password: String): User
214
+ suspend fun getUserOrders(userId: Long): List<Order>
215
+ }
216
+
217
+ class UserServiceImpl(
218
+ private val userRepository: UserRepository,
219
+ private val orderRepository: OrderRepository
220
+ ) : UserService {
221
+
222
+ override suspend fun findAll(page: Int, size: Int): List<User> =
223
+ userRepository.findAll(page * size, size)
224
+
225
+ override suspend fun findById(id: Long): User? =
226
+ userRepository.findById(id)
227
+
228
+ override suspend fun search(query: String, page: Int, size: Int): List<User> =
229
+ userRepository.search(query, page * size, size)
230
+
231
+ override suspend fun create(request: CreateUserRequest): User {
232
+ if (userRepository.existsByEmail(request.email)) {
233
+ throw DuplicateException("Email already registered")
234
+ }
235
+
236
+ val user = User(
237
+ id = 0,
238
+ name = request.name,
239
+ email = request.email,
240
+ passwordHash = BCrypt.hashpw(request.password, BCrypt.gensalt()),
241
+ status = UserStatus.PENDING,
242
+ createdAt = Instant.now()
243
+ )
244
+ return userRepository.save(user)
245
+ }
246
+
247
+ override suspend fun update(id: Long, request: UpdateUserRequest): User? {
248
+ val existing = userRepository.findById(id) ?: return null
249
+
250
+ if (request.email != null && request.email != existing.email) {
251
+ if (userRepository.existsByEmail(request.email)) {
252
+ throw DuplicateException("Email already registered")
253
+ }
254
+ }
255
+
256
+ val updated = existing.copy(
257
+ name = request.name ?: existing.name,
258
+ email = request.email ?: existing.email,
259
+ updatedAt = Instant.now()
260
+ )
261
+ return userRepository.update(updated)
262
+ }
263
+
264
+ override suspend fun delete(id: Long): Boolean =
265
+ userRepository.delete(id)
266
+
267
+ override suspend fun authenticate(email: String, password: String): User {
268
+ val user = userRepository.findByEmail(email)
269
+ ?: throw AuthenticationException("Invalid credentials")
270
+
271
+ if (!BCrypt.checkpw(password, user.passwordHash)) {
272
+ throw AuthenticationException("Invalid credentials")
273
+ }
274
+
275
+ if (user.status != UserStatus.ACTIVE) {
276
+ throw AuthenticationException("Account not active")
277
+ }
278
+
279
+ return user
280
+ }
281
+
282
+ override suspend fun getUserOrders(userId: Long): List<Order> = coroutineScope {
283
+ // Verify user exists
284
+ val user = async { userRepository.findById(userId) }
285
+ val orders = async { orderRepository.findByUserId(userId) }
286
+
287
+ if (user.await() == null) {
288
+ throw NotFoundException("User not found")
289
+ }
290
+ orders.await()
291
+ }
292
+ }
293
+ ```
294
+
295
+ ### Repository with Exposed
296
+
297
+ ```kotlin
298
+ // UserRepository.kt
299
+ interface UserRepository {
300
+ suspend fun findAll(offset: Int, limit: Int): List<User>
301
+ suspend fun findById(id: Long): User?
302
+ suspend fun findByEmail(email: String): User?
303
+ suspend fun search(query: String, offset: Int, limit: Int): List<User>
304
+ suspend fun existsByEmail(email: String): Boolean
305
+ suspend fun save(user: User): User
306
+ suspend fun update(user: User): User
307
+ suspend fun delete(id: Long): Boolean
308
+ }
309
+
310
+ class UserRepositoryImpl(private val database: Database) : UserRepository {
311
+
312
+ override suspend fun findAll(offset: Int, limit: Int): List<User> = dbQuery {
313
+ UserEntity.all()
314
+ .orderBy(Users.createdAt to SortOrder.DESC)
315
+ .limit(limit, offset.toLong())
316
+ .map { it.toModel() }
317
+ }
318
+
319
+ override suspend fun findById(id: Long): User? = dbQuery {
320
+ UserEntity.findById(id)?.toModel()
321
+ }
322
+
323
+ override suspend fun findByEmail(email: String): User? = dbQuery {
324
+ UserEntity.find { Users.email eq email }.singleOrNull()?.toModel()
325
+ }
326
+
327
+ override suspend fun search(query: String, offset: Int, limit: Int): List<User> = dbQuery {
328
+ UserEntity.find {
329
+ (Users.name.lowerCase() like "%${query.lowercase()}%") or
330
+ (Users.email.lowerCase() like "%${query.lowercase()}%")
331
+ }
332
+ .orderBy(Users.createdAt to SortOrder.DESC)
333
+ .limit(limit, offset.toLong())
334
+ .map { it.toModel() }
335
+ }
336
+
337
+ override suspend fun existsByEmail(email: String): Boolean = dbQuery {
338
+ UserEntity.find { Users.email eq email }.count() > 0
339
+ }
340
+
341
+ override suspend fun save(user: User): User = dbQuery {
342
+ UserEntity.new {
343
+ name = user.name
344
+ email = user.email
345
+ passwordHash = user.passwordHash
346
+ status = user.status
347
+ }.toModel()
348
+ }
349
+
350
+ override suspend fun update(user: User): User = dbQuery {
351
+ val entity = UserEntity.findById(user.id)
352
+ ?: throw NotFoundException("User not found")
353
+ entity.name = user.name
354
+ entity.email = user.email
355
+ entity.updatedAt = Instant.now()
356
+ entity.toModel()
357
+ }
358
+
359
+ override suspend fun delete(id: Long): Boolean = dbQuery {
360
+ val entity = UserEntity.findById(id) ?: return@dbQuery false
361
+ entity.delete()
362
+ true
363
+ }
364
+
365
+ private suspend fun <T> dbQuery(block: suspend () -> T): T =
366
+ newSuspendedTransaction(Dispatchers.IO, database) { block() }
367
+ }
368
+ ```
369
+
370
+ ---
371
+
372
+ ## Android with Jetpack Compose
373
+
374
+ ### Complete Screen with ViewModel
375
+
376
+ ```kotlin
377
+ // UserListScreen.kt
378
+ @Composable
379
+ fun UserListScreen(
380
+ viewModel: UserListViewModel = hiltViewModel(),
381
+ onUserClick: (Long) -> Unit,
382
+ onAddUserClick: () -> Unit
383
+ ) {
384
+ val uiState by viewModel.uiState.collectAsStateWithLifecycle()
385
+ val snackbarHostState = remember { SnackbarHostState() }
386
+
387
+ LaunchedEffect(Unit) {
388
+ viewModel.events.collect { event ->
389
+ when (event) {
390
+ is UserListEvent.ShowError -> {
391
+ snackbarHostState.showSnackbar(event.message)
392
+ }
393
+ is UserListEvent.UserDeleted -> {
394
+ snackbarHostState.showSnackbar("User deleted successfully")
395
+ }
396
+ }
397
+ }
398
+ }
399
+
400
+ Scaffold(
401
+ topBar = {
402
+ TopAppBar(
403
+ title = { Text("Users") },
404
+ actions = {
405
+ IconButton(onClick = { viewModel.refresh() }) {
406
+ Icon(Icons.Default.Refresh, contentDescription = "Refresh")
407
+ }
408
+ }
409
+ )
410
+ },
411
+ floatingActionButton = {
412
+ FloatingActionButton(onClick = onAddUserClick) {
413
+ Icon(Icons.Default.Add, contentDescription = "Add User")
414
+ }
415
+ },
416
+ snackbarHost = { SnackbarHost(snackbarHostState) }
417
+ ) { padding ->
418
+ Box(
419
+ modifier = Modifier
420
+ .fillMaxSize()
421
+ .padding(padding)
422
+ ) {
423
+ when (val state = uiState) {
424
+ is UserListUiState.Loading -> {
425
+ CircularProgressIndicator(
426
+ modifier = Modifier.align(Alignment.Center)
427
+ )
428
+ }
429
+ is UserListUiState.Success -> {
430
+ if (state.users.isEmpty()) {
431
+ EmptyState(
432
+ message = "No users found",
433
+ onAddClick = onAddUserClick
434
+ )
435
+ } else {
436
+ UserList(
437
+ users = state.users,
438
+ onUserClick = onUserClick,
439
+ onDeleteClick = { viewModel.deleteUser(it) }
440
+ )
441
+ }
442
+ }
443
+ is UserListUiState.Error -> {
444
+ ErrorState(
445
+ message = state.message,
446
+ onRetryClick = { viewModel.retry() }
447
+ )
448
+ }
449
+ }
450
+
451
+ // Pull to refresh
452
+ PullToRefreshContainer(
453
+ state = rememberPullToRefreshState(),
454
+ isRefreshing = uiState is UserListUiState.Loading,
455
+ onRefresh = { viewModel.refresh() }
456
+ )
457
+ }
458
+ }
459
+ }
460
+
461
+ @Composable
462
+ fun UserList(
463
+ users: List<User>,
464
+ onUserClick: (Long) -> Unit,
465
+ onDeleteClick: (Long) -> Unit
466
+ ) {
467
+ LazyColumn(
468
+ contentPadding = PaddingValues(16.dp),
469
+ verticalArrangement = Arrangement.spacedBy(8.dp)
470
+ ) {
471
+ items(users, key = { it.id }) { user ->
472
+ UserListItem(
473
+ user = user,
474
+ onClick = { onUserClick(user.id) },
475
+ onDelete = { onDeleteClick(user.id) },
476
+ modifier = Modifier.animateItem()
477
+ )
478
+ }
479
+ }
480
+ }
481
+
482
+ @Composable
483
+ fun UserListItem(
484
+ user: User,
485
+ onClick: () -> Unit,
486
+ onDelete: () -> Unit,
487
+ modifier: Modifier = Modifier
488
+ ) {
489
+ var showDeleteDialog by remember { mutableStateOf(false) }
490
+
491
+ if (showDeleteDialog) {
492
+ AlertDialog(
493
+ onDismissRequest = { showDeleteDialog = false },
494
+ title = { Text("Delete User") },
495
+ text = { Text("Are you sure you want to delete ${user.name}?") },
496
+ confirmButton = {
497
+ TextButton(onClick = { onDelete(); showDeleteDialog = false }) {
498
+ Text("Delete", color = MaterialTheme.colorScheme.error)
499
+ }
500
+ },
501
+ dismissButton = {
502
+ TextButton(onClick = { showDeleteDialog = false }) {
503
+ Text("Cancel")
504
+ }
505
+ }
506
+ )
507
+ }
508
+
509
+ Card(
510
+ modifier = modifier
511
+ .fillMaxWidth()
512
+ .clickable(onClick = onClick),
513
+ elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
514
+ ) {
515
+ Row(
516
+ modifier = Modifier.padding(16.dp),
517
+ verticalAlignment = Alignment.CenterVertically
518
+ ) {
519
+ AsyncImage(
520
+ model = ImageRequest.Builder(LocalContext.current)
521
+ .data(user.avatarUrl)
522
+ .crossfade(true)
523
+ .placeholder(R.drawable.avatar_placeholder)
524
+ .build(),
525
+ contentDescription = user.name,
526
+ modifier = Modifier
527
+ .size(48.dp)
528
+ .clip(CircleShape)
529
+ )
530
+ Spacer(Modifier.width(16.dp))
531
+ Column(modifier = Modifier.weight(1f)) {
532
+ Text(
533
+ text = user.name,
534
+ style = MaterialTheme.typography.titleMedium
535
+ )
536
+ Text(
537
+ text = user.email,
538
+ style = MaterialTheme.typography.bodySmall,
539
+ color = MaterialTheme.colorScheme.onSurfaceVariant
540
+ )
541
+ }
542
+ IconButton(onClick = { showDeleteDialog = true }) {
543
+ Icon(
544
+ Icons.Default.Delete,
545
+ contentDescription = "Delete",
546
+ tint = MaterialTheme.colorScheme.error
547
+ )
548
+ }
549
+ }
550
+ }
551
+ }
552
+ ```
553
+
554
+ ### ViewModel with StateFlow
555
+
556
+ ```kotlin
557
+ // UserListViewModel.kt
558
+ @HiltViewModel
559
+ class UserListViewModel @Inject constructor(
560
+ private val userRepository: UserRepository
561
+ ) : ViewModel() {
562
+
563
+ private val _uiState = MutableStateFlow<UserListUiState>(UserListUiState.Loading)
564
+ val uiState: StateFlow<UserListUiState> = _uiState.asStateFlow()
565
+
566
+ private val _events = MutableSharedFlow<UserListEvent>()
567
+ val events: SharedFlow<UserListEvent> = _events.asSharedFlow()
568
+
569
+ init {
570
+ loadUsers()
571
+ }
572
+
573
+ fun loadUsers() {
574
+ viewModelScope.launch {
575
+ _uiState.value = UserListUiState.Loading
576
+ userRepository.getUsers()
577
+ .catch { e ->
578
+ _uiState.value = UserListUiState.Error(e.message ?: "Unknown error")
579
+ }
580
+ .collect { users ->
581
+ _uiState.value = UserListUiState.Success(users)
582
+ }
583
+ }
584
+ }
585
+
586
+ fun refresh() = loadUsers()
587
+ fun retry() = loadUsers()
588
+
589
+ fun deleteUser(id: Long) {
590
+ viewModelScope.launch {
591
+ userRepository.deleteUser(id)
592
+ .onSuccess {
593
+ _events.emit(UserListEvent.UserDeleted(id))
594
+ loadUsers()
595
+ }
596
+ .onFailure { e ->
597
+ _events.emit(UserListEvent.ShowError(e.message ?: "Failed to delete user"))
598
+ }
599
+ }
600
+ }
601
+ }
602
+
603
+ sealed interface UserListUiState {
604
+ data object Loading : UserListUiState
605
+ data class Success(val users: List<User>) : UserListUiState
606
+ data class Error(val message: String) : UserListUiState
607
+ }
608
+
609
+ sealed interface UserListEvent {
610
+ data class ShowError(val message: String) : UserListEvent
611
+ data class UserDeleted(val id: Long) : UserListEvent
612
+ }
613
+ ```
614
+
615
+ ### Repository with Room and Retrofit
616
+
617
+ ```kotlin
618
+ // UserRepository.kt
619
+ interface UserRepository {
620
+ fun getUsers(): Flow<List<User>>
621
+ suspend fun getUser(id: Long): Result<User>
622
+ suspend fun deleteUser(id: Long): Result<Unit>
623
+ suspend fun createUser(request: CreateUserRequest): Result<User>
624
+ suspend fun syncUsers(): Result<Unit>
625
+ }
626
+
627
+ class UserRepositoryImpl @Inject constructor(
628
+ private val api: UserApi,
629
+ private val dao: UserDao,
630
+ @IoDispatcher private val ioDispatcher: CoroutineDispatcher
631
+ ) : UserRepository {
632
+
633
+ override fun getUsers(): Flow<List<User>> =
634
+ dao.getAllUsers()
635
+ .onStart { syncUsersFromNetwork() }
636
+ .flowOn(ioDispatcher)
637
+
638
+ private suspend fun syncUsersFromNetwork() {
639
+ try {
640
+ val users = api.getUsers()
641
+ dao.insertAll(users.map { it.toEntity() })
642
+ } catch (e: Exception) {
643
+ // Log error, continue with cached data
644
+ Timber.e(e, "Failed to sync users from network")
645
+ }
646
+ }
647
+
648
+ override suspend fun getUser(id: Long): Result<User> = withContext(ioDispatcher) {
649
+ runCatching {
650
+ dao.getUser(id)
651
+ ?: api.getUser(id).also { dao.insert(it.toEntity()) }.toDomain()
652
+ }
653
+ }
654
+
655
+ override suspend fun deleteUser(id: Long): Result<Unit> = withContext(ioDispatcher) {
656
+ runCatching {
657
+ api.deleteUser(id)
658
+ dao.delete(id)
659
+ }
660
+ }
661
+
662
+ override suspend fun createUser(request: CreateUserRequest): Result<User> =
663
+ withContext(ioDispatcher) {
664
+ runCatching {
665
+ val user = api.createUser(request)
666
+ dao.insert(user.toEntity())
667
+ user.toDomain()
668
+ }
669
+ }
670
+
671
+ override suspend fun syncUsers(): Result<Unit> = withContext(ioDispatcher) {
672
+ runCatching {
673
+ val users = api.getUsers()
674
+ dao.deleteAll()
675
+ dao.insertAll(users.map { it.toEntity() })
676
+ }
677
+ }
678
+ }
679
+ ```
680
+
681
+ ---
682
+
683
+ ## Compose Multiplatform
684
+
685
+ ### Shared UI Module
686
+
687
+ ```kotlin
688
+ // commonMain/UserScreen.kt
689
+ @Composable
690
+ fun UserScreen(
691
+ viewModel: UserViewModel,
692
+ modifier: Modifier = Modifier
693
+ ) {
694
+ val uiState by viewModel.uiState.collectAsState()
695
+
696
+ Column(modifier = modifier.fillMaxSize()) {
697
+ // Search bar
698
+ SearchBar(
699
+ query = uiState.searchQuery,
700
+ onQueryChange = viewModel::onSearchQueryChange,
701
+ modifier = Modifier.fillMaxWidth().padding(16.dp)
702
+ )
703
+
704
+ // User list
705
+ when (val state = uiState.listState) {
706
+ is ListState.Loading -> LoadingIndicator()
707
+ is ListState.Success -> UserList(
708
+ users = state.users,
709
+ onUserClick = viewModel::onUserClick
710
+ )
711
+ is ListState.Error -> ErrorMessage(
712
+ message = state.message,
713
+ onRetry = viewModel::retry
714
+ )
715
+ }
716
+ }
717
+ }
718
+
719
+ @Composable
720
+ expect fun SearchBar(
721
+ query: String,
722
+ onQueryChange: (String) -> Unit,
723
+ modifier: Modifier = Modifier
724
+ )
725
+
726
+ // androidMain/SearchBar.kt
727
+ @Composable
728
+ actual fun SearchBar(
729
+ query: String,
730
+ onQueryChange: (String) -> Unit,
731
+ modifier: Modifier
732
+ ) {
733
+ OutlinedTextField(
734
+ value = query,
735
+ onValueChange = onQueryChange,
736
+ modifier = modifier,
737
+ placeholder = { Text("Search users...") },
738
+ leadingIcon = { Icon(Icons.Default.Search, null) },
739
+ singleLine = true
740
+ )
741
+ }
742
+
743
+ // desktopMain/SearchBar.kt
744
+ @Composable
745
+ actual fun SearchBar(
746
+ query: String,
747
+ onQueryChange: (String) -> Unit,
748
+ modifier: Modifier
749
+ ) {
750
+ TextField(
751
+ value = query,
752
+ onValueChange = onQueryChange,
753
+ modifier = modifier,
754
+ placeholder = { Text("Search users...") },
755
+ leadingIcon = { Icon(Icons.Default.Search, null) }
756
+ )
757
+ }
758
+ ```
759
+
760
+ ### Shared ViewModel
761
+
762
+ ```kotlin
763
+ // commonMain/UserViewModel.kt
764
+ class UserViewModel(
765
+ private val userRepository: UserRepository
766
+ ) : ViewModel() {
767
+
768
+ private val _uiState = MutableStateFlow(UserUiState())
769
+ val uiState: StateFlow<UserUiState> = _uiState.asStateFlow()
770
+
771
+ private val searchQuery = MutableStateFlow("")
772
+
773
+ init {
774
+ loadUsers()
775
+ observeSearch()
776
+ }
777
+
778
+ private fun loadUsers() {
779
+ viewModelScope.launch {
780
+ _uiState.update { it.copy(listState = ListState.Loading) }
781
+ userRepository.getUsers()
782
+ .catch { e ->
783
+ _uiState.update { it.copy(listState = ListState.Error(e.message ?: "Error")) }
784
+ }
785
+ .collect { users ->
786
+ _uiState.update { it.copy(listState = ListState.Success(users)) }
787
+ }
788
+ }
789
+ }
790
+
791
+ private fun observeSearch() {
792
+ viewModelScope.launch {
793
+ searchQuery
794
+ .debounce(300)
795
+ .distinctUntilChanged()
796
+ .collectLatest { query ->
797
+ if (query.isBlank()) {
798
+ loadUsers()
799
+ } else {
800
+ searchUsers(query)
801
+ }
802
+ }
803
+ }
804
+ }
805
+
806
+ private suspend fun searchUsers(query: String) {
807
+ _uiState.update { it.copy(listState = ListState.Loading) }
808
+ userRepository.searchUsers(query)
809
+ .catch { e ->
810
+ _uiState.update { it.copy(listState = ListState.Error(e.message ?: "Error")) }
811
+ }
812
+ .collect { users ->
813
+ _uiState.update { it.copy(listState = ListState.Success(users)) }
814
+ }
815
+ }
816
+
817
+ fun onSearchQueryChange(query: String) {
818
+ _uiState.update { it.copy(searchQuery = query) }
819
+ searchQuery.value = query
820
+ }
821
+
822
+ fun onUserClick(userId: Long) {
823
+ // Handle navigation
824
+ }
825
+
826
+ fun retry() = loadUsers()
827
+ }
828
+
829
+ data class UserUiState(
830
+ val searchQuery: String = "",
831
+ val listState: ListState = ListState.Loading
832
+ )
833
+
834
+ sealed interface ListState {
835
+ data object Loading : ListState
836
+ data class Success(val users: List<User>) : ListState
837
+ data class Error(val message: String) : ListState
838
+ }
839
+ ```
840
+
841
+ ---
842
+
843
+ ## Build Configuration
844
+
845
+ ### Gradle Kotlin DSL
846
+
847
+ ```kotlin
848
+ // build.gradle.kts
849
+ plugins {
850
+ kotlin("jvm") version "2.0.20"
851
+ kotlin("plugin.serialization") version "2.0.20"
852
+ id("io.ktor.plugin") version "3.0.0"
853
+ id("com.google.devtools.ksp") version "2.0.20-1.0.24"
854
+ }
855
+
856
+ group = "com.example"
857
+ version = "1.0.0"
858
+
859
+ kotlin {
860
+ jvmToolchain(21)
861
+ }
862
+
863
+ application {
864
+ mainClass.set("com.example.ApplicationKt")
865
+ }
866
+
867
+ ktor {
868
+ fatJar {
869
+ archiveFileName.set("app.jar")
870
+ }
871
+ }
872
+
873
+ dependencies {
874
+ // Ktor Server
875
+ implementation("io.ktor:ktor-server-core-jvm")
876
+ implementation("io.ktor:ktor-server-netty-jvm")
877
+ implementation("io.ktor:ktor-server-content-negotiation-jvm")
878
+ implementation("io.ktor:ktor-serialization-kotlinx-json-jvm")
879
+ implementation("io.ktor:ktor-server-auth-jvm")
880
+ implementation("io.ktor:ktor-server-auth-jwt-jvm")
881
+ implementation("io.ktor:ktor-server-status-pages-jvm")
882
+ implementation("io.ktor:ktor-server-call-logging-jvm")
883
+
884
+ // Coroutines
885
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
886
+
887
+ // Koin DI
888
+ implementation("io.insert-koin:koin-ktor:3.5.6")
889
+ implementation("io.insert-koin:koin-logger-slf4j:3.5.6")
890
+
891
+ // Exposed
892
+ implementation("org.jetbrains.exposed:exposed-core:0.55.0")
893
+ implementation("org.jetbrains.exposed:exposed-dao:0.55.0")
894
+ implementation("org.jetbrains.exposed:exposed-jdbc:0.55.0")
895
+ implementation("org.jetbrains.exposed:exposed-kotlin-datetime:0.55.0")
896
+
897
+ // Database
898
+ implementation("org.postgresql:postgresql:42.7.3")
899
+ implementation("com.zaxxer:HikariCP:5.1.0")
900
+
901
+ // Logging
902
+ implementation("ch.qos.logback:logback-classic:1.5.6")
903
+
904
+ // Testing
905
+ testImplementation("io.ktor:ktor-server-test-host-jvm")
906
+ testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
907
+ testImplementation("io.mockk:mockk:1.13.12")
908
+ testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0")
909
+ testImplementation("app.cash.turbine:turbine:1.1.0")
910
+ testImplementation("org.testcontainers:postgresql:1.20.1")
911
+ }
912
+
913
+ tasks.test {
914
+ useJUnitPlatform()
915
+ }
916
+ ```
917
+
918
+ ---
919
+
920
+ ## Models and DTOs
921
+
922
+ ```kotlin
923
+ // Models.kt
924
+ @Serializable
925
+ data class User(
926
+ val id: Long = 0,
927
+ val name: String,
928
+ val email: String,
929
+ val passwordHash: String,
930
+ val status: UserStatus,
931
+ @Serializable(with = InstantSerializer::class)
932
+ val createdAt: Instant = Instant.now(),
933
+ @Serializable(with = InstantSerializer::class)
934
+ val updatedAt: Instant? = null
935
+ ) {
936
+ fun toDto() = UserDto(id, name, email, status, createdAt)
937
+ }
938
+
939
+ @Serializable
940
+ data class UserDto(
941
+ val id: Long,
942
+ val name: String,
943
+ val email: String,
944
+ val status: UserStatus,
945
+ @Serializable(with = InstantSerializer::class)
946
+ val createdAt: Instant
947
+ )
948
+
949
+ @Serializable
950
+ data class CreateUserRequest(
951
+ val name: String,
952
+ val email: String,
953
+ val password: String
954
+ ) {
955
+ fun validate() {
956
+ require(name.isNotBlank() && name.length in 2..100) { "Name must be 2-100 characters" }
957
+ require(email.matches(Regex("^[\\w-.]+@[\\w-]+\\.[a-z]{2,}$"))) { "Invalid email format" }
958
+ require(password.length >= 8) { "Password must be at least 8 characters" }
959
+ }
960
+ }
961
+
962
+ @Serializable
963
+ data class UpdateUserRequest(
964
+ val name: String? = null,
965
+ val email: String? = null
966
+ ) {
967
+ fun validate() {
968
+ name?.let { require(it.isNotBlank() && it.length in 2..100) { "Name must be 2-100 characters" } }
969
+ email?.let { require(it.matches(Regex("^[\\w-.]+@[\\w-]+\\.[a-z]{2,}$"))) { "Invalid email format" } }
970
+ }
971
+ }
972
+
973
+ @Serializable
974
+ data class LoginRequest(
975
+ val email: String,
976
+ val password: String
977
+ )
978
+
979
+ @Serializable
980
+ data class TokenResponse(
981
+ val token: String,
982
+ val user: UserDto?
983
+ )
984
+
985
+ @Serializable
986
+ data class ErrorResponse(
987
+ val message: String,
988
+ val code: String? = null
989
+ )
990
+
991
+ @Serializable
992
+ enum class UserStatus {
993
+ PENDING, ACTIVE, SUSPENDED
994
+ }
995
+
996
+ // Exceptions
997
+ class ValidationException(message: String) : RuntimeException(message)
998
+ class NotFoundException(message: String) : RuntimeException(message)
999
+ class DuplicateException(message: String) : RuntimeException(message)
1000
+ class AuthenticationException(message: String) : RuntimeException(message)
1001
+ ```
1002
+
1003
+ ---
1004
+
1005
+ Last Updated: 2025-12-07
1006
+ Version: 1.0.0