@nextsparkjs/ai-workflow 0.1.0-beta.86

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 (271) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +86 -0
  3. package/claude/_docs/workflows-optimizations.md +359 -0
  4. package/claude/agents/api-tester.md +636 -0
  5. package/claude/agents/architecture-supervisor.md +1381 -0
  6. package/claude/agents/backend-developer.md +1021 -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 +1460 -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 +1291 -0
  15. package/claude/agents/frontend-developer.md +1259 -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 +971 -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 +373 -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 +681 -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 +512 -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 +455 -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/close.md +146 -0
  77. package/claude/commands/session/commit.md +174 -0
  78. package/claude/commands/session/db-entity.md +206 -0
  79. package/claude/commands/session/db-fix.md +212 -0
  80. package/claude/commands/session/db-sample.md +206 -0
  81. package/claude/commands/session/demo.md +178 -0
  82. package/claude/commands/session/doc-bdd.md +207 -0
  83. package/claude/commands/session/doc-feature.md +218 -0
  84. package/claude/commands/session/doc-read.md +225 -0
  85. package/claude/commands/session/execute.md +204 -0
  86. package/claude/commands/session/explain.md +202 -0
  87. package/claude/commands/session/fix-bug.md +210 -0
  88. package/claude/commands/session/fix-build.md +182 -0
  89. package/claude/commands/session/fix-test.md +189 -0
  90. package/claude/commands/session/pending.md +232 -0
  91. package/claude/commands/session/refine.md +188 -0
  92. package/claude/commands/session/resume.md +192 -0
  93. package/claude/commands/session/review.md +192 -0
  94. package/claude/commands/session/scope-change.md +181 -0
  95. package/claude/commands/session/start-blocks.md +347 -0
  96. package/claude/commands/session/start.md +476 -0
  97. package/claude/commands/session/status.md +169 -0
  98. package/claude/commands/session/test-fix.md +221 -0
  99. package/claude/commands/session/test-run.md +203 -0
  100. package/claude/commands/session/test-write.md +242 -0
  101. package/claude/commands/session/validate.md +162 -0
  102. package/claude/config/context.json +54 -0
  103. package/claude/config/github.json +69 -0
  104. package/claude/config/github.schema.json +106 -0
  105. package/claude/config/team.json +46 -0
  106. package/claude/config/team.schema.json +106 -0
  107. package/claude/config/workspace.json +49 -0
  108. package/claude/config/workspace.schema.json +64 -0
  109. package/claude/scripts/.gitkeep +0 -0
  110. package/claude/sessions/.gitkeep +0 -0
  111. package/claude/skills/README.md +228 -0
  112. package/claude/skills/accessibility/SKILL.md +573 -0
  113. package/claude/skills/api-bypass-layers/SKILL.md +550 -0
  114. package/claude/skills/asana-integration/SKILL.md +499 -0
  115. package/claude/skills/better-auth/SKILL.md +666 -0
  116. package/claude/skills/billing-subscriptions/SKILL.md +660 -0
  117. package/claude/skills/block-decision-matrix/SKILL.md +359 -0
  118. package/claude/skills/clickup-integration/SKILL.md +434 -0
  119. package/claude/skills/core-theme-responsibilities/SKILL.md +485 -0
  120. package/claude/skills/create-plugin/SKILL.md +425 -0
  121. package/claude/skills/create-theme/SKILL.md +331 -0
  122. package/claude/skills/cypress-api/SKILL.md +511 -0
  123. package/claude/skills/cypress-api/scripts/generate-api-controller.py +329 -0
  124. package/claude/skills/cypress-api/scripts/generate-api-test.py +930 -0
  125. package/claude/skills/cypress-e2e/SKILL.md +526 -0
  126. package/claude/skills/cypress-e2e/scripts/extract-selectors.py +383 -0
  127. package/claude/skills/cypress-e2e/scripts/generate-uat-test.py +788 -0
  128. package/claude/skills/cypress-selectors/SKILL.md +309 -0
  129. package/claude/skills/cypress-selectors/scripts/extract-missing.py +243 -0
  130. package/claude/skills/cypress-selectors/scripts/generate-block-selectors.py +283 -0
  131. package/claude/skills/cypress-selectors/scripts/validate-selectors.py +145 -0
  132. package/claude/skills/database-migrations/SKILL.md +335 -0
  133. package/claude/skills/database-migrations/scripts/generate-sample-data.py +284 -0
  134. package/claude/skills/database-migrations/scripts/validate-migration.py +323 -0
  135. package/claude/skills/design-system/SKILL.md +682 -0
  136. package/claude/skills/documentation/SKILL.md +540 -0
  137. package/claude/skills/entity-api/SKILL.md +482 -0
  138. package/claude/skills/entity-system/SKILL.md +635 -0
  139. package/claude/skills/entity-system/scripts/generate-child-migration.py +298 -0
  140. package/claude/skills/entity-system/scripts/generate-metas-migration.py +233 -0
  141. package/claude/skills/entity-system/scripts/generate-migration.py +382 -0
  142. package/claude/skills/entity-system/scripts/generate-sample-data.py +418 -0
  143. package/claude/skills/entity-system/scripts/scaffold-entity.py +661 -0
  144. package/claude/skills/github/SKILL.md +467 -0
  145. package/claude/skills/i18n-nextintl/SKILL.md +302 -0
  146. package/claude/skills/i18n-nextintl/scripts/add-translation.py +243 -0
  147. package/claude/skills/i18n-nextintl/scripts/extract-hardcoded.py +246 -0
  148. package/claude/skills/i18n-nextintl/scripts/validate-translations.py +260 -0
  149. package/claude/skills/impact-analysis/SKILL.md +203 -0
  150. package/claude/skills/jest-unit/SKILL.md +306 -0
  151. package/claude/skills/jest-unit/references/component-testing.md +371 -0
  152. package/claude/skills/jest-unit/references/mocking-patterns.md +380 -0
  153. package/claude/skills/jest-unit/references/service-hook-testing.md +454 -0
  154. package/claude/skills/jira-integration/SKILL.md +539 -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 +483 -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 +677 -0
  228. package/claude/skills/registry-system/SKILL.md +331 -0
  229. package/claude/skills/scheduled-actions/SKILL.md +431 -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 +479 -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 +34 -0
  270. package/scripts/setup.mjs +282 -0
  271. package/scripts/sync.mjs +209 -0
@@ -0,0 +1,431 @@
1
+ ---
2
+ name: scheduled-actions
3
+ description: |
4
+ Scheduled Actions system for background task processing in this application.
5
+ Covers action scheduling, handler creation, webhook configuration, and cron processing.
6
+ Use this skill when creating, debugging, or configuring scheduled actions.
7
+ allowed-tools: Read, Glob, Grep, Bash, Write, Edit
8
+ version: 1.0.0
9
+ ---
10
+
11
+ # Scheduled Actions Skill
12
+
13
+ Patterns for background task processing and webhook systems.
14
+
15
+ ## Architecture Overview
16
+
17
+ ```
18
+ SCHEDULED ACTIONS SYSTEM:
19
+
20
+ Core Layer (core/lib/scheduled-actions/):
21
+ ├── scheduler.ts # scheduleAction(), scheduleRecurringAction()
22
+ ├── processor.ts # Cron processing logic
23
+ ├── registry.ts # Handler registration
24
+ └── types.ts # TypeScript interfaces
25
+
26
+ Theme Layer (contents/themes/{theme}/lib/scheduled-actions/):
27
+ ├── index.ts # Handler initialization + registerAllHandlers()
28
+ ├── entity-hooks.ts # Entity event → action mapping
29
+ └── handlers/ # Handler implementations
30
+ ├── webhook.ts # Webhook sender
31
+ ├── email.ts # Email sender (if configured)
32
+ └── {custom}.ts # Custom handlers
33
+
34
+ Configuration (contents/themes/{theme}/config/app.config.ts):
35
+ └── scheduledActions: {
36
+ enabled: true,
37
+ deduplication: { windowSeconds: 10 },
38
+ webhooks: { endpoints: {...}, patterns: {...} }
39
+ }
40
+
41
+ Flow:
42
+ Entity Event → Entity Hook → scheduleAction() → DB Table → Cron → Handler → Result
43
+ ```
44
+
45
+ > **📍 Context-Aware Paths:** Core layer (`core/lib/scheduled-actions/`) is read-only in consumer projects.
46
+ > Create handlers in `contents/themes/{theme}/lib/scheduled-actions/handlers/`.
47
+ > See `core-theme-responsibilities` skill for complete rules.
48
+
49
+ ## When to Use This Skill
50
+
51
+ - Creating new action handlers
52
+ - Setting up webhooks for entity events
53
+ - Debugging pending/failed actions
54
+ - Configuring deduplication or batching
55
+ - Understanding the scheduled actions flow
56
+
57
+ ## Key Files Reference
58
+
59
+ | File | Purpose |
60
+ |------|---------|
61
+ | `core/lib/scheduled-actions/scheduler.ts` | `scheduleAction()`, `scheduleRecurringAction()` |
62
+ | `core/lib/scheduled-actions/processor.ts` | Cron processing logic |
63
+ | `core/lib/scheduled-actions/registry.ts` | Handler registration |
64
+ | `contents/themes/{theme}/lib/scheduled-actions/index.ts` | Handler initialization |
65
+ | `contents/themes/{theme}/lib/scheduled-actions/handlers/` | Handler implementations |
66
+ | `contents/themes/{theme}/config/app.config.ts` | Configuration section |
67
+
68
+ ## Creating Action Handlers
69
+
70
+ ### Handler Template
71
+
72
+ ```typescript
73
+ // contents/themes/{theme}/lib/scheduled-actions/handlers/{name}.ts
74
+ import { registerScheduledAction } from '@/core/lib/scheduled-actions'
75
+
76
+ interface MyPayload {
77
+ entityId: string
78
+ teamId: string
79
+ data: Record<string, unknown>
80
+ }
81
+
82
+ export function registerMyHandler() {
83
+ registerScheduledAction('my-action:type', async (payload, action) => {
84
+ const data = payload as MyPayload
85
+
86
+ try {
87
+ // Implementation logic
88
+ await processMyAction(data)
89
+
90
+ return {
91
+ success: true,
92
+ message: 'Action completed successfully'
93
+ }
94
+ } catch (error) {
95
+ return {
96
+ success: false,
97
+ message: error instanceof Error ? error.message : 'Unknown error'
98
+ }
99
+ }
100
+ })
101
+ }
102
+ ```
103
+
104
+ ### Registering Handler
105
+
106
+ ```typescript
107
+ // contents/themes/{theme}/lib/scheduled-actions/index.ts
108
+ import { registerMyHandler } from './handlers/my-handler'
109
+
110
+ let initialized = false
111
+
112
+ export function registerAllHandlers() {
113
+ if (initialized) return
114
+ initialized = true
115
+
116
+ // Register all handlers
117
+ registerWebhookHandler()
118
+ registerMyHandler() // Add new handler here
119
+ }
120
+ ```
121
+
122
+ ### Handler Types
123
+
124
+ | Type | Description | Use Case |
125
+ |------|-------------|----------|
126
+ | `webhook` | Send HTTP POST to external endpoint | Integrations, notifications |
127
+ | `email` | Send transactional emails | User notifications |
128
+ | `data-processor` | Process/transform data | ETL, aggregations |
129
+ | `cleanup` | Clean up old records | Maintenance tasks |
130
+
131
+ ## Webhook Configuration
132
+
133
+ ### Entity Hook Pattern
134
+
135
+ ```typescript
136
+ // contents/themes/{theme}/lib/scheduled-actions/entity-hooks.ts
137
+ import { scheduleAction } from '@/core/lib/scheduled-actions'
138
+ import { hookSystem } from '@/core/lib/hooks'
139
+
140
+ export function registerEntityHooks() {
141
+ // Hook for task creation
142
+ hookSystem.register('entity.tasks.created', async ({ entity, teamId }) => {
143
+ await scheduleAction({
144
+ type: 'webhook:send',
145
+ payload: {
146
+ endpointKey: 'tasks',
147
+ event: 'task.created',
148
+ data: entity
149
+ },
150
+ scheduledFor: new Date(),
151
+ teamId
152
+ })
153
+ })
154
+
155
+ // Hook for task updates
156
+ hookSystem.register('entity.tasks.updated', async ({ entity, teamId }) => {
157
+ await scheduleAction({
158
+ type: 'webhook:send',
159
+ payload: {
160
+ endpointKey: 'tasks',
161
+ event: 'task.updated',
162
+ data: entity
163
+ },
164
+ scheduledFor: new Date(),
165
+ teamId
166
+ })
167
+ })
168
+ }
169
+ ```
170
+
171
+ ### Webhook Configuration in app.config.ts
172
+
173
+ ```typescript
174
+ // contents/themes/{theme}/config/app.config.ts
175
+ export const appConfig = {
176
+ // ... other config
177
+
178
+ scheduledActions: {
179
+ enabled: true,
180
+
181
+ deduplication: {
182
+ windowSeconds: 10 // 0 to disable
183
+ },
184
+
185
+ webhooks: {
186
+ endpoints: {
187
+ // Key -> Environment variable mapping
188
+ tasks: 'WEBHOOK_URL_TASKS',
189
+ subscriptions: 'WEBHOOK_URL_SUBSCRIPTIONS',
190
+ default: 'WEBHOOK_URL_DEFAULT'
191
+ },
192
+ patterns: {
193
+ // Event pattern -> Endpoint key
194
+ 'task.*': 'tasks',
195
+ 'subscription.*': 'subscriptions',
196
+ '*': 'default' // Fallback
197
+ }
198
+ }
199
+ }
200
+ }
201
+ ```
202
+
203
+ ### Environment Variables
204
+
205
+ ```env
206
+ # Required for cron processing
207
+ CRON_SECRET=your-secure-secret-min-32-chars
208
+
209
+ # Webhook URLs (one per endpoint key)
210
+ WEBHOOK_URL_TASKS=https://your-webhook-url/tasks
211
+ WEBHOOK_URL_SUBSCRIPTIONS=https://your-webhook-url/subs
212
+ WEBHOOK_URL_DEFAULT=https://fallback-url
213
+ ```
214
+
215
+ ## Scheduling Actions
216
+
217
+ ### Immediate Action
218
+
219
+ ```typescript
220
+ import { scheduleAction } from '@/core/lib/scheduled-actions'
221
+
222
+ await scheduleAction({
223
+ type: 'my-action:type',
224
+ payload: {
225
+ entityId: 'abc123',
226
+ data: { field: 'value' }
227
+ },
228
+ scheduledFor: new Date(), // Now
229
+ teamId: 'team_123'
230
+ })
231
+ ```
232
+
233
+ ### Delayed Action
234
+
235
+ ```typescript
236
+ await scheduleAction({
237
+ type: 'reminder:send',
238
+ payload: { userId: 'user_123', message: 'Follow up' },
239
+ scheduledFor: new Date(Date.now() + 24 * 60 * 60 * 1000), // Tomorrow
240
+ teamId: 'team_123'
241
+ })
242
+ ```
243
+
244
+ ### Recurring Action
245
+
246
+ ```typescript
247
+ import { scheduleRecurringAction } from '@/core/lib/scheduled-actions'
248
+
249
+ await scheduleRecurringAction({
250
+ type: 'report:generate',
251
+ payload: { reportType: 'daily-summary' },
252
+ cron: '0 9 * * *', // Every day at 9 AM
253
+ teamId: 'team_123'
254
+ })
255
+ ```
256
+
257
+ ## Debugging Actions
258
+
259
+ ### Check Pending Actions
260
+
261
+ ```bash
262
+ curl "http://localhost:5173/api/v1/devtools/scheduled-actions?status=pending" \
263
+ -H "Authorization: Bearer API_KEY"
264
+ ```
265
+
266
+ ### Check Failed Actions
267
+
268
+ ```bash
269
+ curl "http://localhost:5173/api/v1/devtools/scheduled-actions?status=failed" \
270
+ -H "Authorization: Bearer API_KEY"
271
+ ```
272
+
273
+ ### Manually Trigger Processing
274
+
275
+ ```bash
276
+ curl "http://localhost:5173/api/v1/cron/process" \
277
+ -H "x-cron-secret: CRON_SECRET"
278
+ ```
279
+
280
+ ### Console Log Patterns
281
+
282
+ ```
283
+ [ScheduledActions] Processing 5 pending actions
284
+ [ScheduledActions] Action abc123 completed successfully
285
+ [ScheduledActions] Action xyz789 failed: Connection timeout
286
+ [ScheduledActions] Handler not found for type: unknown:type
287
+ ```
288
+
289
+ ## Deduplication
290
+
291
+ ### Purpose
292
+
293
+ Prevents duplicate actions when the same event fires multiple times in quick succession.
294
+
295
+ ### Configuration
296
+
297
+ ```typescript
298
+ scheduledActions: {
299
+ deduplication: {
300
+ windowSeconds: 10 // Actions with same type+payload within 10s are deduplicated
301
+ }
302
+ }
303
+ ```
304
+
305
+ ### Behavior
306
+
307
+ 1. When action is scheduled, system creates hash of `type + payload`
308
+ 2. If action with same hash exists within window, new action is skipped
309
+ 3. Window is reset when action is processed
310
+
311
+ ### Disabling
312
+
313
+ Set `windowSeconds: 0` to disable deduplication entirely.
314
+
315
+ ## API Endpoints
316
+
317
+ | Endpoint | Method | Auth | Purpose |
318
+ |----------|--------|------|---------|
319
+ | `/api/v1/cron/process` | POST | x-cron-secret | Trigger action processing |
320
+ | `/api/v1/devtools/scheduled-actions` | GET | API Key | List actions (debug) |
321
+ | `/api/v1/devtools/scheduled-actions/:id` | DELETE | API Key | Delete action (debug) |
322
+
323
+ ## Troubleshooting
324
+
325
+ | Issue | Cause | Solution |
326
+ |-------|-------|----------|
327
+ | Handler not found | Not registered | Add to `index.ts` `registerAllHandlers()` |
328
+ | Webhook not sent | Pattern mismatch | Check patterns in `app.config.ts` |
329
+ | Duplicate actions | Dedup disabled | Set `windowSeconds > 0` |
330
+ | Actions stuck pending | Cron not running | Verify cron service and `CRON_SECRET` |
331
+ | 401 on cron endpoint | Wrong header | Use `x-cron-secret` (not `Authorization`) |
332
+ | Env variable undefined | Not set | Add to `.env` and restart server |
333
+
334
+ ## Anti-Patterns
335
+
336
+ ```typescript
337
+ // NEVER: Process actions synchronously in API routes
338
+ // This blocks the response
339
+ app.post('/api/entity', async (req, res) => {
340
+ const entity = await createEntity(req.body)
341
+ await sendWebhook(entity) // WRONG - blocks response
342
+ res.json(entity)
343
+ })
344
+
345
+ // CORRECT: Schedule action for async processing
346
+ app.post('/api/entity', async (req, res) => {
347
+ const entity = await createEntity(req.body)
348
+ await scheduleAction({
349
+ type: 'webhook:send',
350
+ payload: { entity },
351
+ scheduledFor: new Date(),
352
+ teamId: req.teamId
353
+ })
354
+ res.json(entity)
355
+ })
356
+
357
+ // NEVER: Store sensitive data in payload
358
+ await scheduleAction({
359
+ type: 'email:send',
360
+ payload: {
361
+ password: 'secret123' // WRONG - stored in DB
362
+ }
363
+ })
364
+
365
+ // CORRECT: Store references only
366
+ await scheduleAction({
367
+ type: 'email:send',
368
+ payload: {
369
+ userId: 'user_123', // Lookup at processing time
370
+ templateKey: 'password-reset'
371
+ }
372
+ })
373
+
374
+ // NEVER: Forget to handle errors in handlers
375
+ registerScheduledAction('my:action', async (payload) => {
376
+ await riskyOperation(payload) // WRONG - unhandled rejection
377
+ })
378
+
379
+ // CORRECT: Always return success/failure
380
+ registerScheduledAction('my:action', async (payload) => {
381
+ try {
382
+ await riskyOperation(payload)
383
+ return { success: true, message: 'Done' }
384
+ } catch (error) {
385
+ return { success: false, message: error.message }
386
+ }
387
+ })
388
+ ```
389
+
390
+ ## Checklist
391
+
392
+ ### Creating New Handler
393
+
394
+ - [ ] Handler file created in `handlers/` directory
395
+ - [ ] Handler registered in `index.ts` `registerAllHandlers()`
396
+ - [ ] Handler returns `{ success, message }` object
397
+ - [ ] Error handling with try/catch
398
+ - [ ] Registry rebuilt: `node core/scripts/build/registry.mjs`
399
+
400
+ ### Adding Webhook
401
+
402
+ - [ ] Entity hook registered in `entity-hooks.ts`
403
+ - [ ] Endpoint key added to `webhooks.endpoints` config
404
+ - [ ] Pattern added to `webhooks.patterns` config
405
+ - [ ] Environment variable added to `.env`
406
+ - [ ] Environment variable documented in `.env.example`
407
+
408
+ ### Debugging
409
+
410
+ - [ ] Check if `scheduledActions.enabled: true` in config
411
+ - [ ] Verify `CRON_SECRET` is set
412
+ - [ ] Check handler is registered (console log on startup)
413
+ - [ ] Query devtools endpoint for action status
414
+ - [ ] Check console for `[ScheduledActions]` logs
415
+
416
+ ## Related Skills
417
+
418
+ - `entity-api` - API endpoints that trigger entity hooks
419
+ - `service-layer` - Service patterns for action processing
420
+ - `nextjs-api-development` - Cron endpoint patterns
421
+ - `database-migrations` - scheduled_actions table structure
422
+
423
+ ## Documentation
424
+
425
+ Full documentation: `core/docs/20-scheduled-actions/`
426
+ - `01-overview.md` - System overview
427
+ - `02-scheduling.md` - Scheduling patterns
428
+ - `03-handlers.md` - Handler development
429
+ - `04-webhooks.md` - Webhook configuration
430
+ - `05-cron.md` - Cron processing
431
+ - `06-deduplication.md` - Deduplication system