@nextsparkjs/ai-workflow 0.1.0-beta.100

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 (272) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +115 -0
  3. package/claude/_docs/workflows-optimizations.md +359 -0
  4. package/claude/agents/api-tester.md +634 -0
  5. package/claude/agents/architecture-supervisor.md +1351 -0
  6. package/claude/agents/backend-developer.md +997 -0
  7. package/claude/agents/backend-validator.md +417 -0
  8. package/claude/agents/bdd-docs-writer.md +737 -0
  9. package/claude/agents/block-developer.md +677 -0
  10. package/claude/agents/code-reviewer.md +1432 -0
  11. package/claude/agents/db-developer.md +721 -0
  12. package/claude/agents/db-validator.md +407 -0
  13. package/claude/agents/demo-video-generator.md +493 -0
  14. package/claude/agents/documentation-writer.md +1268 -0
  15. package/claude/agents/frontend-developer.md +1234 -0
  16. package/claude/agents/frontend-validator.md +777 -0
  17. package/claude/agents/functional-validator.md +630 -0
  18. package/claude/agents/mock-analyst.md +387 -0
  19. package/claude/agents/product-manager.md +963 -0
  20. package/claude/agents/qa-automation.md +1762 -0
  21. package/claude/agents/release-manager.md +634 -0
  22. package/claude/agents/selectors-translator.md +262 -0
  23. package/claude/agents/unit-test-writer.md +785 -0
  24. package/claude/agents/visual-comparator.md +329 -0
  25. package/claude/agents/workflow-maintainer.md +352 -0
  26. package/claude/commands/do/README.md +88 -0
  27. package/claude/commands/do/create-api.md +64 -0
  28. package/claude/commands/do/create-entity.md +66 -0
  29. package/claude/commands/do/create-migration.md +64 -0
  30. package/claude/commands/do/create-plugin.md +56 -0
  31. package/claude/commands/do/create-theme.md +70 -0
  32. package/claude/commands/do/mock-data.md +67 -0
  33. package/claude/commands/do/reset-db.md +71 -0
  34. package/claude/commands/do/setup-scheduled-action.md +75 -0
  35. package/claude/commands/do/sync-code-review.md +117 -0
  36. package/claude/commands/do/update-selectors.md +112 -0
  37. package/claude/commands/do/use-skills.md +90 -0
  38. package/claude/commands/do/validate-blocks.md +69 -0
  39. package/claude/commands/how-to/README.md +261 -0
  40. package/claude/commands/how-to/add-metadata.md +692 -0
  41. package/claude/commands/how-to/add-taxonomies.md +806 -0
  42. package/claude/commands/how-to/add-translations.md +571 -0
  43. package/claude/commands/how-to/create-api.md +577 -0
  44. package/claude/commands/how-to/create-block.md +575 -0
  45. package/claude/commands/how-to/create-child-entities.md +771 -0
  46. package/claude/commands/how-to/create-entity.md +597 -0
  47. package/claude/commands/how-to/create-migrations.md +605 -0
  48. package/claude/commands/how-to/create-plugin.md +654 -0
  49. package/claude/commands/how-to/customize-app.md +481 -0
  50. package/claude/commands/how-to/customize-dashboard.md +553 -0
  51. package/claude/commands/how-to/customize-theme.md +438 -0
  52. package/claude/commands/how-to/define-features-flows.md +632 -0
  53. package/claude/commands/how-to/deploy.md +507 -0
  54. package/claude/commands/how-to/handle-file-uploads.md +746 -0
  55. package/claude/commands/how-to/implement-search.md +1001 -0
  56. package/claude/commands/how-to/install-plugins.md +352 -0
  57. package/claude/commands/how-to/manage-test-coverage.md +984 -0
  58. package/claude/commands/how-to/run-tests.md +400 -0
  59. package/claude/commands/how-to/set-app-languages.md +601 -0
  60. package/claude/commands/how-to/set-plans-and-permissions.md +575 -0
  61. package/claude/commands/how-to/set-scheduled-actions.md +527 -0
  62. package/claude/commands/how-to/set-user-roles-and-permissions.md +550 -0
  63. package/claude/commands/how-to/setup-authentication.md +388 -0
  64. package/claude/commands/how-to/setup-claude-code.md +440 -0
  65. package/claude/commands/how-to/setup-database.md +274 -0
  66. package/claude/commands/how-to/setup-email-providers.md +598 -0
  67. package/claude/commands/how-to/setup-mobile-dev.md +627 -0
  68. package/claude/commands/how-to/start.md +500 -0
  69. package/claude/commands/how-to/use-devtools.md +639 -0
  70. package/claude/commands/how-to/use-superadmin.md +622 -0
  71. package/claude/commands/session/README.md +193 -0
  72. package/claude/commands/session/block-create.md +190 -0
  73. package/claude/commands/session/block-list.md +203 -0
  74. package/claude/commands/session/block-update.md +192 -0
  75. package/claude/commands/session/block-validate.md +218 -0
  76. package/claude/commands/session/changelog.md +115 -0
  77. package/claude/commands/session/close.md +225 -0
  78. package/claude/commands/session/commit.md +174 -0
  79. package/claude/commands/session/db-entity.md +206 -0
  80. package/claude/commands/session/db-fix.md +212 -0
  81. package/claude/commands/session/db-sample.md +206 -0
  82. package/claude/commands/session/demo.md +178 -0
  83. package/claude/commands/session/doc-bdd.md +207 -0
  84. package/claude/commands/session/doc-feature.md +218 -0
  85. package/claude/commands/session/doc-read.md +225 -0
  86. package/claude/commands/session/execute.md +204 -0
  87. package/claude/commands/session/explain.md +202 -0
  88. package/claude/commands/session/fix-bug.md +210 -0
  89. package/claude/commands/session/fix-build.md +182 -0
  90. package/claude/commands/session/fix-test.md +189 -0
  91. package/claude/commands/session/pending.md +232 -0
  92. package/claude/commands/session/refine.md +188 -0
  93. package/claude/commands/session/resume.md +192 -0
  94. package/claude/commands/session/review.md +192 -0
  95. package/claude/commands/session/scope-change.md +181 -0
  96. package/claude/commands/session/start-blocks.md +347 -0
  97. package/claude/commands/session/start.md +604 -0
  98. package/claude/commands/session/status.md +169 -0
  99. package/claude/commands/session/test-fix.md +221 -0
  100. package/claude/commands/session/test-run.md +203 -0
  101. package/claude/commands/session/test-write.md +242 -0
  102. package/claude/commands/session/validate.md +162 -0
  103. package/claude/config/context.json +40 -0
  104. package/claude/config/github.json +69 -0
  105. package/claude/config/github.schema.json +106 -0
  106. package/claude/config/team.json +46 -0
  107. package/claude/config/team.schema.json +106 -0
  108. package/claude/config/workspace.json +43 -0
  109. package/claude/config/workspace.schema.json +75 -0
  110. package/claude/skills/README.md +228 -0
  111. package/claude/skills/accessibility/SKILL.md +573 -0
  112. package/claude/skills/api-bypass-layers/SKILL.md +550 -0
  113. package/claude/skills/asana-integration/SKILL.md +499 -0
  114. package/claude/skills/better-auth/SKILL.md +666 -0
  115. package/claude/skills/billing-subscriptions/SKILL.md +660 -0
  116. package/claude/skills/block-decision-matrix/SKILL.md +359 -0
  117. package/claude/skills/clickup-integration/SKILL.md +434 -0
  118. package/claude/skills/core-theme-responsibilities/SKILL.md +485 -0
  119. package/claude/skills/create-plugin/SKILL.md +425 -0
  120. package/claude/skills/create-theme/SKILL.md +331 -0
  121. package/claude/skills/cypress-api/SKILL.md +511 -0
  122. package/claude/skills/cypress-api/scripts/generate-api-controller.py +329 -0
  123. package/claude/skills/cypress-api/scripts/generate-api-test.py +930 -0
  124. package/claude/skills/cypress-e2e/SKILL.md +526 -0
  125. package/claude/skills/cypress-e2e/scripts/extract-selectors.py +383 -0
  126. package/claude/skills/cypress-e2e/scripts/generate-uat-test.py +788 -0
  127. package/claude/skills/cypress-selectors/SKILL.md +309 -0
  128. package/claude/skills/cypress-selectors/scripts/extract-missing.py +243 -0
  129. package/claude/skills/cypress-selectors/scripts/generate-block-selectors.py +283 -0
  130. package/claude/skills/cypress-selectors/scripts/validate-selectors.py +145 -0
  131. package/claude/skills/database-migrations/SKILL.md +335 -0
  132. package/claude/skills/database-migrations/scripts/generate-sample-data.py +284 -0
  133. package/claude/skills/database-migrations/scripts/validate-migration.py +323 -0
  134. package/claude/skills/design-system/SKILL.md +682 -0
  135. package/claude/skills/documentation/SKILL.md +540 -0
  136. package/claude/skills/entity-api/SKILL.md +482 -0
  137. package/claude/skills/entity-system/SKILL.md +635 -0
  138. package/claude/skills/entity-system/scripts/generate-child-migration.py +298 -0
  139. package/claude/skills/entity-system/scripts/generate-metas-migration.py +233 -0
  140. package/claude/skills/entity-system/scripts/generate-migration.py +382 -0
  141. package/claude/skills/entity-system/scripts/generate-sample-data.py +418 -0
  142. package/claude/skills/entity-system/scripts/scaffold-entity.py +661 -0
  143. package/claude/skills/github/SKILL.md +467 -0
  144. package/claude/skills/i18n-nextintl/SKILL.md +302 -0
  145. package/claude/skills/i18n-nextintl/scripts/add-translation.py +243 -0
  146. package/claude/skills/i18n-nextintl/scripts/extract-hardcoded.py +246 -0
  147. package/claude/skills/i18n-nextintl/scripts/validate-translations.py +260 -0
  148. package/claude/skills/impact-analysis/SKILL.md +203 -0
  149. package/claude/skills/jest-unit/SKILL.md +306 -0
  150. package/claude/skills/jest-unit/references/component-testing.md +371 -0
  151. package/claude/skills/jest-unit/references/mocking-patterns.md +380 -0
  152. package/claude/skills/jest-unit/references/service-hook-testing.md +454 -0
  153. package/claude/skills/jira-integration/SKILL.md +539 -0
  154. package/claude/skills/media-library/SKILL.md +743 -0
  155. package/claude/skills/mock-analysis/SKILL.md +276 -0
  156. package/claude/skills/monorepo-architecture/SKILL.md +162 -0
  157. package/claude/skills/nextjs-api-development/SKILL.md +364 -0
  158. package/claude/skills/nextjs-api-development/scripts/generate-crud-tests.py +456 -0
  159. package/claude/skills/nextjs-api-development/scripts/scaffold-endpoint.py +481 -0
  160. package/claude/skills/nextjs-api-development/scripts/validate-api.py +283 -0
  161. package/claude/skills/notion-integration/SKILL.md +641 -0
  162. package/claude/skills/npm-development-workflow/SKILL.md +480 -0
  163. package/claude/skills/page-builder-blocks/SKILL.md +530 -0
  164. package/claude/skills/page-builder-blocks/scripts/scaffold-block.py +444 -0
  165. package/claude/skills/permissions-system/SKILL.md +619 -0
  166. package/claude/skills/plugins/SKILL.md +340 -0
  167. package/claude/skills/plugins/references/plugin-templates.md +414 -0
  168. package/claude/skills/plugins/references/plugin-testing.md +353 -0
  169. package/claude/skills/plugins/references/plugin-types.md +198 -0
  170. package/claude/skills/plugins/scripts/scaffold-plugin.py +443 -0
  171. package/claude/skills/pom-patterns/SKILL.md +452 -0
  172. package/claude/skills/pom-patterns/scripts/generate-pom.py +392 -0
  173. package/claude/skills/rate-limiting/SKILL.md +342 -0
  174. package/claude/skills/react-best-practices/AGENTS.md +2410 -0
  175. package/claude/skills/react-best-practices/README.md +123 -0
  176. package/claude/skills/react-best-practices/SKILL.md +125 -0
  177. package/claude/skills/react-best-practices/metadata.json +15 -0
  178. package/claude/skills/react-best-practices/rules/_sections.md +46 -0
  179. package/claude/skills/react-best-practices/rules/_template.md +28 -0
  180. package/claude/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  181. package/claude/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
  182. package/claude/skills/react-best-practices/rules/async-api-routes.md +38 -0
  183. package/claude/skills/react-best-practices/rules/async-defer-await.md +80 -0
  184. package/claude/skills/react-best-practices/rules/async-dependencies.md +36 -0
  185. package/claude/skills/react-best-practices/rules/async-parallel.md +28 -0
  186. package/claude/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
  187. package/claude/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
  188. package/claude/skills/react-best-practices/rules/bundle-conditional.md +31 -0
  189. package/claude/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
  190. package/claude/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  191. package/claude/skills/react-best-practices/rules/bundle-preload.md +50 -0
  192. package/claude/skills/react-best-practices/rules/client-event-listeners.md +74 -0
  193. package/claude/skills/react-best-practices/rules/client-localstorage-schema.md +71 -0
  194. package/claude/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
  195. package/claude/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
  196. package/claude/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
  197. package/claude/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
  198. package/claude/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
  199. package/claude/skills/react-best-practices/rules/js-cache-storage.md +70 -0
  200. package/claude/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
  201. package/claude/skills/react-best-practices/rules/js-early-exit.md +50 -0
  202. package/claude/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
  203. package/claude/skills/react-best-practices/rules/js-index-maps.md +37 -0
  204. package/claude/skills/react-best-practices/rules/js-length-check-first.md +49 -0
  205. package/claude/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
  206. package/claude/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
  207. package/claude/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
  208. package/claude/skills/react-best-practices/rules/rendering-activity.md +26 -0
  209. package/claude/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  210. package/claude/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
  211. package/claude/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
  212. package/claude/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  213. package/claude/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  214. package/claude/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
  215. package/claude/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
  216. package/claude/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
  217. package/claude/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
  218. package/claude/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
  219. package/claude/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  220. package/claude/skills/react-best-practices/rules/rerender-memo.md +44 -0
  221. package/claude/skills/react-best-practices/rules/rerender-transitions.md +40 -0
  222. package/claude/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
  223. package/claude/skills/react-best-practices/rules/server-cache-lru.md +41 -0
  224. package/claude/skills/react-best-practices/rules/server-cache-react.md +76 -0
  225. package/claude/skills/react-best-practices/rules/server-parallel-fetching.md +83 -0
  226. package/claude/skills/react-best-practices/rules/server-serialization.md +38 -0
  227. package/claude/skills/react-patterns/SKILL.md +688 -0
  228. package/claude/skills/registry-system/SKILL.md +331 -0
  229. package/claude/skills/scheduled-actions/SKILL.md +671 -0
  230. package/claude/skills/scope-enforcement/SKILL.md +542 -0
  231. package/claude/skills/scope-enforcement/scripts/validate-scope.py +357 -0
  232. package/claude/skills/server-actions/SKILL.md +493 -0
  233. package/claude/skills/service-layer/SKILL.md +587 -0
  234. package/claude/skills/session-management/SKILL.md +266 -0
  235. package/claude/skills/session-management/scripts/create-session.py +166 -0
  236. package/claude/skills/session-management/scripts/iteration-close.sh +105 -0
  237. package/claude/skills/session-management/scripts/iteration-init.sh +180 -0
  238. package/claude/skills/session-management/scripts/session-archive.sh +87 -0
  239. package/claude/skills/session-management/scripts/session-close.sh +133 -0
  240. package/claude/skills/session-management/scripts/session-init.sh +225 -0
  241. package/claude/skills/session-management/scripts/session-list.sh +163 -0
  242. package/claude/skills/session-management/scripts/split-plan.sh +116 -0
  243. package/claude/skills/shadcn-components/SKILL.md +586 -0
  244. package/claude/skills/shadcn-theming/SKILL.md +446 -0
  245. package/claude/skills/suspense-loading/SKILL.md +280 -0
  246. package/claude/skills/tailwind-theming/SKILL.md +507 -0
  247. package/claude/skills/tanstack-query/SKILL.md +608 -0
  248. package/claude/skills/test-coverage/SKILL.md +239 -0
  249. package/claude/skills/web-design-guidelines/SKILL.md +39 -0
  250. package/claude/skills/zod-validation/SKILL.md +537 -0
  251. package/claude/templates/blocks/progress.md +86 -0
  252. package/claude/templates/iteration/changes.md +61 -0
  253. package/claude/templates/iteration/progress.md +55 -0
  254. package/claude/templates/log.md +31 -0
  255. package/claude/templates/story/context.md +77 -0
  256. package/claude/templates/story/pendings.md +37 -0
  257. package/claude/templates/story/plan.md +299 -0
  258. package/claude/templates/story/requirements.md +109 -0
  259. package/claude/templates/story/scope.json +10 -0
  260. package/claude/templates/story/tests.md +91 -0
  261. package/claude/templates/task/progress.md +58 -0
  262. package/claude/templates/task/requirements.md +54 -0
  263. package/claude/workflows/README.md +154 -0
  264. package/claude/workflows/blocks.md +614 -0
  265. package/claude/workflows/story.md +1207 -0
  266. package/claude/workflows/task.md +927 -0
  267. package/claude/workflows/tweak.md +527 -0
  268. package/cursor/.gitkeep +0 -0
  269. package/package.json +35 -0
  270. package/scripts/postinstall.mjs +198 -0
  271. package/scripts/setup.mjs +282 -0
  272. package/scripts/sync.mjs +209 -0
@@ -0,0 +1,806 @@
1
+ # /how-to:add-taxonomies
2
+
3
+ Interactive guide to implementing taxonomies (tags and categories) in NextSpark.
4
+
5
+ **Aliases:** `/how-to:tags`, `/how-to:categories`
6
+
7
+ ---
8
+
9
+ ## Required Skills
10
+
11
+ Before executing, these skills provide deeper context:
12
+ - `.claude/skills/database-migrations/SKILL.md` - Creating taxonomy tables
13
+ - `.claude/skills/entity-system/SKILL.md` - Entity field definitions
14
+
15
+ ---
16
+
17
+ ## Syntax
18
+
19
+ ```
20
+ /how-to:add-taxonomies
21
+ /how-to:add-taxonomies --type tags
22
+ /how-to:add-taxonomies --entity posts
23
+ ```
24
+
25
+ ---
26
+
27
+ ## Behavior
28
+
29
+ Guides the user through implementing a taxonomy system with tags, categories, and hierarchical classifications.
30
+
31
+ ---
32
+
33
+ ## Tutorial Structure
34
+
35
+ ```
36
+ STEPS OVERVIEW (5 steps)
37
+
38
+ Step 1: Understanding Taxonomies
39
+ └── Tags, categories, hierarchy
40
+
41
+ Step 2: Taxonomy Table Structure
42
+ └── Fields, constraints, indexes
43
+
44
+ Step 3: Creating Taxonomy Types
45
+ └── post_category, product_tag, etc.
46
+
47
+ Step 4: Linking Entities to Taxonomies
48
+ └── Join tables, many-to-many
49
+
50
+ Step 5: UI Components
51
+ └── Tag selectors, category dropdowns
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Step 1: Understanding Taxonomies
57
+
58
+ ```
59
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
60
+ 📚 HOW TO: ADD TAXONOMIES
61
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
62
+
63
+ STEP 1 OF 5: Understanding Taxonomies
64
+
65
+ Taxonomies provide a flexible classification
66
+ system for organizing content.
67
+
68
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
69
+ ```
70
+
71
+ **📋 What are Taxonomies?**
72
+
73
+ ```
74
+ ┌─────────────────────────────────────────────┐
75
+ │ TAXONOMY = Classification System │
76
+ │ ───────────────────────────────────────── │
77
+ │ │
78
+ │ TAGS (flat): │
79
+ │ [javascript] [react] [nextjs] [tutorial] │
80
+ │ │
81
+ │ CATEGORIES (hierarchical): │
82
+ │ Technology │
83
+ │ ├── Frontend │
84
+ │ │ ├── React │
85
+ │ │ └── Vue │
86
+ │ └── Backend │
87
+ │ ├── Node.js │
88
+ │ └── Python │
89
+ └─────────────────────────────────────────────┘
90
+ ```
91
+
92
+ **📋 Tags vs Categories:**
93
+
94
+ | Feature | Tags | Categories |
95
+ |---------|------|------------|
96
+ | Structure | Flat | Hierarchical |
97
+ | Multiple per item | Yes (many) | Usually 1-2 |
98
+ | User created | Often | Usually admin |
99
+ | Purpose | Discovery | Organization |
100
+ | Example | #react, #tutorial | Technology > Frontend |
101
+
102
+ **📋 Common Taxonomy Types:**
103
+
104
+ | Type | Used For | Example |
105
+ |------|----------|---------|
106
+ | `post_category` | Blog posts | Technology, Lifestyle |
107
+ | `post_tag` | Blog tags | #react, #nextjs |
108
+ | `product_category` | E-commerce | Electronics, Clothing |
109
+ | `product_tag` | Product tags | #sale, #new |
110
+ | `portfolio_type` | Portfolio items | Web, Mobile, Design |
111
+ | `skill` | User skills | JavaScript, Design |
112
+
113
+ **📋 Features:**
114
+
115
+ ```
116
+ ✓ Hierarchical support (parent-child)
117
+ ✓ Visual customization (icon, color)
118
+ ✓ Slug-based URLs (/blog/category/technology)
119
+ ✓ Ordering support
120
+ ✓ Soft delete
121
+ ✓ Metadata storage (JSONB)
122
+ ```
123
+
124
+ ```
125
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
126
+
127
+ What would you like to do?
128
+
129
+ [1] Continue to Step 2 (Table Structure)
130
+ [2] What's the difference from enum fields?
131
+ [3] Can users create their own tags?
132
+ ```
133
+
134
+ ---
135
+
136
+ ## Step 2: Taxonomy Table Structure
137
+
138
+ ```
139
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
140
+ STEP 2 OF 5: Taxonomy Table Structure
141
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
142
+
143
+ The taxonomies table provides a flexible
144
+ structure for all classification types.
145
+ ```
146
+
147
+ **📋 Taxonomies Table Schema:**
148
+
149
+ ```sql
150
+ -- migrations/006_taxonomies_table.sql
151
+
152
+ CREATE TABLE taxonomies (
153
+ id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
154
+ userId TEXT REFERENCES users(id),
155
+ teamId TEXT REFERENCES teams(id),
156
+
157
+ -- Classification
158
+ type TEXT NOT NULL, -- 'post_category', 'tag', etc.
159
+ slug TEXT NOT NULL, -- URL-friendly: 'my-category'
160
+ name TEXT NOT NULL, -- Display name: 'My Category'
161
+ description TEXT, -- Optional description
162
+
163
+ -- Visual customization
164
+ icon TEXT, -- Lucide icon name
165
+ color TEXT, -- Hex color or name
166
+
167
+ -- Hierarchy support
168
+ parentId TEXT REFERENCES taxonomies(id),
169
+
170
+ -- Metadata & ordering
171
+ metadata JSONB DEFAULT '{}', -- Flexible extra data
172
+ "order" INTEGER DEFAULT 0, -- Manual ordering
173
+
174
+ -- Status
175
+ isDefault BOOLEAN DEFAULT FALSE, -- Default selection
176
+ isActive BOOLEAN DEFAULT TRUE, -- Enable/disable
177
+
178
+ -- Timestamps
179
+ createdAt TIMESTAMPTZ DEFAULT now(),
180
+ updatedAt TIMESTAMPTZ DEFAULT now(),
181
+ deletedAt TIMESTAMPTZ, -- Soft delete
182
+
183
+ -- Constraints
184
+ UNIQUE(type, slug, teamId),
185
+ CHECK(slug ~ '^[a-z0-9\-]+$'),
186
+ CHECK(LENGTH(slug) >= 2 AND LENGTH(slug) <= 100),
187
+ CHECK(LENGTH(TRIM(name)) > 0)
188
+ );
189
+
190
+ -- Enable RLS
191
+ ALTER TABLE taxonomies ENABLE ROW LEVEL SECURITY;
192
+
193
+ -- Indexes
194
+ CREATE INDEX idx_taxonomies_type ON taxonomies(type);
195
+ CREATE INDEX idx_taxonomies_slug ON taxonomies(slug);
196
+ CREATE INDEX idx_taxonomies_team_id ON taxonomies(teamId);
197
+ CREATE INDEX idx_taxonomies_parent_id ON taxonomies(parentId);
198
+ CREATE INDEX idx_taxonomies_active ON taxonomies(isActive)
199
+ WHERE isActive = TRUE;
200
+ ```
201
+
202
+ **📋 Key Fields Explained:**
203
+
204
+ | Field | Purpose | Example |
205
+ |-------|---------|---------|
206
+ | `type` | Taxonomy classification | `'post_category'` |
207
+ | `slug` | URL-safe identifier | `'web-development'` |
208
+ | `name` | Display name | `'Web Development'` |
209
+ | `parentId` | Hierarchy support | Links to parent taxonomy |
210
+ | `icon` | Visual icon | `'Code'` (Lucide) |
211
+ | `color` | Visual color | `'#3B82F6'` |
212
+ | `metadata` | Flexible storage | `{ "featured": true }` |
213
+ | `order` | Manual sorting | `1, 2, 3...` |
214
+
215
+ **📋 Slug Validation:**
216
+
217
+ ```sql
218
+ -- Only lowercase letters, numbers, and hyphens
219
+ CHECK(slug ~ '^[a-z0-9\-]+$')
220
+
221
+ -- Minimum 2, maximum 100 characters
222
+ CHECK(LENGTH(slug) >= 2 AND LENGTH(slug) <= 100)
223
+
224
+ -- Examples:
225
+ -- ✓ 'web-development'
226
+ -- ✓ 'react-18'
227
+ -- ✗ 'Web Development' (uppercase)
228
+ -- ✗ 'web_development' (underscore)
229
+ ```
230
+
231
+ ```
232
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
233
+
234
+ What would you like to do?
235
+
236
+ [1] Continue to Step 3 (Creating Taxonomy Types)
237
+ [2] How do I add RLS policies?
238
+ [3] Can taxonomies be global (no team)?
239
+ ```
240
+
241
+ ---
242
+
243
+ ## Step 3: Creating Taxonomy Types
244
+
245
+ ```
246
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
247
+ STEP 3 OF 5: Creating Taxonomy Types
248
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
249
+
250
+ Define taxonomy types for different content
251
+ classifications in your app.
252
+ ```
253
+
254
+ **📋 Sample Data Migration:**
255
+
256
+ ```sql
257
+ -- migrations/007_taxonomies_sample_data.sql
258
+
259
+ -- Post categories (hierarchical)
260
+ INSERT INTO taxonomies (type, slug, name, icon, color, "order", teamId)
261
+ SELECT
262
+ 'post_category',
263
+ slug,
264
+ name,
265
+ icon,
266
+ color,
267
+ row_number() OVER (),
268
+ (SELECT id FROM teams LIMIT 1)
269
+ FROM (VALUES
270
+ ('technology', 'Technology', 'Cpu', '#3B82F6'),
271
+ ('lifestyle', 'Lifestyle', 'Heart', '#EC4899'),
272
+ ('business', 'Business', 'Briefcase', '#10B981'),
273
+ ('tutorials', 'Tutorials', 'GraduationCap', '#F59E0B')
274
+ ) AS t(slug, name, icon, color);
275
+
276
+ -- Sub-categories (with parent)
277
+ INSERT INTO taxonomies (type, slug, name, parentId, teamId)
278
+ SELECT
279
+ 'post_category',
280
+ slug,
281
+ name,
282
+ (SELECT id FROM taxonomies WHERE slug = parent_slug AND type = 'post_category'),
283
+ (SELECT id FROM teams LIMIT 1)
284
+ FROM (VALUES
285
+ ('frontend', 'Frontend', 'technology'),
286
+ ('backend', 'Backend', 'technology'),
287
+ ('devops', 'DevOps', 'technology'),
288
+ ('health', 'Health', 'lifestyle'),
289
+ ('travel', 'Travel', 'lifestyle')
290
+ ) AS t(slug, name, parent_slug);
291
+
292
+ -- Post tags (flat)
293
+ INSERT INTO taxonomies (type, slug, name, color, teamId)
294
+ SELECT
295
+ 'post_tag',
296
+ slug,
297
+ name,
298
+ color,
299
+ (SELECT id FROM teams LIMIT 1)
300
+ FROM (VALUES
301
+ ('javascript', 'JavaScript', '#F7DF1E'),
302
+ ('react', 'React', '#61DAFB'),
303
+ ('nextjs', 'Next.js', '#000000'),
304
+ ('typescript', 'TypeScript', '#3178C6'),
305
+ ('tutorial', 'Tutorial', '#10B981'),
306
+ ('beginner', 'Beginner', '#8B5CF6')
307
+ ) AS t(slug, name, color);
308
+ ```
309
+
310
+ **📋 Querying Taxonomies:**
311
+
312
+ ```typescript
313
+ // Get all categories with children
314
+ const categories = await db.query(`
315
+ SELECT
316
+ t.*,
317
+ (
318
+ SELECT json_agg(c.*)
319
+ FROM taxonomies c
320
+ WHERE c.parentId = t.id
321
+ ORDER BY c."order"
322
+ ) as children
323
+ FROM taxonomies t
324
+ WHERE t.type = 'post_category'
325
+ AND t.parentId IS NULL
326
+ AND t.isActive = true
327
+ AND t.teamId = $1
328
+ ORDER BY t."order"
329
+ `, [teamId])
330
+
331
+ // Result:
332
+ // [
333
+ // {
334
+ // id: '...',
335
+ // name: 'Technology',
336
+ // slug: 'technology',
337
+ // children: [
338
+ // { name: 'Frontend', slug: 'frontend' },
339
+ // { name: 'Backend', slug: 'backend' }
340
+ // ]
341
+ // },
342
+ // ...
343
+ // ]
344
+ ```
345
+
346
+ **📋 Taxonomy Service:**
347
+
348
+ ```typescript
349
+ // lib/services/taxonomy.service.ts
350
+ export class TaxonomyService {
351
+ static async getByType(type: string, teamId: string) {
352
+ return db.query(
353
+ 'SELECT * FROM taxonomies WHERE type = $1 AND teamId = $2 AND isActive = true ORDER BY "order"',
354
+ [type, teamId]
355
+ )
356
+ }
357
+
358
+ static async getHierarchy(type: string, teamId: string) {
359
+ const all = await this.getByType(type, teamId)
360
+ return buildTree(all) // Helper to build nested structure
361
+ }
362
+
363
+ static async create(data: CreateTaxonomyInput) {
364
+ const slug = slugify(data.name)
365
+ return db.query(
366
+ 'INSERT INTO taxonomies (type, slug, name, teamId, ...) VALUES ($1, $2, $3, $4, ...) RETURNING *',
367
+ [data.type, slug, data.name, data.teamId, ...]
368
+ )
369
+ }
370
+ }
371
+ ```
372
+
373
+ ```
374
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
375
+
376
+ What would you like to do?
377
+
378
+ [1] Continue to Step 4 (Linking Entities)
379
+ [2] How do I auto-generate slugs?
380
+ [3] Can I import taxonomies from a file?
381
+ ```
382
+
383
+ ---
384
+
385
+ ## Step 4: Linking Entities to Taxonomies
386
+
387
+ ```
388
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
389
+ STEP 4 OF 5: Linking Entities to Taxonomies
390
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
391
+
392
+ Connect entities to taxonomies using
393
+ join tables for many-to-many relationships.
394
+ ```
395
+
396
+ **📋 Entity-Taxonomy Relations Table:**
397
+
398
+ ```sql
399
+ -- migrations/008_entity_taxonomy_relations.sql
400
+
401
+ CREATE TABLE entity_taxonomy_relations (
402
+ id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
403
+
404
+ -- Entity reference (polymorphic)
405
+ entityType TEXT NOT NULL, -- 'posts', 'products', etc.
406
+ entityId TEXT NOT NULL, -- ID of the entity
407
+
408
+ -- Taxonomy reference
409
+ taxonomyId TEXT NOT NULL REFERENCES taxonomies(id) ON DELETE CASCADE,
410
+
411
+ -- Ordering within entity
412
+ "order" INTEGER DEFAULT 0,
413
+
414
+ -- Timestamps
415
+ createdAt TIMESTAMPTZ DEFAULT now(),
416
+
417
+ -- Constraints
418
+ UNIQUE(entityType, entityId, taxonomyId)
419
+ );
420
+
421
+ -- Indexes
422
+ CREATE INDEX idx_etr_entity ON entity_taxonomy_relations(entityType, entityId);
423
+ CREATE INDEX idx_etr_taxonomy ON entity_taxonomy_relations(taxonomyId);
424
+ ```
425
+
426
+ **📋 Alternative: Direct Foreign Key:**
427
+
428
+ ```sql
429
+ -- For single category per entity
430
+ ALTER TABLE posts ADD COLUMN categoryId TEXT REFERENCES taxonomies(id);
431
+
432
+ -- For multiple tags (JSONB array)
433
+ ALTER TABLE posts ADD COLUMN tagIds TEXT[] DEFAULT '{}';
434
+ ```
435
+
436
+ **📋 Linking Examples:**
437
+
438
+ ```typescript
439
+ // Add category to post
440
+ await db.query(`
441
+ INSERT INTO entity_taxonomy_relations (entityType, entityId, taxonomyId)
442
+ VALUES ('posts', $1, $2)
443
+ `, [postId, categoryId])
444
+
445
+ // Add multiple tags
446
+ const tagIds = ['tag-1', 'tag-2', 'tag-3']
447
+ for (const tagId of tagIds) {
448
+ await db.query(`
449
+ INSERT INTO entity_taxonomy_relations (entityType, entityId, taxonomyId)
450
+ VALUES ('posts', $1, $2)
451
+ ON CONFLICT (entityType, entityId, taxonomyId) DO NOTHING
452
+ `, [postId, tagId])
453
+ }
454
+
455
+ // Remove tag from post
456
+ await db.query(`
457
+ DELETE FROM entity_taxonomy_relations
458
+ WHERE entityType = 'posts' AND entityId = $1 AND taxonomyId = $2
459
+ `, [postId, tagId])
460
+ ```
461
+
462
+ **📋 Query with Taxonomies:**
463
+
464
+ ```typescript
465
+ // Get posts with their categories and tags
466
+ const posts = await db.query(`
467
+ SELECT
468
+ p.*,
469
+ (
470
+ SELECT json_agg(t.*)
471
+ FROM entity_taxonomy_relations etr
472
+ JOIN taxonomies t ON t.id = etr.taxonomyId
473
+ WHERE etr.entityType = 'posts'
474
+ AND etr.entityId = p.id
475
+ AND t.type = 'post_category'
476
+ ) as categories,
477
+ (
478
+ SELECT json_agg(t.*)
479
+ FROM entity_taxonomy_relations etr
480
+ JOIN taxonomies t ON t.id = etr.taxonomyId
481
+ WHERE etr.entityType = 'posts'
482
+ AND etr.entityId = p.id
483
+ AND t.type = 'post_tag'
484
+ ) as tags
485
+ FROM posts p
486
+ WHERE p.teamId = $1
487
+ `, [teamId])
488
+ ```
489
+
490
+ **📋 Filter by Taxonomy:**
491
+
492
+ ```typescript
493
+ // Get posts in a specific category
494
+ const posts = await db.query(`
495
+ SELECT p.*
496
+ FROM posts p
497
+ WHERE p.id IN (
498
+ SELECT etr.entityId
499
+ FROM entity_taxonomy_relations etr
500
+ JOIN taxonomies t ON t.id = etr.taxonomyId
501
+ WHERE etr.entityType = 'posts'
502
+ AND t.slug = $1
503
+ AND t.type = 'post_category'
504
+ )
505
+ `, [categorySlug])
506
+
507
+ // Get posts with specific tag
508
+ // GET /api/v1/posts?tag=react
509
+ ```
510
+
511
+ ```
512
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
513
+
514
+ What would you like to do?
515
+
516
+ [1] Continue to Step 5 (UI Components)
517
+ [2] How do I handle taxonomy counts?
518
+ [3] Can I have required taxonomies?
519
+ ```
520
+
521
+ ---
522
+
523
+ ## Step 5: UI Components
524
+
525
+ ```
526
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
527
+ STEP 5 OF 5: UI Components
528
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
529
+
530
+ Create UI components for selecting and
531
+ displaying taxonomies.
532
+ ```
533
+
534
+ **📋 Category Select Component:**
535
+
536
+ ```typescript
537
+ // components/CategorySelect.tsx
538
+ 'use client'
539
+
540
+ import { useQuery } from '@tanstack/react-query'
541
+ import {
542
+ Select,
543
+ SelectContent,
544
+ SelectItem,
545
+ SelectTrigger,
546
+ SelectValue,
547
+ } from '@/core/components/ui/select'
548
+
549
+ interface Props {
550
+ value: string
551
+ onChange: (value: string) => void
552
+ type: string
553
+ teamId: string
554
+ }
555
+
556
+ export function CategorySelect({ value, onChange, type, teamId }: Props) {
557
+ const { data: categories } = useQuery({
558
+ queryKey: ['taxonomies', type, teamId],
559
+ queryFn: () => fetch(`/api/v1/taxonomies?type=${type}`).then(r => r.json())
560
+ })
561
+
562
+ return (
563
+ <Select value={value} onValueChange={onChange}>
564
+ <SelectTrigger>
565
+ <SelectValue placeholder="Select category" />
566
+ </SelectTrigger>
567
+ <SelectContent>
568
+ {categories?.data?.map((cat) => (
569
+ <SelectItem key={cat.id} value={cat.id}>
570
+ {cat.icon && <span className="mr-2">{cat.icon}</span>}
571
+ {cat.name}
572
+ </SelectItem>
573
+ ))}
574
+ </SelectContent>
575
+ </Select>
576
+ )
577
+ }
578
+ ```
579
+
580
+ **📋 Tag Multi-Select Component:**
581
+
582
+ ```typescript
583
+ // components/TagSelect.tsx
584
+ 'use client'
585
+
586
+ import { useState } from 'react'
587
+ import { useQuery } from '@tanstack/react-query'
588
+ import { Badge } from '@/core/components/ui/badge'
589
+ import { X } from 'lucide-react'
590
+
591
+ interface Props {
592
+ value: string[]
593
+ onChange: (value: string[]) => void
594
+ type: string
595
+ }
596
+
597
+ export function TagSelect({ value, onChange, type }: Props) {
598
+ const [search, setSearch] = useState('')
599
+
600
+ const { data: tags } = useQuery({
601
+ queryKey: ['taxonomies', type],
602
+ queryFn: () => fetch(`/api/v1/taxonomies?type=${type}`).then(r => r.json())
603
+ })
604
+
605
+ const selectedTags = tags?.data?.filter(t => value.includes(t.id)) || []
606
+ const availableTags = tags?.data?.filter(t =>
607
+ !value.includes(t.id) &&
608
+ t.name.toLowerCase().includes(search.toLowerCase())
609
+ ) || []
610
+
611
+ const addTag = (tagId: string) => {
612
+ onChange([...value, tagId])
613
+ }
614
+
615
+ const removeTag = (tagId: string) => {
616
+ onChange(value.filter(id => id !== tagId))
617
+ }
618
+
619
+ return (
620
+ <div className="space-y-2">
621
+ {/* Selected tags */}
622
+ <div className="flex flex-wrap gap-2">
623
+ {selectedTags.map((tag) => (
624
+ <Badge
625
+ key={tag.id}
626
+ style={{ backgroundColor: tag.color }}
627
+ >
628
+ {tag.name}
629
+ <X
630
+ className="ml-1 h-3 w-3 cursor-pointer"
631
+ onClick={() => removeTag(tag.id)}
632
+ />
633
+ </Badge>
634
+ ))}
635
+ </div>
636
+
637
+ {/* Search and select */}
638
+ <input
639
+ type="text"
640
+ placeholder="Search tags..."
641
+ value={search}
642
+ onChange={(e) => setSearch(e.target.value)}
643
+ className="w-full px-3 py-2 border rounded"
644
+ />
645
+
646
+ {/* Available tags */}
647
+ {search && (
648
+ <div className="flex flex-wrap gap-2">
649
+ {availableTags.map((tag) => (
650
+ <Badge
651
+ key={tag.id}
652
+ variant="outline"
653
+ className="cursor-pointer"
654
+ onClick={() => addTag(tag.id)}
655
+ >
656
+ + {tag.name}
657
+ </Badge>
658
+ ))}
659
+ </div>
660
+ )}
661
+ </div>
662
+ )
663
+ }
664
+ ```
665
+
666
+ **📋 Entity Field Type:**
667
+
668
+ ```typescript
669
+ // In entity fields definition
670
+ {
671
+ name: 'categoryId',
672
+ type: 'taxonomy',
673
+ taxonomyType: 'post_category',
674
+ required: true,
675
+ display: {
676
+ label: 'Category',
677
+ showInList: true,
678
+ showInForm: true,
679
+ }
680
+ },
681
+ {
682
+ name: 'tagIds',
683
+ type: 'taxonomy-multi',
684
+ taxonomyType: 'post_tag',
685
+ required: false,
686
+ display: {
687
+ label: 'Tags',
688
+ showInList: true,
689
+ showInForm: true,
690
+ }
691
+ }
692
+ ```
693
+
694
+ ```
695
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
696
+
697
+ ✅ TUTORIAL STORY!
698
+
699
+ You've learned:
700
+ • Taxonomy system concepts
701
+ • Table structure with hierarchy
702
+ • Creating taxonomy types
703
+ • Entity-taxonomy relationships
704
+ • UI components for selection
705
+
706
+ 📚 Related tutorials:
707
+ • /how-to:create-entity - Create entities with taxonomies
708
+ • /how-to:create-migrations - Database setup
709
+ • /how-to:implement-search - Filter by taxonomy
710
+
711
+ 🔙 Back to menu: /how-to:start
712
+ ```
713
+
714
+ ---
715
+
716
+ ## Interactive Options
717
+
718
+ ### "What's the difference from enum fields?"
719
+
720
+ ```
721
+ 📋 Taxonomies vs Enum Fields:
722
+
723
+ ENUM FIELDS:
724
+ • Hardcoded in schema
725
+ • Requires code change to modify
726
+ • Type-safe at compile time
727
+ • Limited options (5-10 typically)
728
+ • Example: status: 'draft' | 'published' | 'archived'
729
+
730
+ TAXONOMIES:
731
+ • Stored in database
732
+ • Modified at runtime (admin UI)
733
+ • Unlimited options
734
+ • Can be user-created
735
+ • Support hierarchy
736
+ • Have metadata (icon, color, description)
737
+ • Example: categories, tags, skills
738
+
739
+ USE ENUM FOR:
740
+ ✓ Fixed, known options
741
+ ✓ Business logic (status, priority)
742
+ ✓ Type safety needed
743
+
744
+ USE TAXONOMY FOR:
745
+ ✓ User-defined classifications
746
+ ✓ Content organization
747
+ ✓ Variable number of options
748
+ ✓ Need hierarchy
749
+ ✓ Visual customization
750
+ ```
751
+
752
+ ### "How do I handle taxonomy counts?"
753
+
754
+ ```
755
+ 📋 Taxonomy Counts:
756
+
757
+ Add a count column or compute dynamically:
758
+
759
+ OPTION 1: Computed (always accurate)
760
+
761
+ SELECT
762
+ t.*,
763
+ (
764
+ SELECT COUNT(*)
765
+ FROM entity_taxonomy_relations etr
766
+ WHERE etr.taxonomyId = t.id
767
+ ) as postCount
768
+ FROM taxonomies t
769
+ WHERE t.type = 'post_category';
770
+
771
+ OPTION 2: Cached (faster, needs updates)
772
+
773
+ ALTER TABLE taxonomies ADD COLUMN entityCount INTEGER DEFAULT 0;
774
+
775
+ -- Update on insert
776
+ CREATE OR REPLACE FUNCTION update_taxonomy_count()
777
+ RETURNS TRIGGER AS $$
778
+ BEGIN
779
+ IF TG_OP = 'INSERT' THEN
780
+ UPDATE taxonomies
781
+ SET entityCount = entityCount + 1
782
+ WHERE id = NEW.taxonomyId;
783
+ ELSIF TG_OP = 'DELETE' THEN
784
+ UPDATE taxonomies
785
+ SET entityCount = entityCount - 1
786
+ WHERE id = OLD.taxonomyId;
787
+ END IF;
788
+ RETURN NULL;
789
+ END;
790
+ $$ LANGUAGE plpgsql;
791
+
792
+ CREATE TRIGGER taxonomy_count_trigger
793
+ AFTER INSERT OR DELETE ON entity_taxonomy_relations
794
+ FOR EACH ROW EXECUTE FUNCTION update_taxonomy_count();
795
+ ```
796
+
797
+ ---
798
+
799
+ ## Related Commands
800
+
801
+ | Command | Description |
802
+ |---------|-------------|
803
+ | `/how-to:create-entity` | Create entities with taxonomy fields |
804
+ | `/how-to:create-migrations` | Database setup |
805
+ | `/how-to:implement-search` | Filter by taxonomy |
806
+ | `/how-to:create-child-entities` | Taxonomies for child entities |