@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.
- package/LICENSE +21 -0
- package/README.md +115 -0
- package/claude/_docs/workflows-optimizations.md +359 -0
- package/claude/agents/api-tester.md +634 -0
- package/claude/agents/architecture-supervisor.md +1351 -0
- package/claude/agents/backend-developer.md +997 -0
- package/claude/agents/backend-validator.md +417 -0
- package/claude/agents/bdd-docs-writer.md +737 -0
- package/claude/agents/block-developer.md +677 -0
- package/claude/agents/code-reviewer.md +1432 -0
- package/claude/agents/db-developer.md +721 -0
- package/claude/agents/db-validator.md +407 -0
- package/claude/agents/demo-video-generator.md +493 -0
- package/claude/agents/documentation-writer.md +1268 -0
- package/claude/agents/frontend-developer.md +1234 -0
- package/claude/agents/frontend-validator.md +777 -0
- package/claude/agents/functional-validator.md +630 -0
- package/claude/agents/mock-analyst.md +387 -0
- package/claude/agents/product-manager.md +963 -0
- package/claude/agents/qa-automation.md +1762 -0
- package/claude/agents/release-manager.md +634 -0
- package/claude/agents/selectors-translator.md +262 -0
- package/claude/agents/unit-test-writer.md +785 -0
- package/claude/agents/visual-comparator.md +329 -0
- package/claude/agents/workflow-maintainer.md +352 -0
- package/claude/commands/do/README.md +88 -0
- package/claude/commands/do/create-api.md +64 -0
- package/claude/commands/do/create-entity.md +66 -0
- package/claude/commands/do/create-migration.md +64 -0
- package/claude/commands/do/create-plugin.md +56 -0
- package/claude/commands/do/create-theme.md +70 -0
- package/claude/commands/do/mock-data.md +67 -0
- package/claude/commands/do/reset-db.md +71 -0
- package/claude/commands/do/setup-scheduled-action.md +75 -0
- package/claude/commands/do/sync-code-review.md +117 -0
- package/claude/commands/do/update-selectors.md +112 -0
- package/claude/commands/do/use-skills.md +90 -0
- package/claude/commands/do/validate-blocks.md +69 -0
- package/claude/commands/how-to/README.md +261 -0
- package/claude/commands/how-to/add-metadata.md +692 -0
- package/claude/commands/how-to/add-taxonomies.md +806 -0
- package/claude/commands/how-to/add-translations.md +571 -0
- package/claude/commands/how-to/create-api.md +577 -0
- package/claude/commands/how-to/create-block.md +575 -0
- package/claude/commands/how-to/create-child-entities.md +771 -0
- package/claude/commands/how-to/create-entity.md +597 -0
- package/claude/commands/how-to/create-migrations.md +605 -0
- package/claude/commands/how-to/create-plugin.md +654 -0
- package/claude/commands/how-to/customize-app.md +481 -0
- package/claude/commands/how-to/customize-dashboard.md +553 -0
- package/claude/commands/how-to/customize-theme.md +438 -0
- package/claude/commands/how-to/define-features-flows.md +632 -0
- package/claude/commands/how-to/deploy.md +507 -0
- package/claude/commands/how-to/handle-file-uploads.md +746 -0
- package/claude/commands/how-to/implement-search.md +1001 -0
- package/claude/commands/how-to/install-plugins.md +352 -0
- package/claude/commands/how-to/manage-test-coverage.md +984 -0
- package/claude/commands/how-to/run-tests.md +400 -0
- package/claude/commands/how-to/set-app-languages.md +601 -0
- package/claude/commands/how-to/set-plans-and-permissions.md +575 -0
- package/claude/commands/how-to/set-scheduled-actions.md +527 -0
- package/claude/commands/how-to/set-user-roles-and-permissions.md +550 -0
- package/claude/commands/how-to/setup-authentication.md +388 -0
- package/claude/commands/how-to/setup-claude-code.md +440 -0
- package/claude/commands/how-to/setup-database.md +274 -0
- package/claude/commands/how-to/setup-email-providers.md +598 -0
- package/claude/commands/how-to/setup-mobile-dev.md +627 -0
- package/claude/commands/how-to/start.md +500 -0
- package/claude/commands/how-to/use-devtools.md +639 -0
- package/claude/commands/how-to/use-superadmin.md +622 -0
- package/claude/commands/session/README.md +193 -0
- package/claude/commands/session/block-create.md +190 -0
- package/claude/commands/session/block-list.md +203 -0
- package/claude/commands/session/block-update.md +192 -0
- package/claude/commands/session/block-validate.md +218 -0
- package/claude/commands/session/changelog.md +115 -0
- package/claude/commands/session/close.md +225 -0
- package/claude/commands/session/commit.md +174 -0
- package/claude/commands/session/db-entity.md +206 -0
- package/claude/commands/session/db-fix.md +212 -0
- package/claude/commands/session/db-sample.md +206 -0
- package/claude/commands/session/demo.md +178 -0
- package/claude/commands/session/doc-bdd.md +207 -0
- package/claude/commands/session/doc-feature.md +218 -0
- package/claude/commands/session/doc-read.md +225 -0
- package/claude/commands/session/execute.md +204 -0
- package/claude/commands/session/explain.md +202 -0
- package/claude/commands/session/fix-bug.md +210 -0
- package/claude/commands/session/fix-build.md +182 -0
- package/claude/commands/session/fix-test.md +189 -0
- package/claude/commands/session/pending.md +232 -0
- package/claude/commands/session/refine.md +188 -0
- package/claude/commands/session/resume.md +192 -0
- package/claude/commands/session/review.md +192 -0
- package/claude/commands/session/scope-change.md +181 -0
- package/claude/commands/session/start-blocks.md +347 -0
- package/claude/commands/session/start.md +604 -0
- package/claude/commands/session/status.md +169 -0
- package/claude/commands/session/test-fix.md +221 -0
- package/claude/commands/session/test-run.md +203 -0
- package/claude/commands/session/test-write.md +242 -0
- package/claude/commands/session/validate.md +162 -0
- package/claude/config/context.json +40 -0
- package/claude/config/github.json +69 -0
- package/claude/config/github.schema.json +106 -0
- package/claude/config/team.json +46 -0
- package/claude/config/team.schema.json +106 -0
- package/claude/config/workspace.json +43 -0
- package/claude/config/workspace.schema.json +75 -0
- package/claude/skills/README.md +228 -0
- package/claude/skills/accessibility/SKILL.md +573 -0
- package/claude/skills/api-bypass-layers/SKILL.md +550 -0
- package/claude/skills/asana-integration/SKILL.md +499 -0
- package/claude/skills/better-auth/SKILL.md +666 -0
- package/claude/skills/billing-subscriptions/SKILL.md +660 -0
- package/claude/skills/block-decision-matrix/SKILL.md +359 -0
- package/claude/skills/clickup-integration/SKILL.md +434 -0
- package/claude/skills/core-theme-responsibilities/SKILL.md +485 -0
- package/claude/skills/create-plugin/SKILL.md +425 -0
- package/claude/skills/create-theme/SKILL.md +331 -0
- package/claude/skills/cypress-api/SKILL.md +511 -0
- package/claude/skills/cypress-api/scripts/generate-api-controller.py +329 -0
- package/claude/skills/cypress-api/scripts/generate-api-test.py +930 -0
- package/claude/skills/cypress-e2e/SKILL.md +526 -0
- package/claude/skills/cypress-e2e/scripts/extract-selectors.py +383 -0
- package/claude/skills/cypress-e2e/scripts/generate-uat-test.py +788 -0
- package/claude/skills/cypress-selectors/SKILL.md +309 -0
- package/claude/skills/cypress-selectors/scripts/extract-missing.py +243 -0
- package/claude/skills/cypress-selectors/scripts/generate-block-selectors.py +283 -0
- package/claude/skills/cypress-selectors/scripts/validate-selectors.py +145 -0
- package/claude/skills/database-migrations/SKILL.md +335 -0
- package/claude/skills/database-migrations/scripts/generate-sample-data.py +284 -0
- package/claude/skills/database-migrations/scripts/validate-migration.py +323 -0
- package/claude/skills/design-system/SKILL.md +682 -0
- package/claude/skills/documentation/SKILL.md +540 -0
- package/claude/skills/entity-api/SKILL.md +482 -0
- package/claude/skills/entity-system/SKILL.md +635 -0
- package/claude/skills/entity-system/scripts/generate-child-migration.py +298 -0
- package/claude/skills/entity-system/scripts/generate-metas-migration.py +233 -0
- package/claude/skills/entity-system/scripts/generate-migration.py +382 -0
- package/claude/skills/entity-system/scripts/generate-sample-data.py +418 -0
- package/claude/skills/entity-system/scripts/scaffold-entity.py +661 -0
- package/claude/skills/github/SKILL.md +467 -0
- package/claude/skills/i18n-nextintl/SKILL.md +302 -0
- package/claude/skills/i18n-nextintl/scripts/add-translation.py +243 -0
- package/claude/skills/i18n-nextintl/scripts/extract-hardcoded.py +246 -0
- package/claude/skills/i18n-nextintl/scripts/validate-translations.py +260 -0
- package/claude/skills/impact-analysis/SKILL.md +203 -0
- package/claude/skills/jest-unit/SKILL.md +306 -0
- package/claude/skills/jest-unit/references/component-testing.md +371 -0
- package/claude/skills/jest-unit/references/mocking-patterns.md +380 -0
- package/claude/skills/jest-unit/references/service-hook-testing.md +454 -0
- package/claude/skills/jira-integration/SKILL.md +539 -0
- package/claude/skills/media-library/SKILL.md +743 -0
- package/claude/skills/mock-analysis/SKILL.md +276 -0
- package/claude/skills/monorepo-architecture/SKILL.md +162 -0
- package/claude/skills/nextjs-api-development/SKILL.md +364 -0
- package/claude/skills/nextjs-api-development/scripts/generate-crud-tests.py +456 -0
- package/claude/skills/nextjs-api-development/scripts/scaffold-endpoint.py +481 -0
- package/claude/skills/nextjs-api-development/scripts/validate-api.py +283 -0
- package/claude/skills/notion-integration/SKILL.md +641 -0
- package/claude/skills/npm-development-workflow/SKILL.md +480 -0
- package/claude/skills/page-builder-blocks/SKILL.md +530 -0
- package/claude/skills/page-builder-blocks/scripts/scaffold-block.py +444 -0
- package/claude/skills/permissions-system/SKILL.md +619 -0
- package/claude/skills/plugins/SKILL.md +340 -0
- package/claude/skills/plugins/references/plugin-templates.md +414 -0
- package/claude/skills/plugins/references/plugin-testing.md +353 -0
- package/claude/skills/plugins/references/plugin-types.md +198 -0
- package/claude/skills/plugins/scripts/scaffold-plugin.py +443 -0
- package/claude/skills/pom-patterns/SKILL.md +452 -0
- package/claude/skills/pom-patterns/scripts/generate-pom.py +392 -0
- package/claude/skills/rate-limiting/SKILL.md +342 -0
- package/claude/skills/react-best-practices/AGENTS.md +2410 -0
- package/claude/skills/react-best-practices/README.md +123 -0
- package/claude/skills/react-best-practices/SKILL.md +125 -0
- package/claude/skills/react-best-practices/metadata.json +15 -0
- package/claude/skills/react-best-practices/rules/_sections.md +46 -0
- package/claude/skills/react-best-practices/rules/_template.md +28 -0
- package/claude/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/claude/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
- package/claude/skills/react-best-practices/rules/async-api-routes.md +38 -0
- package/claude/skills/react-best-practices/rules/async-defer-await.md +80 -0
- package/claude/skills/react-best-practices/rules/async-dependencies.md +36 -0
- package/claude/skills/react-best-practices/rules/async-parallel.md +28 -0
- package/claude/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/claude/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/claude/skills/react-best-practices/rules/bundle-conditional.md +31 -0
- package/claude/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/claude/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/claude/skills/react-best-practices/rules/bundle-preload.md +50 -0
- package/claude/skills/react-best-practices/rules/client-event-listeners.md +74 -0
- package/claude/skills/react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/claude/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/claude/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/claude/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
- package/claude/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/claude/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/claude/skills/react-best-practices/rules/js-cache-storage.md +70 -0
- package/claude/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/claude/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/claude/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/claude/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/claude/skills/react-best-practices/rules/js-length-check-first.md +49 -0
- package/claude/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/claude/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/claude/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/claude/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/claude/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/claude/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/claude/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/claude/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/claude/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/claude/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/claude/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/claude/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/claude/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/claude/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/claude/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/claude/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/claude/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/claude/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/claude/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/claude/skills/react-best-practices/rules/server-cache-react.md +76 -0
- package/claude/skills/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/claude/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/claude/skills/react-patterns/SKILL.md +688 -0
- package/claude/skills/registry-system/SKILL.md +331 -0
- package/claude/skills/scheduled-actions/SKILL.md +671 -0
- package/claude/skills/scope-enforcement/SKILL.md +542 -0
- package/claude/skills/scope-enforcement/scripts/validate-scope.py +357 -0
- package/claude/skills/server-actions/SKILL.md +493 -0
- package/claude/skills/service-layer/SKILL.md +587 -0
- package/claude/skills/session-management/SKILL.md +266 -0
- package/claude/skills/session-management/scripts/create-session.py +166 -0
- package/claude/skills/session-management/scripts/iteration-close.sh +105 -0
- package/claude/skills/session-management/scripts/iteration-init.sh +180 -0
- package/claude/skills/session-management/scripts/session-archive.sh +87 -0
- package/claude/skills/session-management/scripts/session-close.sh +133 -0
- package/claude/skills/session-management/scripts/session-init.sh +225 -0
- package/claude/skills/session-management/scripts/session-list.sh +163 -0
- package/claude/skills/session-management/scripts/split-plan.sh +116 -0
- package/claude/skills/shadcn-components/SKILL.md +586 -0
- package/claude/skills/shadcn-theming/SKILL.md +446 -0
- package/claude/skills/suspense-loading/SKILL.md +280 -0
- package/claude/skills/tailwind-theming/SKILL.md +507 -0
- package/claude/skills/tanstack-query/SKILL.md +608 -0
- package/claude/skills/test-coverage/SKILL.md +239 -0
- package/claude/skills/web-design-guidelines/SKILL.md +39 -0
- package/claude/skills/zod-validation/SKILL.md +537 -0
- package/claude/templates/blocks/progress.md +86 -0
- package/claude/templates/iteration/changes.md +61 -0
- package/claude/templates/iteration/progress.md +55 -0
- package/claude/templates/log.md +31 -0
- package/claude/templates/story/context.md +77 -0
- package/claude/templates/story/pendings.md +37 -0
- package/claude/templates/story/plan.md +299 -0
- package/claude/templates/story/requirements.md +109 -0
- package/claude/templates/story/scope.json +10 -0
- package/claude/templates/story/tests.md +91 -0
- package/claude/templates/task/progress.md +58 -0
- package/claude/templates/task/requirements.md +54 -0
- package/claude/workflows/README.md +154 -0
- package/claude/workflows/blocks.md +614 -0
- package/claude/workflows/story.md +1207 -0
- package/claude/workflows/task.md +927 -0
- package/claude/workflows/tweak.md +527 -0
- package/cursor/.gitkeep +0 -0
- package/package.json +35 -0
- package/scripts/postinstall.mjs +198 -0
- package/scripts/setup.mjs +282 -0
- package/scripts/sync.mjs +209 -0
|
@@ -0,0 +1,597 @@
|
|
|
1
|
+
# /how-to:create-entity
|
|
2
|
+
|
|
3
|
+
Interactive guide to create entities with full CRUD in NextSpark.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Required Skills
|
|
8
|
+
|
|
9
|
+
Before executing, these skills provide deeper context:
|
|
10
|
+
- `.claude/skills/entity-system/SKILL.md` - Entity configuration and registry
|
|
11
|
+
- `.claude/skills/database-migrations/SKILL.md` - PostgreSQL migrations with RLS
|
|
12
|
+
- `.claude/skills/entity-api/SKILL.md` - Dynamic API patterns
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Syntax
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
/how-to:create-entity
|
|
20
|
+
/how-to:create-entity [entity-name]
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Behavior
|
|
26
|
+
|
|
27
|
+
Guides the user through creating a complete entity with database migration, automatic CRUD API, and dashboard integration.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Tutorial Structure
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
STEPS OVERVIEW (6 steps)
|
|
35
|
+
|
|
36
|
+
Step 1: Understanding the Entity System
|
|
37
|
+
βββ How entities work in NextSpark
|
|
38
|
+
|
|
39
|
+
Step 2: Create Entity Configuration
|
|
40
|
+
βββ Define entity config with fields
|
|
41
|
+
|
|
42
|
+
Step 3: Create Database Migration
|
|
43
|
+
βββ SQL with RLS policies
|
|
44
|
+
|
|
45
|
+
Step 4: Generate Sample Data
|
|
46
|
+
βββ Create realistic test data
|
|
47
|
+
|
|
48
|
+
Step 5: Add Translations
|
|
49
|
+
βββ i18n for labels and messages
|
|
50
|
+
|
|
51
|
+
Step 6: Test Your Entity
|
|
52
|
+
βββ Verify CRUD operations
|
|
53
|
+
|
|
54
|
+
Bonus: Customize the Dashboard UI
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Step 1: Understanding Entities
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
63
|
+
π HOW TO: CREATE AN ENTITY
|
|
64
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
65
|
+
|
|
66
|
+
STEP 1 OF 6: Understanding the Entity System
|
|
67
|
+
|
|
68
|
+
In NextSpark, an **entity** is a data type that automatically gets:
|
|
69
|
+
|
|
70
|
+
β
Database table with RLS policies
|
|
71
|
+
β
Full CRUD API endpoints
|
|
72
|
+
β
Dashboard UI (list, create, edit, delete)
|
|
73
|
+
β
Form validation with Zod
|
|
74
|
+
β
i18n support
|
|
75
|
+
β
Permissions integration
|
|
76
|
+
|
|
77
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
78
|
+
|
|
79
|
+
π Entity Files Structure:
|
|
80
|
+
|
|
81
|
+
contents/themes/{theme}/entities/{entity}/
|
|
82
|
+
βββ config.ts # Entity configuration (REQUIRED)
|
|
83
|
+
βββ messages/
|
|
84
|
+
β βββ en.json # English translations
|
|
85
|
+
β βββ es.json # Spanish translations
|
|
86
|
+
βββ migrations/
|
|
87
|
+
βββ 001_{entity}.sql # Database migration
|
|
88
|
+
|
|
89
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
90
|
+
|
|
91
|
+
π What you get automatically:
|
|
92
|
+
|
|
93
|
+
β’ GET /api/v1/entities/{entity} β List all
|
|
94
|
+
β’ GET /api/v1/entities/{entity}/{id} β Get one
|
|
95
|
+
β’ POST /api/v1/entities/{entity} β Create
|
|
96
|
+
β’ PATCH /api/v1/entities/{entity}/{id} β Update
|
|
97
|
+
β’ DELETE /api/v1/entities/{entity}/{id} β Delete
|
|
98
|
+
|
|
99
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
100
|
+
|
|
101
|
+
What entity would you like to create?
|
|
102
|
+
|
|
103
|
+
Example: "products", "tasks", "invoices"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Step 2: Create Entity Configuration
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
112
|
+
STEP 2 OF 6: Create Entity Configuration
|
|
113
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
114
|
+
|
|
115
|
+
The config.ts file defines your entity's structure:
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**π Entity Config Example:**
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
// contents/themes/default/entities/products/config.ts
|
|
122
|
+
import type { EntityConfig } from '@/core/types/entity'
|
|
123
|
+
import { z } from 'zod'
|
|
124
|
+
import { Package } from 'lucide-react'
|
|
125
|
+
|
|
126
|
+
export const productsEntity: EntityConfig = {
|
|
127
|
+
// Identity
|
|
128
|
+
name: 'products',
|
|
129
|
+
slug: 'products',
|
|
130
|
+
table: 'products',
|
|
131
|
+
|
|
132
|
+
// Display
|
|
133
|
+
displayName: 'entities.products.name',
|
|
134
|
+
displayNamePlural: 'entities.products.namePlural',
|
|
135
|
+
icon: Package,
|
|
136
|
+
|
|
137
|
+
// Schema (Zod validation)
|
|
138
|
+
schema: z.object({
|
|
139
|
+
name: z.string().min(1).max(255),
|
|
140
|
+
description: z.string().max(1000).optional(),
|
|
141
|
+
price: z.number().min(0),
|
|
142
|
+
sku: z.string().min(1).max(50),
|
|
143
|
+
categoryId: z.string().uuid().optional(),
|
|
144
|
+
isActive: z.boolean().default(true),
|
|
145
|
+
}),
|
|
146
|
+
|
|
147
|
+
// Field definitions for UI
|
|
148
|
+
fields: {
|
|
149
|
+
name: {
|
|
150
|
+
type: 'text',
|
|
151
|
+
label: 'entities.products.fields.name',
|
|
152
|
+
required: true,
|
|
153
|
+
searchable: true,
|
|
154
|
+
sortable: true,
|
|
155
|
+
},
|
|
156
|
+
description: {
|
|
157
|
+
type: 'textarea',
|
|
158
|
+
label: 'entities.products.fields.description',
|
|
159
|
+
},
|
|
160
|
+
price: {
|
|
161
|
+
type: 'number',
|
|
162
|
+
label: 'entities.products.fields.price',
|
|
163
|
+
format: 'currency',
|
|
164
|
+
sortable: true,
|
|
165
|
+
},
|
|
166
|
+
sku: {
|
|
167
|
+
type: 'text',
|
|
168
|
+
label: 'entities.products.fields.sku',
|
|
169
|
+
searchable: true,
|
|
170
|
+
},
|
|
171
|
+
categoryId: {
|
|
172
|
+
type: 'relation',
|
|
173
|
+
label: 'entities.products.fields.category',
|
|
174
|
+
relation: {
|
|
175
|
+
entity: 'categories',
|
|
176
|
+
displayField: 'name',
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
isActive: {
|
|
180
|
+
type: 'boolean',
|
|
181
|
+
label: 'entities.products.fields.isActive',
|
|
182
|
+
default: true,
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
|
|
186
|
+
// List view configuration
|
|
187
|
+
listView: {
|
|
188
|
+
columns: ['name', 'sku', 'price', 'isActive'],
|
|
189
|
+
defaultSort: { field: 'name', direction: 'asc' },
|
|
190
|
+
searchableFields: ['name', 'sku'],
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
// Dashboard settings
|
|
194
|
+
dashboard: {
|
|
195
|
+
enabled: true,
|
|
196
|
+
showInMenu: true,
|
|
197
|
+
menuOrder: 10,
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
// Permissions (uses entity name)
|
|
201
|
+
// Automatically creates: products.read, products.create, etc.
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export default productsEntity
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
**π Field Types Available:**
|
|
208
|
+
|
|
209
|
+
- `text` - Single line text
|
|
210
|
+
- `textarea` - Multi-line text
|
|
211
|
+
- `number` - Numeric with optional format
|
|
212
|
+
- `boolean` - True/false toggle
|
|
213
|
+
- `select` - Dropdown with options
|
|
214
|
+
- `date` - Date picker
|
|
215
|
+
- `datetime` - Date and time
|
|
216
|
+
- `email` - Email with validation
|
|
217
|
+
- `url` - URL with validation
|
|
218
|
+
- `relation` - Reference to another entity
|
|
219
|
+
- `json` - JSON editor
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
223
|
+
|
|
224
|
+
What would you like to do?
|
|
225
|
+
|
|
226
|
+
[1] Continue to Step 3 (Migration)
|
|
227
|
+
[2] I have a question about config
|
|
228
|
+
[3] What field options are available?
|
|
229
|
+
[4] Let me create my entity config now
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Step 3: Create Database Migration
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
238
|
+
STEP 3 OF 6: Create Database Migration
|
|
239
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
240
|
+
|
|
241
|
+
The migration creates your database table with RLS:
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**π Migration Example:**
|
|
245
|
+
|
|
246
|
+
```sql
|
|
247
|
+
-- contents/themes/default/entities/products/migrations/001_products.sql
|
|
248
|
+
-- ============================================================================
|
|
249
|
+
-- Entity: products
|
|
250
|
+
-- Description: Products catalog for the store
|
|
251
|
+
-- ============================================================================
|
|
252
|
+
|
|
253
|
+
-- Main Table
|
|
254
|
+
CREATE TABLE IF NOT EXISTS "products" (
|
|
255
|
+
-- Primary key (UUID)
|
|
256
|
+
"id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
257
|
+
|
|
258
|
+
-- Team ownership (REQUIRED for multi-tenant)
|
|
259
|
+
"teamId" UUID NOT NULL REFERENCES "team"("id") ON DELETE CASCADE,
|
|
260
|
+
|
|
261
|
+
-- Entity fields (camelCase!)
|
|
262
|
+
"name" VARCHAR(255) NOT NULL,
|
|
263
|
+
"description" TEXT,
|
|
264
|
+
"price" DECIMAL(10,2) NOT NULL DEFAULT 0,
|
|
265
|
+
"sku" VARCHAR(50) NOT NULL,
|
|
266
|
+
"categoryId" UUID REFERENCES "categories"("id") ON DELETE SET NULL,
|
|
267
|
+
"isActive" BOOLEAN DEFAULT true,
|
|
268
|
+
|
|
269
|
+
-- Audit fields
|
|
270
|
+
"createdAt" TIMESTAMPTZ DEFAULT NOW(),
|
|
271
|
+
"updatedAt" TIMESTAMPTZ DEFAULT NOW(),
|
|
272
|
+
"createdBy" UUID REFERENCES "user"("id") ON DELETE SET NULL,
|
|
273
|
+
"updatedBy" UUID REFERENCES "user"("id") ON DELETE SET NULL
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
-- Indexes
|
|
277
|
+
CREATE INDEX IF NOT EXISTS "idx_products_teamId" ON "products"("teamId");
|
|
278
|
+
CREATE INDEX IF NOT EXISTS "idx_products_categoryId" ON "products"("categoryId");
|
|
279
|
+
CREATE INDEX IF NOT EXISTS "idx_products_sku" ON "products"("sku");
|
|
280
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "idx_products_team_sku"
|
|
281
|
+
ON "products"("teamId", "sku");
|
|
282
|
+
|
|
283
|
+
-- ============================================================================
|
|
284
|
+
-- Row Level Security
|
|
285
|
+
-- ============================================================================
|
|
286
|
+
|
|
287
|
+
ALTER TABLE "products" ENABLE ROW LEVEL SECURITY;
|
|
288
|
+
|
|
289
|
+
-- Team members can view their team's products
|
|
290
|
+
CREATE POLICY "products_select_policy" ON "products"
|
|
291
|
+
FOR SELECT
|
|
292
|
+
USING (
|
|
293
|
+
"teamId" IN (
|
|
294
|
+
SELECT "teamId" FROM "teamMembers"
|
|
295
|
+
WHERE "userId" = current_setting('app.user_id', true)::UUID
|
|
296
|
+
)
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
-- Team members can insert products for their team
|
|
300
|
+
CREATE POLICY "products_insert_policy" ON "products"
|
|
301
|
+
FOR INSERT
|
|
302
|
+
WITH CHECK (
|
|
303
|
+
"teamId" IN (
|
|
304
|
+
SELECT "teamId" FROM "teamMembers"
|
|
305
|
+
WHERE "userId" = current_setting('app.user_id', true)::UUID
|
|
306
|
+
)
|
|
307
|
+
);
|
|
308
|
+
|
|
309
|
+
-- Team members can update their team's products
|
|
310
|
+
CREATE POLICY "products_update_policy" ON "products"
|
|
311
|
+
FOR UPDATE
|
|
312
|
+
USING (
|
|
313
|
+
"teamId" IN (
|
|
314
|
+
SELECT "teamId" FROM "teamMembers"
|
|
315
|
+
WHERE "userId" = current_setting('app.user_id', true)::UUID
|
|
316
|
+
)
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
-- Team members can delete their team's products
|
|
320
|
+
CREATE POLICY "products_delete_policy" ON "products"
|
|
321
|
+
FOR DELETE
|
|
322
|
+
USING (
|
|
323
|
+
"teamId" IN (
|
|
324
|
+
SELECT "teamId" FROM "teamMembers"
|
|
325
|
+
WHERE "userId" = current_setting('app.user_id', true)::UUID
|
|
326
|
+
)
|
|
327
|
+
);
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**β οΈ CRITICAL Rules:**
|
|
331
|
+
|
|
332
|
+
- ALL column names use camelCase (not snake_case)
|
|
333
|
+
- TIMESTAMPTZ for dates (not TIMESTAMP)
|
|
334
|
+
- Always include teamId for multi-tenant
|
|
335
|
+
- Always add RLS policies
|
|
336
|
+
|
|
337
|
+
```
|
|
338
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
339
|
+
|
|
340
|
+
What would you like to do?
|
|
341
|
+
|
|
342
|
+
[1] Continue to Step 4 (Sample Data)
|
|
343
|
+
[2] I have a question about migrations
|
|
344
|
+
[3] How do I add a metadata table?
|
|
345
|
+
[4] Let me create my migration now
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## Step 4: Generate Sample Data
|
|
351
|
+
|
|
352
|
+
```
|
|
353
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
354
|
+
STEP 4 OF 6: Generate Sample Data
|
|
355
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
356
|
+
|
|
357
|
+
Add sample data for development and testing:
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
**π Sample Data Migration:**
|
|
361
|
+
|
|
362
|
+
```sql
|
|
363
|
+
-- contents/themes/default/entities/products/migrations/002_products_sample.sql
|
|
364
|
+
-- ============================================================================
|
|
365
|
+
-- Sample Data: products
|
|
366
|
+
-- ============================================================================
|
|
367
|
+
|
|
368
|
+
-- Get reference IDs (assuming default team and user exist)
|
|
369
|
+
DO $$
|
|
370
|
+
DECLARE
|
|
371
|
+
v_team_id UUID;
|
|
372
|
+
v_user_id UUID;
|
|
373
|
+
BEGIN
|
|
374
|
+
SELECT id INTO v_team_id FROM "team" LIMIT 1;
|
|
375
|
+
SELECT id INTO v_user_id FROM "user" LIMIT 1;
|
|
376
|
+
|
|
377
|
+
-- Insert sample products
|
|
378
|
+
INSERT INTO "products" (
|
|
379
|
+
"teamId", "name", "description", "price", "sku", "isActive",
|
|
380
|
+
"createdBy", "updatedBy"
|
|
381
|
+
) VALUES
|
|
382
|
+
(v_team_id, 'Wireless Headphones', 'Premium noise-canceling headphones', 299.99, 'WH-001', true, v_user_id, v_user_id),
|
|
383
|
+
(v_team_id, 'Mechanical Keyboard', 'RGB mechanical gaming keyboard', 149.99, 'KB-001', true, v_user_id, v_user_id),
|
|
384
|
+
(v_team_id, 'USB-C Hub', '7-in-1 USB-C dock for laptops', 79.99, 'HUB-001', true, v_user_id, v_user_id),
|
|
385
|
+
(v_team_id, 'Webcam HD', '1080p HD webcam with microphone', 89.99, 'WC-001', true, v_user_id, v_user_id),
|
|
386
|
+
(v_team_id, 'Monitor Stand', 'Adjustable monitor stand with USB', 59.99, 'MS-001', true, v_user_id, v_user_id),
|
|
387
|
+
(v_team_id, 'Laptop Sleeve', 'Protective sleeve for 15" laptops', 29.99, 'LS-001', true, v_user_id, v_user_id),
|
|
388
|
+
(v_team_id, 'Wireless Mouse', 'Ergonomic wireless mouse', 49.99, 'WM-001', true, v_user_id, v_user_id),
|
|
389
|
+
(v_team_id, 'Desk Lamp', 'LED desk lamp with adjustable brightness', 39.99, 'DL-001', false, v_user_id, v_user_id),
|
|
390
|
+
(v_team_id, 'Cable Organizer', 'Desktop cable management system', 19.99, 'CO-001', true, v_user_id, v_user_id),
|
|
391
|
+
(v_team_id, 'Screen Cleaner Kit', 'Microfiber cloth and cleaning solution', 14.99, 'SC-001', true, v_user_id, v_user_id)
|
|
392
|
+
ON CONFLICT DO NOTHING;
|
|
393
|
+
END $$;
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
**π Sample Data Guidelines:**
|
|
397
|
+
|
|
398
|
+
- Use 8-12 varied records
|
|
399
|
+
- Include edge cases (inactive items)
|
|
400
|
+
- Use realistic values
|
|
401
|
+
- Reference existing users/teams
|
|
402
|
+
- Make data coherent (related items)
|
|
403
|
+
|
|
404
|
+
```
|
|
405
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
406
|
+
|
|
407
|
+
What would you like to do?
|
|
408
|
+
|
|
409
|
+
[1] Continue to Step 5 (Translations)
|
|
410
|
+
[2] I have a question about sample data
|
|
411
|
+
[3] Let me create my sample data now
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## Step 5: Add Translations
|
|
417
|
+
|
|
418
|
+
```
|
|
419
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
420
|
+
STEP 5 OF 6: Add Translations
|
|
421
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
422
|
+
|
|
423
|
+
Add i18n translations for your entity:
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
**π English Translations (en.json):**
|
|
427
|
+
|
|
428
|
+
```json
|
|
429
|
+
// contents/themes/default/entities/products/messages/en.json
|
|
430
|
+
{
|
|
431
|
+
"entities": {
|
|
432
|
+
"products": {
|
|
433
|
+
"name": "Product",
|
|
434
|
+
"namePlural": "Products",
|
|
435
|
+
"description": "Manage your product catalog",
|
|
436
|
+
|
|
437
|
+
"fields": {
|
|
438
|
+
"name": "Name",
|
|
439
|
+
"description": "Description",
|
|
440
|
+
"price": "Price",
|
|
441
|
+
"sku": "SKU",
|
|
442
|
+
"category": "Category",
|
|
443
|
+
"isActive": "Active"
|
|
444
|
+
},
|
|
445
|
+
|
|
446
|
+
"placeholders": {
|
|
447
|
+
"name": "Enter product name...",
|
|
448
|
+
"description": "Enter product description...",
|
|
449
|
+
"sku": "Enter SKU code..."
|
|
450
|
+
},
|
|
451
|
+
|
|
452
|
+
"actions": {
|
|
453
|
+
"create": "Create Product",
|
|
454
|
+
"edit": "Edit Product",
|
|
455
|
+
"delete": "Delete Product"
|
|
456
|
+
},
|
|
457
|
+
|
|
458
|
+
"messages": {
|
|
459
|
+
"created": "Product created successfully",
|
|
460
|
+
"updated": "Product updated successfully",
|
|
461
|
+
"deleted": "Product deleted successfully",
|
|
462
|
+
"confirmDelete": "Are you sure you want to delete this product?"
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
**π Spanish Translations (es.json):**
|
|
470
|
+
|
|
471
|
+
```json
|
|
472
|
+
// contents/themes/default/entities/products/messages/es.json
|
|
473
|
+
{
|
|
474
|
+
"entities": {
|
|
475
|
+
"products": {
|
|
476
|
+
"name": "Producto",
|
|
477
|
+
"namePlural": "Productos",
|
|
478
|
+
"description": "Administra tu catΓ‘logo de productos",
|
|
479
|
+
|
|
480
|
+
"fields": {
|
|
481
|
+
"name": "Nombre",
|
|
482
|
+
"description": "DescripciΓ³n",
|
|
483
|
+
"price": "Precio",
|
|
484
|
+
"sku": "SKU",
|
|
485
|
+
"category": "CategorΓa",
|
|
486
|
+
"isActive": "Activo"
|
|
487
|
+
},
|
|
488
|
+
|
|
489
|
+
"placeholders": {
|
|
490
|
+
"name": "Ingresa el nombre del producto...",
|
|
491
|
+
"description": "Ingresa la descripciΓ³n...",
|
|
492
|
+
"sku": "Ingresa el cΓ³digo SKU..."
|
|
493
|
+
},
|
|
494
|
+
|
|
495
|
+
"actions": {
|
|
496
|
+
"create": "Crear Producto",
|
|
497
|
+
"edit": "Editar Producto",
|
|
498
|
+
"delete": "Eliminar Producto"
|
|
499
|
+
},
|
|
500
|
+
|
|
501
|
+
"messages": {
|
|
502
|
+
"created": "Producto creado exitosamente",
|
|
503
|
+
"updated": "Producto actualizado exitosamente",
|
|
504
|
+
"deleted": "Producto eliminado exitosamente",
|
|
505
|
+
"confirmDelete": "ΒΏEstΓ‘s seguro de que deseas eliminar este producto?"
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
```
|
|
513
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
514
|
+
|
|
515
|
+
What would you like to do?
|
|
516
|
+
|
|
517
|
+
[1] Continue to Step 6 (Testing)
|
|
518
|
+
[2] What translations are required?
|
|
519
|
+
[3] Let me create my translations now
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
## Step 6: Test Your Entity
|
|
525
|
+
|
|
526
|
+
```
|
|
527
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
528
|
+
STEP 6 OF 6: Test Your Entity
|
|
529
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
**1οΈβ£ Run the migration:**
|
|
533
|
+
|
|
534
|
+
```bash
|
|
535
|
+
pnpm db:migrate
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
**2οΈβ£ Rebuild the entity registry:**
|
|
539
|
+
|
|
540
|
+
```bash
|
|
541
|
+
node core/scripts/build/registry.mjs
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
**3οΈβ£ Start the dev server:**
|
|
545
|
+
|
|
546
|
+
```bash
|
|
547
|
+
pnpm dev
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
**4οΈβ£ Test the API endpoints:**
|
|
551
|
+
|
|
552
|
+
```bash
|
|
553
|
+
# List all products
|
|
554
|
+
curl http://localhost:3000/api/v1/entities/products \
|
|
555
|
+
-H "Authorization: Bearer YOUR_TOKEN"
|
|
556
|
+
|
|
557
|
+
# Create a product
|
|
558
|
+
curl -X POST http://localhost:3000/api/v1/entities/products \
|
|
559
|
+
-H "Authorization: Bearer YOUR_TOKEN" \
|
|
560
|
+
-H "Content-Type: application/json" \
|
|
561
|
+
-d '{"name":"Test Product","price":99.99,"sku":"TEST-001"}'
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
**5οΈβ£ Test in the Dashboard:**
|
|
565
|
+
|
|
566
|
+
- Go to /dashboard/products
|
|
567
|
+
- Verify list view shows your sample data
|
|
568
|
+
- Test create, edit, and delete operations
|
|
569
|
+
|
|
570
|
+
```
|
|
571
|
+
βββββββββββββββββββββββββββββββββββββββββββββ
|
|
572
|
+
|
|
573
|
+
β
TUTORIAL STORY!
|
|
574
|
+
|
|
575
|
+
You've created a complete entity with:
|
|
576
|
+
β’ Database table with RLS
|
|
577
|
+
β’ Automatic CRUD API
|
|
578
|
+
β’ Dashboard integration
|
|
579
|
+
β’ Full i18n support
|
|
580
|
+
|
|
581
|
+
π Related tutorials:
|
|
582
|
+
β’ /how-to:create-migrations - Advanced migrations
|
|
583
|
+
β’ /how-to:create-api - Custom API endpoints
|
|
584
|
+
β’ /how-to:set-user-roles-and-permissions - Entity permissions
|
|
585
|
+
|
|
586
|
+
π Back to menu: /how-to:start
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
---
|
|
590
|
+
|
|
591
|
+
## Related Commands
|
|
592
|
+
|
|
593
|
+
| Command | Action |
|
|
594
|
+
|---------|--------|
|
|
595
|
+
| `/session:db:entity` | Create entity via session workflow |
|
|
596
|
+
| `/session:db:sample` | Generate sample data |
|
|
597
|
+
| `/how-to:create-migrations` | Advanced migration patterns |
|