@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,493 @@
1
+ ---
2
+ name: server-actions
3
+ description: |
4
+ Next.js Server Actions for mutations in this application.
5
+ Covers entity actions, user actions, team actions, and best practices.
6
+ Use this skill when implementing mutations from Client Components.
7
+ allowed-tools: Read, Glob, Grep
8
+ version: 1.0.0
9
+ ---
10
+
11
+ # Server Actions Skill
12
+
13
+ Patterns for using Next.js Server Actions to perform mutations from Client Components.
14
+
15
+ ## Architecture Overview
16
+
17
+ ```
18
+ core/lib/actions/
19
+ ├── index.ts # Re-exports all actions
20
+ ├── types.ts # Shared types (EntityActionResult, etc.)
21
+ ├── entity.actions.ts # Generic CRUD for any registered entity
22
+ ├── user.actions.ts # User profile management
23
+ └── team.actions.ts # Team and member management
24
+ ```
25
+
26
+ ## When to Use This Skill
27
+
28
+ - Calling mutations from Client Components (`'use client'`)
29
+ - Form submissions without JavaScript
30
+ - Automatic cache revalidation after mutations
31
+ - Type-safe end-to-end mutations
32
+
33
+ ## Import Pattern
34
+
35
+ ```typescript
36
+ // From Client Components
37
+ 'use client'
38
+
39
+ import {
40
+ // Entity actions
41
+ createEntity,
42
+ updateEntity,
43
+ deleteEntity,
44
+ getEntity,
45
+ listEntities,
46
+ deleteEntities,
47
+ entityExists,
48
+ countEntities,
49
+ // User actions
50
+ updateProfile,
51
+ updateAvatar,
52
+ deleteAccount,
53
+ // Team actions
54
+ updateTeam,
55
+ inviteMember,
56
+ removeMember,
57
+ updateMemberRole,
58
+ } from '@nextsparkjs/core/actions'
59
+ ```
60
+
61
+ ## Security Model
62
+
63
+ **All actions follow the same security pattern:**
64
+
65
+ 1. Auth is obtained from session/cookies (NEVER from client parameters)
66
+ 2. `userId` comes from `getTypedSession()`
67
+ 3. `teamId` comes from `httpOnly` cookie `activeTeamId`
68
+ 4. Permissions are checked via `checkPermission()`
69
+
70
+ **Never pass userId/teamId as parameters:**
71
+ ```typescript
72
+ // WRONG - Never trust client data for auth
73
+ export async function updateProfile(userId: string, data: ProfileData) { ... }
74
+
75
+ // CORRECT - Get auth from server context
76
+ export async function updateProfile(data: ProfileData) {
77
+ const session = await getTypedSession(await headers())
78
+ if (!session?.user?.id) {
79
+ return { success: false, error: 'Authentication required' }
80
+ }
81
+ const userId = session.user.id
82
+ // ...
83
+ }
84
+ ```
85
+
86
+ ## Entity Actions
87
+
88
+ ### createEntity
89
+
90
+ Create a new entity record.
91
+
92
+ ```typescript
93
+ const result = await createEntity('products', {
94
+ name: 'New Product',
95
+ price: 99.99,
96
+ status: 'draft',
97
+ })
98
+
99
+ if (result.success) {
100
+ console.log('Created:', result.data)
101
+ } else {
102
+ console.error('Error:', result.error)
103
+ }
104
+ ```
105
+
106
+ ### updateEntity
107
+
108
+ Update an existing entity.
109
+
110
+ ```typescript
111
+ const result = await updateEntity('products', productId, {
112
+ status: 'published',
113
+ })
114
+
115
+ // With custom revalidation
116
+ await updateEntity('products', productId, data, {
117
+ revalidatePaths: ['/dashboard/overview'],
118
+ revalidateTags: ['product-stats'],
119
+ })
120
+ ```
121
+
122
+ ### deleteEntity
123
+
124
+ Delete an entity by ID.
125
+
126
+ ```typescript
127
+ const result = await deleteEntity('products', productId)
128
+
129
+ // With redirect after delete
130
+ await deleteEntity('products', productId, {
131
+ redirectTo: '/dashboard/products',
132
+ })
133
+ ```
134
+
135
+ ### deleteEntities (Batch)
136
+
137
+ Delete multiple entities at once.
138
+
139
+ ```typescript
140
+ const result = await deleteEntities('products', ['id1', 'id2', 'id3'])
141
+
142
+ if (result.success) {
143
+ console.log(`Deleted ${result.data.deletedCount} products`)
144
+ }
145
+ ```
146
+
147
+ ### getEntity / listEntities
148
+
149
+ For reads from Client Components (prefer Server Components when possible).
150
+
151
+ ```typescript
152
+ // Get single entity
153
+ const result = await getEntity('products', productId)
154
+
155
+ // List with pagination and filters
156
+ const result = await listEntities('products', {
157
+ limit: 20,
158
+ offset: 0,
159
+ where: { status: 'active' },
160
+ orderBy: 'createdAt',
161
+ orderDir: 'desc',
162
+ })
163
+ ```
164
+
165
+ ### entityExists / countEntities
166
+
167
+ ```typescript
168
+ // Check if entity exists
169
+ const result = await entityExists('products', productId)
170
+
171
+ // Count with filter
172
+ const result = await countEntities('products', { status: 'active' })
173
+ ```
174
+
175
+ ## User Actions
176
+
177
+ ### updateProfile
178
+
179
+ Update the current user's profile.
180
+
181
+ ```typescript
182
+ const result = await updateProfile({
183
+ firstName: 'John',
184
+ lastName: 'Doe',
185
+ timezone: 'America/New_York',
186
+ language: 'en',
187
+ })
188
+
189
+ // Allowed fields: firstName, lastName, name, country, timezone, language
190
+ ```
191
+
192
+ ### updateAvatar
193
+
194
+ Update the user's avatar (URL, not file upload).
195
+
196
+ ```typescript
197
+ // After uploading file to storage and getting URL
198
+ const formData = new FormData()
199
+ formData.append('avatar', 'https://example.com/uploaded-avatar.jpg')
200
+
201
+ const result = await updateAvatar(formData)
202
+ ```
203
+
204
+ ### deleteAccount
205
+
206
+ Delete the current user's account.
207
+
208
+ ```typescript
209
+ // Check conditions first!
210
+ const result = await deleteAccount()
211
+
212
+ // Will fail if user owns teams
213
+ // Error: "Cannot delete account while owning teams. Transfer ownership first."
214
+ ```
215
+
216
+ ## Team Actions
217
+
218
+ ### updateTeam
219
+
220
+ Update team information (requires owner or admin role).
221
+
222
+ ```typescript
223
+ const result = await updateTeam(teamId, {
224
+ name: 'New Team Name',
225
+ description: 'Updated description',
226
+ slug: 'new-slug',
227
+ })
228
+
229
+ // Will check slug availability if changing
230
+ ```
231
+
232
+ ### inviteMember
233
+
234
+ Add a user to the team (requires owner or admin role).
235
+
236
+ ```typescript
237
+ const result = await inviteMember(
238
+ teamId,
239
+ 'user@example.com', // User must already exist
240
+ 'member' // 'member' | 'admin' | 'viewer'
241
+ )
242
+
243
+ if (result.success) {
244
+ console.log('Invited:', result.data.memberId)
245
+ }
246
+ ```
247
+
248
+ ### removeMember
249
+
250
+ Remove a member from the team.
251
+
252
+ ```typescript
253
+ const result = await removeMember(teamId, userId)
254
+
255
+ // Cannot remove:
256
+ // - Team owner (must transfer ownership first)
257
+ // - Other admins (if requestor is admin, not owner)
258
+ ```
259
+
260
+ ### updateMemberRole
261
+
262
+ Change a member's role.
263
+
264
+ ```typescript
265
+ const result = await updateMemberRole(teamId, userId, 'admin')
266
+
267
+ // Restrictions:
268
+ // - Cannot set role to 'owner' (use transferOwnership)
269
+ // - Only owner can promote to admin
270
+ // - Only owner can demote admins
271
+ ```
272
+
273
+ ## Result Types
274
+
275
+ All actions return a discriminated union:
276
+
277
+ ```typescript
278
+ type EntityActionResult<T> =
279
+ | { success: true; data: T }
280
+ | { success: false; error: string }
281
+
282
+ type EntityActionVoidResult =
283
+ | { success: true }
284
+ | { success: false; error: string }
285
+ ```
286
+
287
+ Usage with type guards:
288
+
289
+ ```typescript
290
+ const result = await createEntity('products', data)
291
+
292
+ if (result.success) {
293
+ // TypeScript knows result.data exists
294
+ console.log(result.data.id)
295
+ } else {
296
+ // TypeScript knows result.error exists
297
+ toast.error(result.error)
298
+ }
299
+ ```
300
+
301
+ ## Revalidation Patterns
302
+
303
+ ### Default Revalidation
304
+
305
+ Entity actions automatically revalidate:
306
+ - Create: `/dashboard/{entitySlug}`
307
+ - Update: `/dashboard/{entitySlug}` and `/dashboard/{entitySlug}/{id}`
308
+ - Delete: `/dashboard/{entitySlug}`
309
+
310
+ ### Custom Revalidation
311
+
312
+ ```typescript
313
+ await createEntity('products', data, {
314
+ revalidatePaths: ['/dashboard/overview', '/public/catalog'],
315
+ revalidateTags: ['product-count', 'catalog'],
316
+ })
317
+ ```
318
+
319
+ ### Redirect After Mutation
320
+
321
+ ```typescript
322
+ await deleteEntity('products', id, {
323
+ redirectTo: '/dashboard/products',
324
+ })
325
+ // Note: redirect() throws NEXT_REDIRECT - action won't return data
326
+ ```
327
+
328
+ ## Form Integration
329
+
330
+ ### With React Hook Form
331
+
332
+ ```typescript
333
+ 'use client'
334
+
335
+ function ProductForm() {
336
+ const form = useForm()
337
+
338
+ async function onSubmit(data) {
339
+ const result = await createEntity('products', data)
340
+ if (result.success) {
341
+ router.push(`/products/${result.data.id}`)
342
+ } else {
343
+ form.setError('root', { message: result.error })
344
+ }
345
+ }
346
+
347
+ return <form onSubmit={form.handleSubmit(onSubmit)}>...</form>
348
+ }
349
+ ```
350
+
351
+ ### With Native Forms
352
+
353
+ ```typescript
354
+ 'use client'
355
+
356
+ function ProfileForm() {
357
+ async function handleAction(formData: FormData) {
358
+ const result = await updateProfile({
359
+ firstName: formData.get('firstName') as string,
360
+ lastName: formData.get('lastName') as string,
361
+ })
362
+ // Handle result
363
+ }
364
+
365
+ return (
366
+ <form action={handleAction}>
367
+ <input name="firstName" />
368
+ <input name="lastName" />
369
+ <button type="submit">Save</button>
370
+ </form>
371
+ )
372
+ }
373
+ ```
374
+
375
+ ## Creating New Server Actions
376
+
377
+ ### Template
378
+
379
+ ```typescript
380
+ // core/lib/actions/[domain].actions.ts
381
+ 'use server'
382
+
383
+ import { revalidatePath } from 'next/cache'
384
+ import { headers } from 'next/headers'
385
+ import { getTypedSession } from '../auth'
386
+ import type { EntityActionResult, EntityActionVoidResult } from './types'
387
+
388
+ export async function myAction(data: MyInput): Promise<EntityActionResult<MyOutput>> {
389
+ try {
390
+ // 1. Get auth context
391
+ const headersList = await headers()
392
+ const session = await getTypedSession(headersList)
393
+ if (!session?.user?.id) {
394
+ return { success: false, error: 'Authentication required' }
395
+ }
396
+ const userId = session.user.id
397
+
398
+ // 2. Validate input
399
+ if (!data.requiredField) {
400
+ return { success: false, error: 'Required field is missing' }
401
+ }
402
+
403
+ // 3. Check permissions (if needed)
404
+ // const hasPermission = await checkPermission(userId, teamId, 'resource.action')
405
+
406
+ // 4. Execute business logic via Service
407
+ const result = await MyService.doSomething(userId, data)
408
+
409
+ // 5. Revalidate caches
410
+ revalidatePath('/dashboard/relevant-path')
411
+
412
+ return { success: true, data: result }
413
+ } catch (error) {
414
+ console.error('[myAction] Error:', error)
415
+ return {
416
+ success: false,
417
+ error: error instanceof Error ? error.message : 'Unknown error',
418
+ }
419
+ }
420
+ }
421
+ ```
422
+
423
+ ### Checklist for New Actions
424
+
425
+ - [ ] File marked with `'use server'` at top
426
+ - [ ] Auth obtained from session (not parameters)
427
+ - [ ] Input validation before service calls
428
+ - [ ] Permission checks where needed
429
+ - [ ] Business logic delegated to Services
430
+ - [ ] `revalidatePath` called for affected routes
431
+ - [ ] Error handling with try/catch
432
+ - [ ] Proper return type (`EntityActionResult` or `EntityActionVoidResult`)
433
+ - [ ] Export from `index.ts`
434
+
435
+ ## Testing Server Actions
436
+
437
+ ```typescript
438
+ // tests/jest/lib/actions/my.actions.test.ts
439
+
440
+ import { myAction } from '@/core/lib/actions/my.actions'
441
+
442
+ // Mock dependencies
443
+ jest.mock('@/core/lib/auth', () => ({
444
+ getTypedSession: jest.fn(),
445
+ }))
446
+
447
+ jest.mock('next/cache', () => ({
448
+ revalidatePath: jest.fn(),
449
+ }))
450
+
451
+ jest.mock('next/headers', () => ({
452
+ headers: jest.fn().mockReturnValue(new Headers()),
453
+ }))
454
+
455
+ describe('myAction', () => {
456
+ beforeEach(() => {
457
+ jest.clearAllMocks()
458
+ // Setup authenticated user
459
+ const { getTypedSession } = require('@/core/lib/auth')
460
+ getTypedSession.mockResolvedValue({
461
+ user: { id: 'user-123' },
462
+ })
463
+ })
464
+
465
+ it('succeeds with valid data', async () => {
466
+ const result = await myAction({ name: 'Test' })
467
+ expect(result.success).toBe(true)
468
+ })
469
+
470
+ it('fails when not authenticated', async () => {
471
+ const { getTypedSession } = require('@/core/lib/auth')
472
+ getTypedSession.mockResolvedValue(null)
473
+
474
+ const result = await myAction({ name: 'Test' })
475
+ expect(result.success).toBe(false)
476
+ expect(result.error).toBe('Authentication required')
477
+ })
478
+ })
479
+ ```
480
+
481
+ ## Performance Considerations
482
+
483
+ 1. **Prefer Server Components for reads** - Server Actions are for mutations
484
+ 2. **Batch operations when possible** - Use `deleteEntities` instead of multiple `deleteEntity`
485
+ 3. **Minimal revalidation** - Only revalidate affected paths
486
+ 4. **Early validation** - Fail fast before expensive operations
487
+
488
+ ## Related Skills
489
+
490
+ - `service-layer` - Business logic implementation
491
+ - `tanstack-query` - Optimistic updates and caching
492
+ - `react-patterns` - Form and component patterns
493
+ - `zod-validation` - Input validation schemas