@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,692 @@
1
+ # /how-to:add-metadata
2
+
3
+ Interactive guide to working with entity metadata in NextSpark.
4
+
5
+ **Aliases:** `/how-to:metadata`, `/how-to:entity-metadata`
6
+
7
+ ---
8
+
9
+ ## Required Skills
10
+
11
+ Before executing, these skills provide deeper context:
12
+ - `.claude/skills/entity-system/SKILL.md` - Entity configuration and types
13
+ - `.claude/skills/database-migrations/SKILL.md` - Creating metadata tables
14
+
15
+ ---
16
+
17
+ ## Syntax
18
+
19
+ ```
20
+ /how-to:add-metadata
21
+ /how-to:add-metadata --entity users
22
+ /how-to:add-metadata --api
23
+ ```
24
+
25
+ ---
26
+
27
+ ## Behavior
28
+
29
+ Guides the user through understanding and implementing the metadata system for entities.
30
+
31
+ ---
32
+
33
+ ## Tutorial Structure
34
+
35
+ ```
36
+ STEPS OVERVIEW (5 steps)
37
+
38
+ Step 1: Understanding Metadata
39
+ └── Conceptual framework
40
+
41
+ Step 2: Metadata Tables
42
+ └── users_metas, entity_metas structure
43
+
44
+ Step 3: Using MetaService
45
+ └── getEntityMetas, getBulkEntityMetas
46
+
47
+ Step 4: Helper Functions
48
+ └── withMeta, copyEntityMetas
49
+
50
+ Step 5: API Patterns
51
+ └── Reading/writing metadata via API
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Step 1: Understanding Metadata
57
+
58
+ ```
59
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
60
+ 📚 HOW TO: ADD METADATA
61
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
62
+
63
+ STEP 1 OF 5: Understanding Metadata
64
+
65
+ Metadata allows you to extend entities with
66
+ flexible key-value data without schema changes.
67
+
68
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
69
+ ```
70
+
71
+ **📋 What is Metadata?**
72
+
73
+ ```
74
+ ┌─────────────────────────────────────────────┐
75
+ │ METADATA = Flexible Extension Data │
76
+ │ ───────────────────────────────────────── │
77
+ │ │
78
+ │ • Key-value pairs attached to entities │
79
+ │ • No schema changes required │
80
+ │ • Stored in separate _metas tables │
81
+ │ • Supports any data type (JSON) │
82
+ │ • Can be public or private │
83
+ │ • Searchable/filterable │
84
+ └─────────────────────────────────────────────┘
85
+ ```
86
+
87
+ **📋 When to Use Metadata:**
88
+
89
+ | Use Metadata | Use Schema Fields |
90
+ |--------------|-------------------|
91
+ | Optional/rare data | Required/common data |
92
+ | User-defined fields | Core business fields |
93
+ | Plugin extensions | Standard CRUD fields |
94
+ | A/B test data | Type-safe fields |
95
+ | Feature flags | Searchable fields |
96
+ | Temporary data | Indexed fields |
97
+
98
+ **📋 Metadata vs Schema Fields:**
99
+
100
+ ```typescript
101
+ // Schema field (in entity table)
102
+ // ✓ Type-safe, indexed, required
103
+ interface Task {
104
+ id: string
105
+ title: string // Schema field
106
+ status: string // Schema field
107
+ }
108
+
109
+ // Metadata (in _metas table)
110
+ // ✓ Flexible, optional, extensible
111
+ const taskMeta = {
112
+ customPriority: 5,
113
+ userNotes: 'Remember to review',
114
+ featureFlag: true,
115
+ pluginData: { ... }
116
+ }
117
+ ```
118
+
119
+ **📋 Entity Meta Configuration:**
120
+
121
+ ```typescript
122
+ // Core entity configs in types/meta.types.ts
123
+ const CORE_ENTITY_CONFIGS = {
124
+ user: {
125
+ entityType: 'user',
126
+ tableName: 'users',
127
+ metaTableName: 'users_metas',
128
+ idColumn: 'userId',
129
+ apiPath: 'users'
130
+ }
131
+ }
132
+ ```
133
+
134
+ ```
135
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
136
+
137
+ What would you like to do?
138
+
139
+ [1] Continue to Step 2 (Metadata Tables)
140
+ [2] What are good use cases for metadata?
141
+ [3] How is metadata different from JSONB columns?
142
+ ```
143
+
144
+ ---
145
+
146
+ ## Step 2: Metadata Tables
147
+
148
+ ```
149
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
150
+ STEP 2 OF 5: Metadata Tables
151
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
152
+
153
+ Metadata is stored in separate _metas tables
154
+ following a standard structure.
155
+ ```
156
+
157
+ **📋 Metadata Table Schema:**
158
+
159
+ ```sql
160
+ -- Example: users_metas table
161
+ CREATE TABLE users_metas (
162
+ id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
163
+ userId TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
164
+
165
+ -- Meta key-value
166
+ metaKey TEXT NOT NULL,
167
+ metaValue JSONB NOT NULL,
168
+
169
+ -- Type information
170
+ dataType TEXT NOT NULL DEFAULT 'string',
171
+ -- 'string' | 'number' | 'boolean' | 'json' | 'array'
172
+
173
+ -- Visibility & search
174
+ isPublic BOOLEAN DEFAULT false,
175
+ isSearchable BOOLEAN DEFAULT false,
176
+
177
+ -- Timestamps
178
+ createdAt TIMESTAMPTZ DEFAULT now(),
179
+ updatedAt TIMESTAMPTZ DEFAULT now(),
180
+
181
+ -- Constraints
182
+ UNIQUE(userId, metaKey)
183
+ );
184
+
185
+ -- Indexes for performance
186
+ CREATE INDEX idx_users_metas_user_id ON users_metas(userId);
187
+ CREATE INDEX idx_users_metas_key ON users_metas(metaKey);
188
+ CREATE INDEX idx_users_metas_searchable ON users_metas(isSearchable)
189
+ WHERE isSearchable = true;
190
+ ```
191
+
192
+ **📋 Creating Metadata Table for Custom Entity:**
193
+
194
+ ```sql
195
+ -- For a 'tasks' entity
196
+ CREATE TABLE tasks_metas (
197
+ id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
198
+ entityId TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
199
+
200
+ metaKey TEXT NOT NULL,
201
+ metaValue JSONB NOT NULL,
202
+ dataType TEXT NOT NULL DEFAULT 'string',
203
+
204
+ isPublic BOOLEAN DEFAULT false,
205
+ isSearchable BOOLEAN DEFAULT false,
206
+
207
+ createdAt TIMESTAMPTZ DEFAULT now(),
208
+ updatedAt TIMESTAMPTZ DEFAULT now(),
209
+
210
+ UNIQUE(entityId, metaKey)
211
+ );
212
+ ```
213
+
214
+ **📋 EntityMeta Interface:**
215
+
216
+ ```typescript
217
+ // From types/meta.types.ts
218
+ interface EntityMeta {
219
+ id: string
220
+ metaKey: string
221
+ metaValue: unknown // Flexible value
222
+ dataType: MetaDataType // 'string' | 'number' | 'boolean' | 'json' | 'array'
223
+ isPublic: boolean // Visibility control
224
+ isSearchable: boolean // Can be searched
225
+ createdAt: string
226
+ updatedAt: string
227
+ }
228
+ ```
229
+
230
+ **📋 Data Types:**
231
+
232
+ | Type | Description | Example |
233
+ |------|-------------|---------|
234
+ | `string` | Text value | `"hello"` |
235
+ | `number` | Numeric value | `42` |
236
+ | `boolean` | True/false | `true` |
237
+ | `json` | Object | `{ "key": "value" }` |
238
+ | `array` | Array | `[1, 2, 3]` |
239
+
240
+ ```
241
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
242
+
243
+ What would you like to do?
244
+
245
+ [1] Continue to Step 3 (Using MetaService)
246
+ [2] How do I add RLS to metadata tables?
247
+ [3] Can I have metadata without a table?
248
+ ```
249
+
250
+ ---
251
+
252
+ ## Step 3: Using MetaService
253
+
254
+ ```
255
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
256
+ STEP 3 OF 5: Using MetaService
257
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
258
+
259
+ MetaService provides methods for reading and
260
+ writing entity metadata.
261
+ ```
262
+
263
+ **📋 MetaService Methods:**
264
+
265
+ ```typescript
266
+ // From lib/services/meta.service.ts
267
+ import { MetaService } from '@/core/lib/services/meta.service'
268
+
269
+ // Get metadata for single entity
270
+ const metas = await MetaService.getEntityMetas(
271
+ 'user', // entityType
272
+ 'user-123', // entityId
273
+ 'current-user', // userId (for RLS)
274
+ false // includePrivate
275
+ )
276
+ // Returns: { preference: 'dark', language: 'en' }
277
+
278
+ // Get metadata for multiple entities (bulk)
279
+ const bulkMetas = await MetaService.getBulkEntityMetas(
280
+ 'task', // entityType
281
+ ['task-1', 'task-2', 'task-3'], // entityIds
282
+ 'current-user', // userId
283
+ false // includePrivate
284
+ )
285
+ // Returns: {
286
+ // 'task-1': { priority: 5, notes: '...' },
287
+ // 'task-2': { priority: 3 },
288
+ // 'task-3': {}
289
+ // }
290
+ ```
291
+
292
+ **📋 Why Bulk Queries?**
293
+
294
+ ```
295
+ ┌─────────────────────────────────────────────┐
296
+ │ N+1 PROBLEM SOLVED │
297
+ │ ───────────────────────────────────────── │
298
+ │ │
299
+ │ WITHOUT bulk: │
300
+ │ 1 query for entity list │
301
+ │ + N queries for N entity metas │
302
+ │ = N+1 total queries (slow!) │
303
+ │ │
304
+ │ WITH bulk: │
305
+ │ 1 query for entity list │
306
+ │ + 1 query for ALL metas │
307
+ │ = 2 total queries (fast!) │
308
+ └─────────────────────────────────────────────┘
309
+ ```
310
+
311
+ **📋 Writing Metadata:**
312
+
313
+ ```typescript
314
+ // Create/Update metadata payload
315
+ interface CreateMetaPayload {
316
+ metaKey: string
317
+ metaValue: unknown
318
+ dataType?: MetaDataType
319
+ isPublic?: boolean
320
+ isSearchable?: boolean
321
+ }
322
+
323
+ // Example: Save user preferences
324
+ await MetaService.setEntityMeta(
325
+ 'user',
326
+ 'user-123',
327
+ {
328
+ metaKey: 'theme',
329
+ metaValue: 'dark',
330
+ dataType: 'string',
331
+ isPublic: true
332
+ }
333
+ )
334
+
335
+ // Delete metadata
336
+ await MetaService.deleteEntityMeta(
337
+ 'user',
338
+ 'user-123',
339
+ 'theme' // metaKey
340
+ )
341
+ ```
342
+
343
+ **📋 Visibility Control:**
344
+
345
+ ```typescript
346
+ // isPublic controls who can see the metadata
347
+
348
+ // Public metadata (isPublic: true)
349
+ // - Visible to all users who can access the entity
350
+ // - Good for: preferences, display settings
351
+
352
+ // Private metadata (isPublic: false)
353
+ // - Only visible to entity owner or admin
354
+ // - Good for: internal notes, plugin data
355
+ ```
356
+
357
+ ```
358
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
359
+
360
+ What would you like to do?
361
+
362
+ [1] Continue to Step 4 (Helper Functions)
363
+ [2] How do I query searchable metadata?
364
+ [3] Can I use metadata in RLS policies?
365
+ ```
366
+
367
+ ---
368
+
369
+ ## Step 4: Helper Functions
370
+
371
+ ```
372
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
373
+ STEP 4 OF 5: Helper Functions
374
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
375
+
376
+ Helper functions make it easy to work with
377
+ metadata in common scenarios.
378
+ ```
379
+
380
+ **📋 withMeta Helper:**
381
+
382
+ ```typescript
383
+ // From lib/helpers/entity-meta.helpers.ts
384
+ import { withMeta } from '@/core/lib/helpers/entity-meta.helpers'
385
+
386
+ // Add metadata to single entity
387
+ const task = await getTask(taskId)
388
+ const taskWithMeta = await withMeta(
389
+ task,
390
+ 'task',
391
+ userId,
392
+ false // includePrivate
393
+ )
394
+ // Result: { id, title, status, meta: { priority: 5, notes: '...' } }
395
+
396
+ // Add metadata to array of entities
397
+ const tasks = await getTasks()
398
+ const tasksWithMeta = await withMeta(
399
+ tasks,
400
+ 'task',
401
+ userId,
402
+ false
403
+ )
404
+ // Result: [
405
+ // { id: '1', title: '...', meta: { ... } },
406
+ // { id: '2', title: '...', meta: { ... } }
407
+ // ]
408
+ ```
409
+
410
+ **📋 copyEntityMetas Helper:**
411
+
412
+ ```typescript
413
+ import { copyEntityMetas } from '@/core/lib/helpers/entity-meta.helpers'
414
+
415
+ // Copy metadata from one entity to another
416
+ await copyEntityMetas(
417
+ 'task', // entityType
418
+ 'source-task-id', // sourceEntityId
419
+ 'target-task-id', // targetEntityId
420
+ userId,
421
+ ['priority', 'notes'] // specific keys (optional)
422
+ )
423
+
424
+ // Use case: Duplicating a task with its metadata
425
+ const newTask = await duplicateTask(originalTaskId)
426
+ await copyEntityMetas('task', originalTaskId, newTask.id, userId)
427
+ ```
428
+
429
+ **📋 validateBasicMetas Helper:**
430
+
431
+ ```typescript
432
+ import { validateBasicMetas } from '@/core/lib/helpers/entity-meta.helpers'
433
+
434
+ // Validate metadata before saving
435
+ const metas = {
436
+ preference: 'dark',
437
+ count: 42,
438
+ enabled: true
439
+ }
440
+
441
+ try {
442
+ validateBasicMetas(metas)
443
+ // Valid - proceed to save
444
+ } catch (error) {
445
+ // Invalid metadata structure
446
+ }
447
+ ```
448
+
449
+ **📋 Common Pattern: Entity with Meta:**
450
+
451
+ ```typescript
452
+ // In your service layer
453
+ class TaskService {
454
+ static async getById(taskId: string, userId: string) {
455
+ const task = await db.query(
456
+ 'SELECT * FROM tasks WHERE id = $1',
457
+ [taskId]
458
+ )
459
+
460
+ // Add metadata
461
+ return withMeta(task, 'task', userId)
462
+ }
463
+
464
+ static async list(userId: string) {
465
+ const tasks = await db.query(
466
+ 'SELECT * FROM tasks WHERE team_id = $1',
467
+ [teamId]
468
+ )
469
+
470
+ // Bulk add metadata (efficient!)
471
+ return withMeta(tasks, 'task', userId)
472
+ }
473
+ }
474
+ ```
475
+
476
+ ```
477
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
478
+
479
+ What would you like to do?
480
+
481
+ [1] Continue to Step 5 (API Patterns)
482
+ [2] Show me the full helper file
483
+ [3] How do I create a custom helper?
484
+ ```
485
+
486
+ ---
487
+
488
+ ## Step 5: API Patterns
489
+
490
+ ```
491
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
492
+ STEP 5 OF 5: API Patterns
493
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
494
+
495
+ Expose metadata through your API endpoints.
496
+ ```
497
+
498
+ **📋 Including Meta in Entity Response:**
499
+
500
+ ```typescript
501
+ // In your API route handler
502
+ export async function GET(request: NextRequest) {
503
+ const auth = await authenticateRequest(request)
504
+ const { searchParams } = new URL(request.url)
505
+ const includeMeta = searchParams.get('include_meta') === 'true'
506
+
507
+ const tasks = await TaskService.list(auth.teamId)
508
+
509
+ if (includeMeta) {
510
+ const tasksWithMeta = await withMeta(tasks, 'task', auth.userId)
511
+ return createApiResponse({ data: tasksWithMeta })
512
+ }
513
+
514
+ return createApiResponse({ data: tasks })
515
+ }
516
+
517
+ // Client usage
518
+ // GET /api/v1/tasks?include_meta=true
519
+ ```
520
+
521
+ **📋 Metadata CRUD Endpoints:**
522
+
523
+ ```typescript
524
+ // GET /api/v1/tasks/:id/meta
525
+ export async function GET(request, { params }) {
526
+ const { id } = params
527
+ const auth = await authenticateRequest(request)
528
+
529
+ const metas = await MetaService.getEntityMetas(
530
+ 'task', id, auth.userId
531
+ )
532
+
533
+ return createApiResponse({ data: metas })
534
+ }
535
+
536
+ // POST /api/v1/tasks/:id/meta
537
+ export async function POST(request, { params }) {
538
+ const { id } = params
539
+ const auth = await authenticateRequest(request)
540
+ const body = await request.json()
541
+
542
+ await MetaService.setEntityMeta('task', id, {
543
+ metaKey: body.key,
544
+ metaValue: body.value,
545
+ dataType: body.type || 'string',
546
+ isPublic: body.isPublic || false
547
+ })
548
+
549
+ return createApiResponse({ message: 'Metadata saved' })
550
+ }
551
+
552
+ // DELETE /api/v1/tasks/:id/meta/:key
553
+ export async function DELETE(request, { params }) {
554
+ const { id, key } = params
555
+ const auth = await authenticateRequest(request)
556
+
557
+ await MetaService.deleteEntityMeta('task', id, key)
558
+
559
+ return createApiResponse({ message: 'Metadata deleted' })
560
+ }
561
+ ```
562
+
563
+ **📋 Query String Pattern:**
564
+
565
+ ```
566
+ # Get entity with metadata
567
+ GET /api/v1/tasks?include_meta=true
568
+
569
+ # Get only public metadata
570
+ GET /api/v1/tasks?include_meta=public
571
+
572
+ # Get specific metadata keys
573
+ GET /api/v1/tasks?include_meta=true&meta_keys=priority,notes
574
+ ```
575
+
576
+ **📋 Response Format:**
577
+
578
+ ```json
579
+ {
580
+ "success": true,
581
+ "data": {
582
+ "id": "task-123",
583
+ "title": "My Task",
584
+ "status": "pending",
585
+ "meta": {
586
+ "priority": 5,
587
+ "notes": "Important task",
588
+ "customField": { "nested": "value" }
589
+ }
590
+ }
591
+ }
592
+ ```
593
+
594
+ ```
595
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
596
+
597
+ ✅ TUTORIAL STORY!
598
+
599
+ You've learned:
600
+ • Metadata conceptual framework
601
+ • Metadata table structure
602
+ • Using MetaService
603
+ • Helper functions (withMeta, copyEntityMetas)
604
+ • API patterns for metadata
605
+
606
+ 📚 Related tutorials:
607
+ • /how-to:create-entity - Create entities with metadata support
608
+ • /how-to:create-migrations - Create metadata tables
609
+ • /how-to:create-api - Create metadata API endpoints
610
+
611
+ 🔙 Back to menu: /how-to:start
612
+ ```
613
+
614
+ ---
615
+
616
+ ## Interactive Options
617
+
618
+ ### "What are good use cases for metadata?"
619
+
620
+ ```
621
+ 📋 Common Metadata Use Cases:
622
+
623
+ USER PREFERENCES:
624
+ • Theme preference (dark/light)
625
+ • Language preference
626
+ • Notification settings
627
+ • Dashboard layout
628
+
629
+ PLUGIN EXTENSIONS:
630
+ • Plugin-specific data
631
+ • Integration tokens
632
+ • Custom fields from plugins
633
+
634
+ FEATURE FLAGS:
635
+ • Beta feature access
636
+ • A/B test groups
637
+ • Feature enablement
638
+
639
+ TEMPORARY DATA:
640
+ • Onboarding progress
641
+ • Tutorial completion
642
+ • Wizard state
643
+
644
+ CUSTOM FIELDS:
645
+ • User-defined fields
646
+ • Dynamic form data
647
+ • Flexible attributes
648
+
649
+ ANALYTICS:
650
+ • Usage counters
651
+ • Last activity timestamps
652
+ • Engagement metrics
653
+ ```
654
+
655
+ ### "How is metadata different from JSONB columns?"
656
+
657
+ ```
658
+ 📋 Metadata vs JSONB Column:
659
+
660
+ JSONB COLUMN (on main table):
661
+ ✓ Part of main entity table
662
+ ✓ Single query with entity
663
+ ✓ Can be indexed (specific paths)
664
+ ✗ Schema changes to modify
665
+ ✗ All-or-nothing visibility
666
+ ✗ Hard to manage permissions
667
+
668
+ METADATA TABLE (separate):
669
+ ✓ No schema changes needed
670
+ ✓ Per-key visibility control
671
+ ✓ Per-key searchability
672
+ ✓ Easy to extend by plugins
673
+ ✓ Independent lifecycle
674
+ ✗ Extra query needed
675
+ ✗ More complex joins
676
+
677
+ RECOMMENDATION:
678
+ • Use JSONB for structured, known data
679
+ • Use metadata for flexible, extensible data
680
+ • Use metadata for plugin/theme extensions
681
+ ```
682
+
683
+ ---
684
+
685
+ ## Related Commands
686
+
687
+ | Command | Description |
688
+ |---------|-------------|
689
+ | `/how-to:create-entity` | Create entities with metadata |
690
+ | `/how-to:create-migrations` | Create metadata tables |
691
+ | `/how-to:create-api` | Create metadata endpoints |
692
+ | `/how-to:create-child-entities` | Child entities with metadata |