@c0x12c/ai-toolkit 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/.claude-plugin/marketplace.json +16 -0
  2. package/.claude-plugin/plugin.json +12 -0
  3. package/README.md +439 -0
  4. package/VERSION +1 -0
  5. package/agents/design-critic.md +127 -0
  6. package/agents/idea-killer.md +72 -0
  7. package/agents/infrastructure-expert.md +49 -0
  8. package/agents/micronaut-backend-expert.md +45 -0
  9. package/agents/phase-reviewer.md +150 -0
  10. package/agents/research-planner.md +70 -0
  11. package/agents/solution-architect-cto.md +49 -0
  12. package/agents/sre-architect.md +49 -0
  13. package/agents/team-coordinator.md +111 -0
  14. package/bin/cli.js +780 -0
  15. package/claude-md/00-header.md +39 -0
  16. package/claude-md/01-core.md +105 -0
  17. package/claude-md/05-database.md +20 -0
  18. package/claude-md/11-backend-micronaut.md +19 -0
  19. package/claude-md/20-frontend-react.md +44 -0
  20. package/claude-md/25-ux-design.md +56 -0
  21. package/claude-md/30-infrastructure.md +24 -0
  22. package/claude-md/30-project-mgmt.md +119 -0
  23. package/claude-md/40-product.md +39 -0
  24. package/claude-md/50-ops.md +34 -0
  25. package/claude-md/60-research.md +27 -0
  26. package/claude-md/90-footer.md +21 -0
  27. package/commands/spartan/brainstorm.md +134 -0
  28. package/commands/spartan/brownfield.md +157 -0
  29. package/commands/spartan/build.md +435 -0
  30. package/commands/spartan/careful.md +94 -0
  31. package/commands/spartan/commit-message.md +112 -0
  32. package/commands/spartan/content.md +17 -0
  33. package/commands/spartan/context-save.md +161 -0
  34. package/commands/spartan/contribute.md +140 -0
  35. package/commands/spartan/daily.md +42 -0
  36. package/commands/spartan/debug.md +308 -0
  37. package/commands/spartan/deep-dive.md +55 -0
  38. package/commands/spartan/deploy.md +207 -0
  39. package/commands/spartan/e2e.md +264 -0
  40. package/commands/spartan/env-setup.md +166 -0
  41. package/commands/spartan/epic.md +199 -0
  42. package/commands/spartan/fe-review.md +181 -0
  43. package/commands/spartan/figma-to-code.md +260 -0
  44. package/commands/spartan/forensics.md +46 -0
  45. package/commands/spartan/freeze.md +84 -0
  46. package/commands/spartan/fundraise.md +53 -0
  47. package/commands/spartan/gate-review.md +229 -0
  48. package/commands/spartan/gsd-upgrade.md +376 -0
  49. package/commands/spartan/guard.md +42 -0
  50. package/commands/spartan/init-project.md +178 -0
  51. package/commands/spartan/init-rules.md +298 -0
  52. package/commands/spartan/interview.md +154 -0
  53. package/commands/spartan/kickoff.md +73 -0
  54. package/commands/spartan/kotlin-service.md +109 -0
  55. package/commands/spartan/lean-canvas.md +222 -0
  56. package/commands/spartan/lint-rules.md +122 -0
  57. package/commands/spartan/map-codebase.md +124 -0
  58. package/commands/spartan/migration.md +82 -0
  59. package/commands/spartan/next-app.md +317 -0
  60. package/commands/spartan/next-feature.md +212 -0
  61. package/commands/spartan/onboard.md +326 -0
  62. package/commands/spartan/outreach.md +16 -0
  63. package/commands/spartan/phase.md +142 -0
  64. package/commands/spartan/pitch.md +18 -0
  65. package/commands/spartan/plan.md +210 -0
  66. package/commands/spartan/pr-ready.md +202 -0
  67. package/commands/spartan/project.md +106 -0
  68. package/commands/spartan/qa.md +222 -0
  69. package/commands/spartan/research.md +254 -0
  70. package/commands/spartan/review.md +132 -0
  71. package/commands/spartan/scan-rules.md +173 -0
  72. package/commands/spartan/sessions.md +143 -0
  73. package/commands/spartan/spec.md +131 -0
  74. package/commands/spartan/startup.md +257 -0
  75. package/commands/spartan/team.md +570 -0
  76. package/commands/spartan/teardown.md +161 -0
  77. package/commands/spartan/testcontainer.md +97 -0
  78. package/commands/spartan/tf-cost.md +123 -0
  79. package/commands/spartan/tf-deploy.md +116 -0
  80. package/commands/spartan/tf-drift.md +100 -0
  81. package/commands/spartan/tf-import.md +107 -0
  82. package/commands/spartan/tf-module.md +121 -0
  83. package/commands/spartan/tf-plan.md +100 -0
  84. package/commands/spartan/tf-review.md +106 -0
  85. package/commands/spartan/tf-scaffold.md +109 -0
  86. package/commands/spartan/tf-security.md +147 -0
  87. package/commands/spartan/think.md +221 -0
  88. package/commands/spartan/unfreeze.md +13 -0
  89. package/commands/spartan/update.md +134 -0
  90. package/commands/spartan/ux.md +1233 -0
  91. package/commands/spartan/validate.md +193 -0
  92. package/commands/spartan/web-to-prd.md +706 -0
  93. package/commands/spartan/workstreams.md +109 -0
  94. package/commands/spartan/write.md +16 -0
  95. package/commands/spartan.md +386 -0
  96. package/frameworks/00-framework-comparison-guide.md +317 -0
  97. package/frameworks/01-lean-canvas.md +196 -0
  98. package/frameworks/02-design-sprint.md +304 -0
  99. package/frameworks/03-foundation-sprint.md +337 -0
  100. package/frameworks/04-business-model-canvas.md +391 -0
  101. package/frameworks/05-customer-development.md +426 -0
  102. package/frameworks/06-jobs-to-be-done.md +358 -0
  103. package/frameworks/07-mom-test.md +392 -0
  104. package/frameworks/08-value-proposition-canvas.md +488 -0
  105. package/frameworks/09-javelin-board.md +428 -0
  106. package/frameworks/10-build-measure-learn.md +467 -0
  107. package/frameworks/11-mvp-approaches.md +533 -0
  108. package/frameworks/think-before-build.md +593 -0
  109. package/lib/assembler.js +197 -0
  110. package/lib/assembler.test.js +159 -0
  111. package/lib/detector.js +166 -0
  112. package/lib/detector.test.js +221 -0
  113. package/lib/packs.js +16 -0
  114. package/lib/resolver.js +272 -0
  115. package/lib/resolver.test.js +298 -0
  116. package/lib/worktree.sh +104 -0
  117. package/package.json +50 -0
  118. package/packs/backend-micronaut.yaml +35 -0
  119. package/packs/backend-nodejs.yaml +15 -0
  120. package/packs/backend-python.yaml +15 -0
  121. package/packs/core.yaml +37 -0
  122. package/packs/database.yaml +21 -0
  123. package/packs/frontend-react.yaml +24 -0
  124. package/packs/infrastructure.yaml +40 -0
  125. package/packs/ops.yaml +16 -0
  126. package/packs/packs.compiled.json +371 -0
  127. package/packs/product.yaml +22 -0
  128. package/packs/project-mgmt.yaml +24 -0
  129. package/packs/research.yaml +39 -0
  130. package/packs/shared-backend.yaml +14 -0
  131. package/packs/ux-design.yaml +21 -0
  132. package/rules/backend-micronaut/API_DESIGN.md +313 -0
  133. package/rules/backend-micronaut/BATCH_PROCESSING.md +92 -0
  134. package/rules/backend-micronaut/CONTROLLERS.md +388 -0
  135. package/rules/backend-micronaut/KOTLIN.md +414 -0
  136. package/rules/backend-micronaut/RETROFIT_PLACEMENT.md +290 -0
  137. package/rules/backend-micronaut/SERVICES_AND_BEANS.md +325 -0
  138. package/rules/core/NAMING_CONVENTIONS.md +208 -0
  139. package/rules/core/SKILL_AUTHORING.md +174 -0
  140. package/rules/core/TIMEZONE.md +316 -0
  141. package/rules/database/ORM_AND_REPO.md +289 -0
  142. package/rules/database/SCHEMA.md +146 -0
  143. package/rules/database/TRANSACTIONS.md +311 -0
  144. package/rules/frontend-react/FRONTEND.md +344 -0
  145. package/rules/infrastructure/MODULES.md +260 -0
  146. package/rules/infrastructure/NAMING.md +196 -0
  147. package/rules/infrastructure/PROVIDERS.md +309 -0
  148. package/rules/infrastructure/SECURITY.md +310 -0
  149. package/rules/infrastructure/STATE_AND_BACKEND.md +237 -0
  150. package/rules/infrastructure/STRUCTURE.md +234 -0
  151. package/rules/infrastructure/VARIABLES.md +285 -0
  152. package/rules/shared-backend/ARCHITECTURE.md +46 -0
  153. package/rules/ux-design/DESIGN_PROCESS.md +176 -0
  154. package/skills/api-endpoint-creator/SKILL.md +455 -0
  155. package/skills/api-endpoint-creator/error-handling-guide.md +244 -0
  156. package/skills/api-endpoint-creator/examples.md +522 -0
  157. package/skills/api-endpoint-creator/testing-patterns.md +302 -0
  158. package/skills/article-writing/SKILL.md +109 -0
  159. package/skills/article-writing/examples.md +59 -0
  160. package/skills/backend-api-design/SKILL.md +84 -0
  161. package/skills/backend-api-design/code-patterns.md +138 -0
  162. package/skills/brainstorm/SKILL.md +95 -0
  163. package/skills/browser-qa/SKILL.md +87 -0
  164. package/skills/browser-qa/playwright-snippets.md +110 -0
  165. package/skills/ci-cd-patterns/SKILL.md +108 -0
  166. package/skills/ci-cd-patterns/workflows.md +149 -0
  167. package/skills/competitive-teardown/SKILL.md +93 -0
  168. package/skills/competitive-teardown/example-analysis.md +50 -0
  169. package/skills/content-engine/SKILL.md +131 -0
  170. package/skills/content-engine/examples.md +72 -0
  171. package/skills/database-patterns/SKILL.md +72 -0
  172. package/skills/database-patterns/code-templates.md +114 -0
  173. package/skills/database-table-creator/SKILL.md +141 -0
  174. package/skills/database-table-creator/examples.md +552 -0
  175. package/skills/database-table-creator/kotlin-templates.md +400 -0
  176. package/skills/database-table-creator/migration-template.sql +68 -0
  177. package/skills/database-table-creator/validation-checklist.md +337 -0
  178. package/skills/deep-research/SKILL.md +80 -0
  179. package/skills/design-intelligence/SKILL.md +268 -0
  180. package/skills/design-workflow/SKILL.md +127 -0
  181. package/skills/design-workflow/checklists.md +45 -0
  182. package/skills/idea-validation/SKILL.md +129 -0
  183. package/skills/idea-validation/example-report.md +50 -0
  184. package/skills/investor-materials/SKILL.md +122 -0
  185. package/skills/investor-materials/example-outline.md +70 -0
  186. package/skills/investor-outreach/SKILL.md +112 -0
  187. package/skills/investor-outreach/examples.md +76 -0
  188. package/skills/kotlin-best-practices/SKILL.md +58 -0
  189. package/skills/kotlin-best-practices/code-patterns.md +132 -0
  190. package/skills/market-research/SKILL.md +99 -0
  191. package/skills/security-checklist/SKILL.md +65 -0
  192. package/skills/security-checklist/audit-reference.md +95 -0
  193. package/skills/service-debugging/SKILL.md +116 -0
  194. package/skills/service-debugging/common-issues.md +65 -0
  195. package/skills/startup-pipeline/SKILL.md +152 -0
  196. package/skills/terraform-best-practices/SKILL.md +244 -0
  197. package/skills/terraform-module-creator/SKILL.md +284 -0
  198. package/skills/terraform-review/SKILL.md +222 -0
  199. package/skills/terraform-security-audit/SKILL.md +280 -0
  200. package/skills/terraform-service-scaffold/SKILL.md +574 -0
  201. package/skills/testing-strategies/SKILL.md +116 -0
  202. package/skills/testing-strategies/examples.md +103 -0
  203. package/skills/testing-strategies/integration-test-setup.md +71 -0
  204. package/skills/ui-ux-pro-max/SKILL.md +238 -0
  205. package/skills/ui-ux-pro-max/data/charts.csv +26 -0
  206. package/skills/ui-ux-pro-max/data/colors.csv +97 -0
  207. package/skills/ui-ux-pro-max/data/icons.csv +101 -0
  208. package/skills/ui-ux-pro-max/data/landing.csv +31 -0
  209. package/skills/ui-ux-pro-max/data/products.csv +97 -0
  210. package/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  211. package/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
  212. package/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  213. package/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  214. package/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  215. package/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  216. package/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  217. package/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  218. package/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  219. package/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  220. package/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  221. package/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  222. package/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  223. package/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  224. package/skills/ui-ux-pro-max/data/styles.csv +68 -0
  225. package/skills/ui-ux-pro-max/data/typography.csv +58 -0
  226. package/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  227. package/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  228. package/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
  229. package/skills/ui-ux-pro-max/python-setup.md +146 -0
  230. package/skills/ui-ux-pro-max/scripts/core.py +253 -0
  231. package/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
  232. package/skills/ui-ux-pro-max/scripts/search.py +114 -0
  233. package/skills/web-to-prd/SKILL.md +478 -0
  234. package/templates/build-config.yaml +44 -0
  235. package/templates/commands-config.yaml +55 -0
  236. package/templates/competitor-analysis.md +60 -0
  237. package/templates/content/AGENT_TEMPLATE.md +47 -0
  238. package/templates/content/COMMAND_TEMPLATE.md +27 -0
  239. package/templates/content/RULE_TEMPLATE.md +40 -0
  240. package/templates/content/SKILL_TEMPLATE.md +41 -0
  241. package/templates/design-config.md +105 -0
  242. package/templates/design-doc.md +207 -0
  243. package/templates/epic.md +100 -0
  244. package/templates/feature-spec.md +181 -0
  245. package/templates/idea-canvas.md +47 -0
  246. package/templates/implementation-plan.md +159 -0
  247. package/templates/prd-template.md +86 -0
  248. package/templates/preamble.md +89 -0
  249. package/templates/project-readme.md +35 -0
  250. package/templates/quality-gates.md +230 -0
  251. package/templates/spartan-config.yaml +164 -0
  252. package/templates/user-interview.md +69 -0
  253. package/templates/validation-checklist.md +108 -0
  254. package/templates/workflow-backend-micronaut.md +409 -0
  255. package/templates/workflow-frontend-react.md +233 -0
@@ -0,0 +1,325 @@
1
+ # Service Layer and Bean Management
2
+
3
+ ## Service Layer Rules
4
+
5
+ ### Core Principle
6
+
7
+ **Services fetch data. Managers persist data.**
8
+
9
+ ### Services MUST NOT Call Repositories
10
+
11
+ ```kotlin
12
+ // ❌ WRONG - Service calling repository
13
+ class DefaultGitHubSyncService(
14
+ private val commitRepository: GitHubCommitRepository, // NO!
15
+ private val prRepository: GitHubPullRequestRepository // NO!
16
+ ) : GitHubSyncService {
17
+
18
+ override suspend fun syncCommits(org: String) {
19
+ val commits = gitHubClient.fetchCommits(org)
20
+ commitRepository.insert(...) // Services should NOT do this!
21
+ }
22
+ }
23
+
24
+ // ✓ CORRECT - Service returns data, Manager persists
25
+ class DefaultGitHubDataFetcher(
26
+ private val gitHubClient: GitHubGraphQLClient,
27
+ private val identityResolver: IdentityResolver
28
+ ) : GitHubDataFetcher {
29
+
30
+ override suspend fun fetchCommits(org: String): Either<ClientException, List<GitHubCommitData>> {
31
+ val commits = gitHubClient.fetchCommits(org)
32
+ return commits.map { it.toData(identityResolver) }.right() // Return DTOs!
33
+ }
34
+ }
35
+ ```
36
+
37
+ ### Services Return DTOs, Not Entities
38
+
39
+ Services should return data transfer objects that represent fetched data:
40
+
41
+ ```kotlin
42
+ // DTO returned by service
43
+ data class GitHubCommitData(
44
+ val sha: String,
45
+ val authorUsername: String?,
46
+ val employeeId: UUID?, // Resolved by service
47
+ val committedAt: Instant,
48
+ val additions: Int,
49
+ val deletions: Int
50
+ )
51
+
52
+ // Manager converts DTO to Entity for persistence
53
+ class DefaultGitHubSyncManager(...) : GitHubSyncManager {
54
+
55
+ override suspend fun syncCommits(org: String) {
56
+ val commitData = dataFetcher.fetchCommits(org)
57
+ .fold({ return it.left() }, { it })
58
+
59
+ for (data in commitData) {
60
+ val entity = GitHubCommitEntity(
61
+ sha = data.sha,
62
+ employeeId = data.employeeId,
63
+ // ...
64
+ )
65
+ commitRepository.insert(entity) // Manager does persistence
66
+ }
67
+ }
68
+ }
69
+ ```
70
+
71
+ ### Service Allowed Dependencies
72
+
73
+ | Allowed | Not Allowed |
74
+ |---------|-------------|
75
+ | External API clients (GitHubGraphQLClient, SlackClient) | Repositories |
76
+ | Identity resolvers (for mapping external IDs) | Database context |
77
+ | Configuration classes | Transaction management |
78
+ | Logging | Other managers |
79
+ | Token providers | |
80
+
81
+ ### Manager Allowed Dependencies
82
+
83
+ | Allowed | Not Allowed |
84
+ |---------|-------------|
85
+ | Repositories | External API clients (use Services instead) |
86
+ | Services | Direct HTTP calls |
87
+ | Other managers | |
88
+ | Database context | |
89
+ | Distributed locks | |
90
+
91
+ ### Data Flow Examples
92
+
93
+ #### Correct: Manager Orchestrates, Service Fetches
94
+
95
+ ```
96
+ 1. Controller receives sync request
97
+
98
+ 2. Manager.syncCommits() called
99
+
100
+ 3. Manager calls Service.fetchCommits()
101
+
102
+ 4. Service calls GitHubGraphQLClient
103
+
104
+ 5. Service resolves identities
105
+
106
+ 6. Service returns List<GitHubCommitData>
107
+
108
+ 7. Manager iterates data, calls Repository.insert()
109
+
110
+ 8. Manager updates sync cursor
111
+
112
+ 9. Manager returns SyncResult to Controller
113
+ ```
114
+
115
+ #### Wrong: Service Does Everything
116
+
117
+ ```
118
+ 1. Controller receives sync request
119
+
120
+ 2. Service.syncCommits() called
121
+
122
+ 3. Service calls GitHubGraphQLClient
123
+
124
+ 4. Service calls Repository.insert() ← VIOLATION!
125
+
126
+ 5. Service returns SyncResult
127
+ ```
128
+
129
+ ### Naming Conventions
130
+
131
+ | Layer | Interface Suffix | Implementation Prefix | Example |
132
+ |-------|------------------|----------------------|---------|
133
+ | Service | `*Fetcher` or `*Service` (readonly) | `Default*` | `GitHubDataFetcher` / `DefaultGitHubDataFetcher` |
134
+ | Manager | `*Manager` | `Default*` | `GitHubSyncManager` / `DefaultGitHubSyncManager` |
135
+ | Repository | `*Repository` | `Default*` | `GitHubCommitRepository` / `DefaultGitHubCommitRepository` |
136
+
137
+ ### When to Use Service vs Manager
138
+
139
+ #### Use Service (Fetcher) When:
140
+ - Calling external APIs (GitHub, Slack, Notion, Atlas)
141
+ - Transforming external data formats
142
+ - Resolving identities (external ID → employee_id)
143
+ - No database writes needed
144
+
145
+ #### Use Manager When:
146
+ - Orchestrating multiple operations
147
+ - Persisting data to database
148
+ - Managing transactions
149
+ - Business logic that needs DB state
150
+ - Distributed locking
151
+
152
+ ### Refactoring Guide: Service Calling Repositories
153
+
154
+ When you find a Service calling repositories:
155
+
156
+ 1. **Create a new Manager interface** that defines the operation
157
+ 2. **Create a new Fetcher interface** for the external data fetch
158
+ 3. **Move DB operations to Manager**
159
+ 4. **Move API calls to Fetcher**
160
+ 5. **Manager calls Fetcher, then Repository**
161
+
162
+ #### Before (Wrong)
163
+ ```kotlin
164
+ class DefaultSyncService(
165
+ private val apiClient: ExternalApiClient,
166
+ private val repository: DataRepository // ← Problem
167
+ ) : SyncService {
168
+
169
+ override suspend fun sync() {
170
+ val data = apiClient.fetch()
171
+ repository.insert(data) // ← Service doing persistence
172
+ }
173
+ }
174
+ ```
175
+
176
+ #### After (Correct)
177
+ ```kotlin
178
+ // Service: Fetch only
179
+ class DefaultDataFetcher(
180
+ private val apiClient: ExternalApiClient
181
+ ) : DataFetcher {
182
+
183
+ override suspend fun fetch(): List<DataDTO> {
184
+ return apiClient.fetch().map { it.toDTO() }
185
+ }
186
+ }
187
+
188
+ // Manager: Orchestrate and persist
189
+ class DefaultSyncManager(
190
+ private val fetcher: DataFetcher,
191
+ private val repository: DataRepository
192
+ ) : SyncManager {
193
+
194
+ override suspend fun sync() {
195
+ val data = fetcher.fetch()
196
+ repository.insertAll(data.map { it.toEntity() })
197
+ }
198
+ }
199
+ ```
200
+
201
+ ---
202
+
203
+ ## Bean Management (3-Tier Hierarchy)
204
+
205
+ ```
206
+ Application Beans (top) — business logic, depends on module + shared
207
+
208
+ Module Beans (middle) — reusable module components, depends on shared only
209
+
210
+ Shared Beans (bottom) — infrastructure (DB, Redis, AWS), no dependencies
211
+ ```
212
+
213
+ ### Bean Creation Rules
214
+
215
+ 1. **Always use `@Factory` classes** — never `@Singleton` on implementations directly
216
+ 2. **Depend on interfaces**, not concrete classes
217
+ 3. **`@Named`** for multiple implementations of same interface
218
+ 4. **`@Primary`** for default implementation
219
+ 5. **`@Requires`** for conditional bean creation
220
+ 6. **No circular dependencies** — fix with interface extraction (see below)
221
+
222
+ ```kotlin
223
+ // CORRECT — Factory pattern
224
+ @Factory
225
+ class UserFactory {
226
+ @Singleton
227
+ fun provideUserRepository(db: DatabaseContext): UserRepository {
228
+ return DefaultUserRepository(db)
229
+ }
230
+ }
231
+
232
+ // WRONG — @Singleton on implementation
233
+ @Singleton
234
+ class DefaultUserRepository(private val db: DatabaseContext) : UserRepository
235
+ ```
236
+
237
+ ### Bean Testing
238
+
239
+ Use `@Replaces` to swap beans at any tier in tests:
240
+ ```kotlin
241
+ @Singleton
242
+ @Replaces(DatabaseContext::class)
243
+ fun testDatabaseContext(): DatabaseContext = InMemoryDatabaseContext()
244
+ ```
245
+
246
+ ### Bean Scope
247
+
248
+ - `@Singleton` — default, use this for most beans
249
+ - `@Prototype` — rare, new instance per injection
250
+ - `@RequestScope` — per HTTP request, controllers only
251
+
252
+ ---
253
+
254
+ ## Enforcement Checklists
255
+
256
+ ### Service Layer Checklist
257
+
258
+ - [ ] Services have NO repository imports
259
+ - [ ] Services have NO `insert`, `update`, `delete` calls
260
+ - [ ] Services return DTOs, not entities
261
+ - [ ] Managers handle all DB operations
262
+ - [ ] Managers wrap DB operations in transactions
263
+ - [ ] External API calls go through Services, not Managers
264
+
265
+ ### Bean Checklist
266
+
267
+ - [ ] Determine tier: Shared / Module / Application
268
+ - [ ] Create `@Factory` class with right naming
269
+ - [ ] Define bean method with `@Singleton` (or right scope)
270
+ - [ ] Inject dependencies via method parameters
271
+ - [ ] Verify dependency direction (no upward dependencies)
272
+ - [ ] Return interface type, not concrete implementation
273
+ - [ ] Use `@Named` for multiple implementations
274
+ - [ ] Use `@Primary` for default implementation
275
+ - [ ] Use `@Requires` for conditional creation
276
+ - [ ] No circular dependencies (see "Breaking Circular Dependencies" below)
277
+ - [ ] Bean is testable (can be replaced with `@Replaces`)
278
+
279
+ ---
280
+
281
+ ## Breaking Circular Dependencies
282
+
283
+ `Provider<T>` for lazy initialization is a code smell for a circular dependency. Fix the root cause.
284
+
285
+ ### The Problem
286
+
287
+ ```
288
+ ProjectManager → WorkspaceManager → SomeService → ProjectManager (cycle!)
289
+ ```
290
+
291
+ **Bad workaround:**
292
+ ```kotlin
293
+ // Provider<T> hides the cycle — DON'T DO THIS
294
+ class DefaultProjectManager(
295
+ private val workspaceManagerProvider: Provider<WorkspaceManager>, // Lazy
296
+ ) : ProjectManager
297
+ ```
298
+
299
+ ### The Fix: Interface Extraction + Layer Split
300
+
301
+ **Step 1** — Find the shared functionality causing the cycle.
302
+
303
+ **Step 2** — Extract it into a focused interface:
304
+ ```kotlin
305
+ interface ProjectThumbnailResolver {
306
+ suspend fun resolveProjectThumbnailUrl(entity: ProjectEntity): String?
307
+ }
308
+ ```
309
+
310
+ **Step 3** — Move the logic to a new component with lower-level dependencies:
311
+ ```kotlin
312
+ class DefaultProjectThumbnailResolver(
313
+ private val storageService: StorageService // No cycle
314
+ ) : ProjectThumbnailResolver { ... }
315
+ ```
316
+
317
+ **Step 4** — Inject directly, no Provider needed:
318
+ ```kotlin
319
+ class DefaultProjectManager(
320
+ private val workspaceManager: WorkspaceManager, // Direct injection
321
+ private val projectThumbnailResolver: ProjectThumbnailResolver // New!
322
+ ) : ProjectManager
323
+ ```
324
+
325
+ **Rule:** If you reach for `Provider<T>`, stop. Extract the shared functionality into its own interface at a lower layer.
@@ -0,0 +1,208 @@
1
+ # Naming Conventions
2
+
3
+ ## Overview
4
+
5
+ This document defines the naming conventions used across different layers of the stack. Consistent naming reduces bugs, makes the codebase easier to understand, and helps everyone move faster.
6
+
7
+ ## Convention Summary
8
+
9
+ | Layer | Convention | Example |
10
+ |-------|-----------|---------|
11
+ | **Database (SQL)** | `snake_case` | `points_balance`, `user_id`, `created_at` |
12
+ | **Kotlin Code** | `camelCase` | `pointsBalance`, `userId`, `createdAt` |
13
+ | **API JSON (over wire)** | `snake_case` | `"points_balance"`, `"user_id"` |
14
+ | **TypeScript Code** | `camelCase` | `pointsBalance`, `userId`, `createdAt` |
15
+
16
+ ## How It Works
17
+
18
+ ### Backend (Kotlin + Micronaut)
19
+
20
+ **Jackson ObjectMapper** is configured globally with `SNAKE_CASE` naming strategy:
21
+
22
+ ```kotlin
23
+ // In your Jackson configuration module
24
+ fun ObjectMapper.configured(): ObjectMapper {
25
+ propertyNamingStrategy = PropertyNamingStrategies.SNAKE_CASE
26
+ // ... other configuration
27
+ }
28
+ ```
29
+
30
+ This means:
31
+ - **Write Kotlin code in `camelCase`** (idiomatic Kotlin)
32
+ - **Jackson automatically converts to `snake_case`** when serializing to JSON
33
+ - **Jackson automatically converts from `snake_case`** when deserializing JSON
34
+
35
+ **Example:**
36
+ ```kotlin
37
+ // Kotlin DTO (use camelCase)
38
+ @Serdeable
39
+ data class CreateRecognitionRequest(
40
+ val receiverIds: List<UUID>, // camelCase in code
41
+ val coreValueIds: List<UUID>, // camelCase in code
42
+ val points: Int,
43
+ val message: String
44
+ )
45
+ ```
46
+
47
+ **JSON sent/received (automatic snake_case):**
48
+ ```json
49
+ {
50
+ "receiver_ids": ["uuid-1", "uuid-2"],
51
+ "core_value_ids": ["uuid-3"],
52
+ "points": 10,
53
+ "message": "Great work!"
54
+ }
55
+ ```
56
+
57
+ ### Frontend (TypeScript + React)
58
+
59
+ **Axios interceptors** automatically convert between conventions:
60
+
61
+ ```typescript
62
+ // src/lib/case-converter.ts
63
+ export function toSnakeCase<T>(obj: T): T // camelCase -> snake_case
64
+ export function toCamelCase<T>(obj: T): T // snake_case -> camelCase
65
+ ```
66
+
67
+ ```typescript
68
+ // src/lib/api.ts
69
+ // Request interceptor: Convert camelCase to snake_case before sending
70
+ api.interceptors.request.use((config) => {
71
+ if (config.data && typeof config.data === 'object') {
72
+ config.data = toSnakeCase(config.data)
73
+ }
74
+ return config
75
+ })
76
+
77
+ // Response interceptor: Convert snake_case to camelCase after receiving
78
+ api.interceptors.response.use((response) => {
79
+ if (response.data && typeof response.data === 'object') {
80
+ response.data = toCamelCase(response.data)
81
+ }
82
+ return response
83
+ })
84
+ ```
85
+
86
+ This means:
87
+ - **Write TypeScript code in `camelCase`** (idiomatic JavaScript/TypeScript)
88
+ - **Interceptors automatically convert to `snake_case`** when sending requests
89
+ - **Interceptors automatically convert to `camelCase`** when receiving responses
90
+
91
+ **Example:**
92
+ ```typescript
93
+ // TypeScript interface (use camelCase)
94
+ export interface CreateRecognitionRequest {
95
+ receiverIds: string[] // camelCase in code
96
+ coreValueIds: string[] // camelCase in code
97
+ points: number
98
+ message: string
99
+ }
100
+
101
+ // Usage - just use camelCase everywhere
102
+ const data: CreateRecognitionRequest = {
103
+ receiverIds: ['uuid-1', 'uuid-2'],
104
+ coreValueIds: ['uuid-3'],
105
+ points: 10,
106
+ message: 'Great work!'
107
+ }
108
+
109
+ // Interceptor automatically sends as snake_case
110
+ await api.post('/recognitions', data)
111
+ ```
112
+
113
+ ### Database (PostgreSQL)
114
+
115
+ All database objects use `snake_case`:
116
+
117
+ ```sql
118
+ -- Tables (plural, snake_case)
119
+ CREATE TABLE users (...)
120
+ CREATE TABLE core_values (...)
121
+ CREATE TABLE recognition_receivers (...)
122
+
123
+ -- Columns (snake_case)
124
+ id UUID PRIMARY KEY
125
+ points_balance INTEGER
126
+ allowance_balance INTEGER
127
+ created_at TIMESTAMP
128
+ updated_at TIMESTAMP
129
+ deleted_at TIMESTAMP
130
+
131
+ -- Indexes (idx_tablename_column)
132
+ CREATE INDEX idx_users_email ON users(email)
133
+ CREATE INDEX idx_recognitions_giver_id ON recognitions(giver_id)
134
+ ```
135
+
136
+ ## CRITICAL: @QueryValue Must Use Explicit snake_case Names
137
+
138
+ **The frontend axios interceptor converts ALL query params to `snake_case` (e.g., `projectId` → `project_id`). But Micronaut's `@QueryValue` does NOT auto-convert — it matches the EXACT param name from the URL.**
139
+
140
+ **Jackson's SNAKE_CASE config only affects JSON body serialization/deserialization, NOT query parameter binding.**
141
+
142
+ This means ALL multi-word `@QueryValue` params MUST have explicit snake_case names:
143
+
144
+ ```kotlin
145
+ // ✅ CORRECT — explicit snake_case name matches what frontend sends
146
+ @QueryValue("project_id") projectId: UUID,
147
+ @QueryValue("alert_id") alertId: UUID,
148
+ @QueryValue("repo_full_name") repoFullName: String,
149
+
150
+ // ❌ WRONG — Micronaut expects ?projectId=xxx but frontend sends ?project_id=xxx
151
+ @QueryValue projectId: UUID,
152
+ @QueryValue alertId: UUID,
153
+ @QueryValue repoFullName: String,
154
+
155
+ // ✅ OK — single-word params don't need explicit name (no case conversion needed)
156
+ @QueryValue status: String,
157
+ @QueryValue limit: Int,
158
+ @QueryValue id: UUID,
159
+ ```
160
+
161
+ **Rule: If a `@QueryValue` param name has more than one word (contains uppercase letters), ALWAYS add explicit `@QueryValue("snake_case_name")`.**
162
+
163
+ ## Rules
164
+
165
+ ### DO
166
+
167
+ 1. **Use `camelCase` in all Kotlin code** (properties, variables, function parameters)
168
+ 2. **Use `camelCase` in all TypeScript code** (interfaces, variables, function parameters)
169
+ 3. **Use `snake_case` in all SQL** (tables, columns, indexes)
170
+ 4. **Let the framework handle conversion** (Jackson for backend, Axios interceptors for frontend)
171
+ 5. **ALWAYS add explicit snake_case name to multi-word `@QueryValue` params**
172
+
173
+ ### DON'T
174
+
175
+ 1. **DON'T manually convert case in API calls** - interceptors handle this
176
+ 2. **DON'T use `@JsonProperty` unless mapping external APIs** (like Google OAuth)
177
+ 3. **DON'T mix conventions within the same layer**
178
+ 4. **DON'T use `snake_case` in Kotlin or TypeScript code**
179
+ 5. **DON'T use `camelCase` in SQL or JSON API contracts**
180
+ 6. **DON'T use bare `@QueryValue` for multi-word param names** — always add explicit snake_case
181
+
182
+ ### When to Use `@JsonProperty`
183
+
184
+ Only use `@JsonProperty` annotation when:
185
+ - Mapping responses from **external APIs** that don't follow your conventions
186
+ - Field names must differ from the automatic conversion for **backwards compatibility**
187
+
188
+ ```kotlin
189
+ // ONLY for external APIs (like Google OAuth)
190
+ @Serdeable
191
+ data class GoogleTokenResponse(
192
+ @JsonProperty("access_token")
193
+ val accessToken: String,
194
+ @JsonProperty("expires_in")
195
+ val expiresIn: Int,
196
+ @JsonProperty("id_token")
197
+ val idToken: String?
198
+ )
199
+ ```
200
+
201
+ ## Code Review Checklist
202
+
203
+ - [ ] No manual `snake_case` in Kotlin DTO properties
204
+ - [ ] No manual `snake_case` in TypeScript interfaces
205
+ - [ ] No manual case conversion in API calls (let interceptors handle it)
206
+ - [ ] `@JsonProperty` only used for external API mappings
207
+ - [ ] Database columns and tables use `snake_case`
208
+ - [ ] Exposed Table definitions match database column names
@@ -0,0 +1,174 @@
1
+ # Skill Authoring Rules
2
+
3
+ Rules for creating and modifying skills in the Spartan AI Toolkit. Follow these when writing new skills or improving existing ones.
4
+
5
+ ## Frontmatter (REQUIRED)
6
+
7
+ Every SKILL.md must have these fields:
8
+
9
+ ```yaml
10
+ ---
11
+ name: skill-name
12
+ description: "What it does. Use when [trigger conditions]."
13
+ allowed_tools:
14
+ - Read
15
+ - Write
16
+ # ... tools the skill needs
17
+ ---
18
+ ```
19
+
20
+ ### Description Must Be a Trigger
21
+
22
+ The description tells the model WHEN to activate the skill, not WHAT the skill is.
23
+
24
+ | Bad (summary) | Good (trigger) |
25
+ |----------------|----------------|
26
+ | "Database design patterns including schemas and migrations" | "Database design patterns. Use when creating tables, writing migrations, or implementing repositories." |
27
+ | "The full startup pipeline from brainstorm to outreach" | "Coordinates the full startup pipeline. Use when the user starts a new idea project or references stages/gates." |
28
+
29
+ **Rule:** Every description must contain "Use when" followed by specific trigger conditions.
30
+
31
+ ### allowed_tools Must Match the Skill's Needs
32
+
33
+ | Skill type | Typical tools |
34
+ |------------|--------------|
35
+ | Code/backend (writes files) | Read, Write, Edit, Glob, Grep, Bash |
36
+ | Research/analysis (web searches) | WebSearch, WebFetch, Read |
37
+ | Content/writing (creates + researches) | Read, Write, WebSearch |
38
+ | Review/audit (reads only) | Read, Glob, Grep |
39
+
40
+ ---
41
+
42
+ ## Folder Structure (Skills Are Folders, Not Files)
43
+
44
+ A skill is a directory, not just a markdown file. Use the file system for progressive disclosure.
45
+
46
+ ```
47
+ toolkit/skills/my-skill/
48
+ SKILL.md # Main definition — short, high-level (required)
49
+ code-patterns.md # Code examples (if code-heavy skill)
50
+ examples.md # Good/bad examples (if teaching a style)
51
+ checklists.md # Review checklists (if audit/review skill)
52
+ workflows.md # Ready-to-use templates (if scaffolding skill)
53
+ ```
54
+
55
+ ### When to Split Into Multiple Files
56
+
57
+ | SKILL.md is... | Action |
58
+ |-----------------|--------|
59
+ | Under 100 lines | One file is fine |
60
+ | 100-150 lines with code blocks | Split code into a reference file |
61
+ | 150+ lines | Must split — too much for one read |
62
+
63
+ ### SKILL.md Should Be the Summary
64
+
65
+ Keep SKILL.md short (60-120 lines). It should have:
66
+ - Frontmatter
67
+ - "When to Use" section
68
+ - Key rules and principles (without detailed code)
69
+ - Gotchas section
70
+ - References to supporting files
71
+
72
+ Move into supporting files:
73
+ - Detailed code templates and examples
74
+ - Long checklists
75
+ - Good/bad comparisons
76
+ - Ready-to-use templates
77
+
78
+ Reference with: `> See code-patterns.md for complete implementation templates.`
79
+
80
+ ---
81
+
82
+ ## Gotchas Section (REQUIRED)
83
+
84
+ Every skill must have a `## Gotchas` section. This is the highest-value content in any skill.
85
+
86
+ ### Format
87
+
88
+ ```markdown
89
+ ## Gotchas
90
+
91
+ - **Bold lead-in sentence.** Explanation of why this matters and what to do instead.
92
+ - **Another gotcha.** Details.
93
+ ```
94
+
95
+ ### What Makes a Good Gotcha
96
+
97
+ - Specific failure patterns Claude hits when using this skill
98
+ - Things that look right but are wrong
99
+ - Common mistakes users make in this domain
100
+ - Counter-intuitive rules that violate defaults
101
+
102
+ ### What is NOT a Gotcha
103
+
104
+ - General best practices (put those in Rules)
105
+ - Obvious things Claude already knows
106
+ - Restating the instructions in negative form
107
+
108
+ **Minimum 3 gotchas per skill. Build this section over time as you find new failure patterns.**
109
+
110
+ ---
111
+
112
+ ## Content Rules
113
+
114
+ ### Don't State the Obvious
115
+
116
+ Claude already knows how to code, research, and write. Focus on information that pushes Claude OUT of its normal patterns.
117
+
118
+ | Bad (obvious) | Good (non-obvious) |
119
+ |----------------|---------------------|
120
+ | "Use proper error handling" | "`!!` is banned — use `?.`, `?:`, or null check" |
121
+ | "Write clean code" | "Don't add docstrings to code you didn't change" |
122
+ | "Research thoroughly" | "Press releases aren't research — cross-check with third-party sources" |
123
+
124
+ ### Give Claude Flexibility
125
+
126
+ Tell Claude WHAT to check and WHY, not exact steps for every situation. Skills are reused across many contexts — being too specific makes them brittle.
127
+
128
+ | Bad (railroading) | Good (flexible) |
129
+ |---------------------|------------------|
130
+ | "Step 1: Open file X. Step 2: Find line Y. Step 3: Change to Z." | "Check the controller for @ExecuteOn annotation. If missing, add it." |
131
+
132
+ ### Use Examples Over Instructions
133
+
134
+ A good/bad example teaches more than a paragraph of rules. When possible, show rather than tell.
135
+
136
+ ---
137
+
138
+ ## Config Pattern (for Stateful Skills)
139
+
140
+ Skills that run repeatedly for the same user should store preferences:
141
+
142
+ ```json
143
+ // content-config.json in the project root
144
+ {
145
+ "defaultPlatforms": ["x", "linkedin"],
146
+ "brandVoice": "direct and technical",
147
+ "audience": "developers"
148
+ }
149
+ ```
150
+
151
+ Read config at skill start. Skip setup questions for configured fields.
152
+
153
+ ---
154
+
155
+ ## Naming
156
+
157
+ | Type | Convention | Example |
158
+ |------|-----------|---------|
159
+ | Skill directory | `kebab-case` | `ci-cd-patterns/` |
160
+ | Main file | `SKILL.md` (always) | `SKILL.md` |
161
+ | Supporting files | `kebab-case.md` | `code-patterns.md` |
162
+
163
+ ---
164
+
165
+ ## Checklist: Before Shipping a Skill
166
+
167
+ - [ ] Frontmatter has `name`, `description` (with trigger), and `allowed_tools`
168
+ - [ ] Description says "Use when..." with specific conditions
169
+ - [ ] SKILL.md is under 120 lines (split if longer)
170
+ - [ ] Has a `## Gotchas` section with 3+ items
171
+ - [ ] Code-heavy content is in supporting files, not inline
172
+ - [ ] Examples show good AND bad patterns where applicable
173
+ - [ ] Doesn't restate things Claude already knows
174
+ - [ ] Gives Claude flexibility — principles over exact steps