@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,482 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: entity-api
|
|
3
|
+
description: |
|
|
4
|
+
Dynamic entity API patterns for CRUD operations.
|
|
5
|
+
Covers entity resolution, query parameters, response formats, child entities, and metadata.
|
|
6
|
+
Use this skill when consuming entity APIs or understanding dynamic endpoint behavior.
|
|
7
|
+
allowed-tools: Read, Glob, Grep
|
|
8
|
+
version: 1.0.0
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Entity API Skill
|
|
12
|
+
|
|
13
|
+
Patterns for consuming the dynamic entity API system.
|
|
14
|
+
|
|
15
|
+
## Architecture Overview
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
app/api/v1/
|
|
19
|
+
├── [entity]/route.ts # LIST (GET), CREATE (POST)
|
|
20
|
+
├── [entity]/[id]/route.ts # READ (GET), UPDATE (PATCH), DELETE
|
|
21
|
+
├── [entity]/[id]/child/[childType]/route.ts # Child LIST/CREATE
|
|
22
|
+
└── [entity]/[id]/child/[childType]/[childId]/route.ts # Child UPDATE/DELETE
|
|
23
|
+
|
|
24
|
+
core/lib/api/entity/
|
|
25
|
+
├── generic-handler.ts # CRUD handlers
|
|
26
|
+
├── resolver.ts # Entity resolution
|
|
27
|
+
└── helpers.ts # Metadata, response formatting
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## When to Use This Skill
|
|
31
|
+
|
|
32
|
+
- Consuming entity endpoints in frontend code
|
|
33
|
+
- Understanding API response formats
|
|
34
|
+
- Working with query parameters (filtering, pagination, search)
|
|
35
|
+
- Implementing child entity operations
|
|
36
|
+
- Working with metadata (metas) system
|
|
37
|
+
|
|
38
|
+
## Entity Resolution Order
|
|
39
|
+
|
|
40
|
+
When a request hits `/api/v1/{entity}`:
|
|
41
|
+
|
|
42
|
+
1. **Extract slug** - `/api/v1/products` → `products`
|
|
43
|
+
2. **Check core path** - Skip if: users, api-keys, auth, system, health, internal, admin, debug
|
|
44
|
+
3. **Registry lookup** - `entityRegistry.getBySlug('products')`
|
|
45
|
+
4. **Custom override check** - Look for `app/api/v1/(contents)/products/route.ts`
|
|
46
|
+
5. **Return resolution** - `{ entityConfig, hasCustomOverride, isValidEntity }`
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
// If custom override exists, generic handler is skipped
|
|
50
|
+
if (existsSync('app/api/v1/(contents)/products/route.ts')) {
|
|
51
|
+
return { hasCustomOverride: true, isValidEntity: false }
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Query Parameters
|
|
56
|
+
|
|
57
|
+
### Pagination
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
GET /api/v1/tasks?page=1&limit=10
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Field Selection
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
GET /api/v1/tasks?fields=id,name,slug
|
|
67
|
+
GET /api/v1/tasks?fields=status&distinct=true # Distinct values
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Multiple IDs
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
GET /api/v1/tasks?ids=id1,id2,id3
|
|
74
|
+
GET /api/v1/tasks?ids=id1&ids=id2 # Alternative syntax
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Filtering (Field-Based)
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
GET /api/v1/tasks?status=published
|
|
81
|
+
GET /api/v1/tasks?status=draft,published # OR logic
|
|
82
|
+
GET /api/v1/tasks?status=draft&priority=high # AND logic
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Search
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
GET /api/v1/tasks?search=keyword # Searches: name, title, slug, content
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Date Range
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
GET /api/v1/tasks?dateField=createdAt&from=2025-01-01&to=2025-12-31
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Taxonomy Filtering
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
GET /api/v1/tasks?taxonomyId=tax-123&taxonomyType=category
|
|
101
|
+
GET /api/v1/tasks?categoryId=tax-123 # Legacy convenience
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Metadata
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
GET /api/v1/tasks?metas=all # Include all metadata
|
|
108
|
+
GET /api/v1/tasks?metas=key1,key2,key3 # Specific keys only
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Child Entities
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
GET /api/v1/clients/123?child=all # Include all children
|
|
115
|
+
GET /api/v1/clients/123?child=audiences,products # Specific types
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Sorting
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
GET /api/v1/tasks?sortBy=createdAt&sortOrder=DESC
|
|
122
|
+
GET /api/v1/tasks?sortBy=name&sortOrder=ASC
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Response Formats
|
|
126
|
+
|
|
127
|
+
### List Success (200)
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
{
|
|
131
|
+
success: true,
|
|
132
|
+
data: [
|
|
133
|
+
{ id: "1", name: "Task 1", status: "active", createdAt: "2025-01-01T..." },
|
|
134
|
+
{ id: "2", name: "Task 2", status: "done", createdAt: "2025-01-02T..." }
|
|
135
|
+
],
|
|
136
|
+
info: {
|
|
137
|
+
timestamp: "2025-12-30T...",
|
|
138
|
+
total: 42,
|
|
139
|
+
page: 1,
|
|
140
|
+
limit: 10,
|
|
141
|
+
totalPages: 5,
|
|
142
|
+
hasNextPage: true,
|
|
143
|
+
hasPrevPage: false
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Single Entity Success (200)
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
{
|
|
152
|
+
success: true,
|
|
153
|
+
data: {
|
|
154
|
+
id: "1",
|
|
155
|
+
name: "Task 1",
|
|
156
|
+
status: "active",
|
|
157
|
+
createdAt: "2025-01-01T...",
|
|
158
|
+
updatedAt: "2025-01-01T..."
|
|
159
|
+
},
|
|
160
|
+
info: {
|
|
161
|
+
timestamp: "2025-12-30T..."
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Create Success (201)
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
{
|
|
170
|
+
success: true,
|
|
171
|
+
data: {
|
|
172
|
+
id: "newly-created-id",
|
|
173
|
+
name: "New Task",
|
|
174
|
+
// ... all fields
|
|
175
|
+
},
|
|
176
|
+
info: {
|
|
177
|
+
timestamp: "2025-12-30T..."
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Error Response
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
{
|
|
186
|
+
success: false,
|
|
187
|
+
error: "Entity not found",
|
|
188
|
+
code: "NOT_FOUND",
|
|
189
|
+
details: { entityType: "tasks", id: "invalid-id" },
|
|
190
|
+
info: {
|
|
191
|
+
timestamp: "2025-12-30T..."
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### With Metadata
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
{
|
|
200
|
+
success: true,
|
|
201
|
+
data: {
|
|
202
|
+
id: "1",
|
|
203
|
+
name: "Task 1",
|
|
204
|
+
metas: {
|
|
205
|
+
seo_title: "Custom Title",
|
|
206
|
+
seo_description: "Meta description",
|
|
207
|
+
custom_key: { nested: "value" }
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
info: { ... }
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### With Children
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
{
|
|
218
|
+
success: true,
|
|
219
|
+
data: {
|
|
220
|
+
id: "client-123",
|
|
221
|
+
name: "Acme Corp",
|
|
222
|
+
child: {
|
|
223
|
+
audiences: [
|
|
224
|
+
{ id: "aud-1", name: "Enterprise", parentId: "client-123" },
|
|
225
|
+
{ id: "aud-2", name: "SMB", parentId: "client-123" }
|
|
226
|
+
],
|
|
227
|
+
products: [
|
|
228
|
+
{ id: "prod-1", name: "Product A", parentId: "client-123" }
|
|
229
|
+
]
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
info: { ... }
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Child Entities
|
|
237
|
+
|
|
238
|
+
### List Child Entities
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
GET /api/v1/clients/{parentId}/child/audiences
|
|
242
|
+
GET /api/v1/clients/{parentId}/child/audiences?page=1&limit=20
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Create Child Entity
|
|
246
|
+
|
|
247
|
+
```
|
|
248
|
+
POST /api/v1/clients/{parentId}/child/audiences
|
|
249
|
+
Content-Type: application/json
|
|
250
|
+
|
|
251
|
+
{
|
|
252
|
+
"name": "New Audience",
|
|
253
|
+
"description": "Target audience description",
|
|
254
|
+
"status": "active"
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Response includes `parentId`:
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
{
|
|
262
|
+
success: true,
|
|
263
|
+
data: {
|
|
264
|
+
id: "aud-xyz",
|
|
265
|
+
parentId: "client-123", // Automatically set
|
|
266
|
+
name: "New Audience",
|
|
267
|
+
// ...
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Update Child Entity
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
PATCH /api/v1/clients/{parentId}/child/audiences/{childId}
|
|
276
|
+
Content-Type: application/json
|
|
277
|
+
|
|
278
|
+
{
|
|
279
|
+
"name": "Updated Name"
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Delete Child Entity
|
|
284
|
+
|
|
285
|
+
```
|
|
286
|
+
DELETE /api/v1/clients/{parentId}/child/audiences/{childId}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Metadata System
|
|
290
|
+
|
|
291
|
+
### Reading Metadata
|
|
292
|
+
|
|
293
|
+
```typescript
|
|
294
|
+
// Include all metas
|
|
295
|
+
const response = await fetch('/api/v1/tasks/123?metas=all')
|
|
296
|
+
|
|
297
|
+
// Include specific metas
|
|
298
|
+
const response = await fetch('/api/v1/tasks/123?metas=seo_title,color_label')
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Writing Metadata
|
|
302
|
+
|
|
303
|
+
Include `metas` in request body:
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
// Create with metas
|
|
307
|
+
await fetch('/api/v1/tasks', {
|
|
308
|
+
method: 'POST',
|
|
309
|
+
body: JSON.stringify({
|
|
310
|
+
name: 'Task Name',
|
|
311
|
+
status: 'active',
|
|
312
|
+
metas: {
|
|
313
|
+
seo_title: 'Custom SEO Title',
|
|
314
|
+
custom_field: { nested: 'value' }
|
|
315
|
+
}
|
|
316
|
+
})
|
|
317
|
+
})
|
|
318
|
+
|
|
319
|
+
// Update metas (merge behavior)
|
|
320
|
+
await fetch('/api/v1/tasks/123', {
|
|
321
|
+
method: 'PATCH',
|
|
322
|
+
body: JSON.stringify({
|
|
323
|
+
metas: {
|
|
324
|
+
seo_title: 'Updated Title' // Other metas preserved
|
|
325
|
+
}
|
|
326
|
+
})
|
|
327
|
+
})
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**Metadata Behavior:**
|
|
331
|
+
|
|
332
|
+
- Stored separately from entity data
|
|
333
|
+
- Security inherited from parent entity via RLS
|
|
334
|
+
- Objects are merged, primitive types are replaced
|
|
335
|
+
- Lazy loaded only when requested
|
|
336
|
+
|
|
337
|
+
## Authentication
|
|
338
|
+
|
|
339
|
+
### Required Headers
|
|
340
|
+
|
|
341
|
+
```typescript
|
|
342
|
+
// Team context (REQUIRED for team entities)
|
|
343
|
+
headers: {
|
|
344
|
+
'x-team-id': 'team-uuid'
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// API key auth (optional)
|
|
348
|
+
headers: {
|
|
349
|
+
'Authorization': 'Bearer sk_...',
|
|
350
|
+
// OR
|
|
351
|
+
'x-api-key': 'sk_...'
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Builder source (enables blocks field)
|
|
355
|
+
headers: {
|
|
356
|
+
'x-builder-source': 'true'
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Scope Requirements
|
|
361
|
+
|
|
362
|
+
| Operation | Required Scope |
|
|
363
|
+
|-----------|---------------|
|
|
364
|
+
| GET (list/read) | `{entity}:read` |
|
|
365
|
+
| POST (create) | `{entity}:write` |
|
|
366
|
+
| PATCH (update) | `{entity}:write` |
|
|
367
|
+
| DELETE | `{entity}:delete` or `{entity}:write` |
|
|
368
|
+
|
|
369
|
+
## Error Codes
|
|
370
|
+
|
|
371
|
+
| Code | HTTP Status | Description |
|
|
372
|
+
|------|-------------|-------------|
|
|
373
|
+
| `AUTHENTICATION_REQUIRED` | 401 | No auth credentials |
|
|
374
|
+
| `INVALID_API_KEY` | 401 | API key invalid/expired |
|
|
375
|
+
| `TEAM_CONTEXT_REQUIRED` | 400 | Missing x-team-id header |
|
|
376
|
+
| `INSUFFICIENT_PERMISSIONS` | 403 | User lacks required scope |
|
|
377
|
+
| `NOT_FOUND` | 404 | Entity doesn't exist |
|
|
378
|
+
| `VALIDATION_ERROR` | 400 | Request body validation failed |
|
|
379
|
+
| `CONFLICT` | 409 | Duplicate or constraint violation |
|
|
380
|
+
|
|
381
|
+
## Frontend Integration
|
|
382
|
+
|
|
383
|
+
### TanStack Query Example
|
|
384
|
+
|
|
385
|
+
```typescript
|
|
386
|
+
import { useQuery } from '@tanstack/react-query'
|
|
387
|
+
|
|
388
|
+
function useTaskList(filters: TaskFilters) {
|
|
389
|
+
return useQuery({
|
|
390
|
+
queryKey: ['entity', 'tasks', filters],
|
|
391
|
+
queryFn: async () => {
|
|
392
|
+
const params = new URLSearchParams({
|
|
393
|
+
page: String(filters.page),
|
|
394
|
+
limit: String(filters.limit),
|
|
395
|
+
...(filters.status && { status: filters.status }),
|
|
396
|
+
...(filters.search && { search: filters.search }),
|
|
397
|
+
})
|
|
398
|
+
|
|
399
|
+
const response = await fetch(`/api/v1/tasks?${params}`)
|
|
400
|
+
if (!response.ok) throw new Error('Failed to fetch')
|
|
401
|
+
return response.json()
|
|
402
|
+
},
|
|
403
|
+
})
|
|
404
|
+
}
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Mutation Example
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
import { useMutation, useQueryClient } from '@tanstack/react-query'
|
|
411
|
+
|
|
412
|
+
function useCreateTask() {
|
|
413
|
+
const queryClient = useQueryClient()
|
|
414
|
+
|
|
415
|
+
return useMutation({
|
|
416
|
+
mutationFn: async (data: CreateTaskData) => {
|
|
417
|
+
const response = await fetch('/api/v1/tasks', {
|
|
418
|
+
method: 'POST',
|
|
419
|
+
headers: { 'Content-Type': 'application/json' },
|
|
420
|
+
body: JSON.stringify(data),
|
|
421
|
+
})
|
|
422
|
+
if (!response.ok) throw new Error('Failed to create')
|
|
423
|
+
return response.json()
|
|
424
|
+
},
|
|
425
|
+
onSuccess: () => {
|
|
426
|
+
queryClient.invalidateQueries({ queryKey: ['entity', 'tasks'] })
|
|
427
|
+
},
|
|
428
|
+
})
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
## Anti-Patterns
|
|
433
|
+
|
|
434
|
+
```typescript
|
|
435
|
+
// NEVER: Hardcode entity names in URLs
|
|
436
|
+
const endpoint = '/api/v1/tasks'
|
|
437
|
+
|
|
438
|
+
// CORRECT: Use entity config
|
|
439
|
+
const endpoint = `/api/v1/${entityConfig.slug}`
|
|
440
|
+
|
|
441
|
+
// NEVER: Skip team context for team entities
|
|
442
|
+
fetch('/api/v1/tasks') // Missing x-team-id!
|
|
443
|
+
|
|
444
|
+
// CORRECT: Always include team context
|
|
445
|
+
fetch('/api/v1/tasks', {
|
|
446
|
+
headers: { 'x-team-id': teamId }
|
|
447
|
+
})
|
|
448
|
+
|
|
449
|
+
// NEVER: Assume all entities have same fields
|
|
450
|
+
if (entity.status === 'active') { ... } // Not all entities have status!
|
|
451
|
+
|
|
452
|
+
// CORRECT: Check entity config for available fields
|
|
453
|
+
const hasStatus = entityConfig.fields.some(f => f.name === 'status')
|
|
454
|
+
|
|
455
|
+
// NEVER: Ignore pagination info
|
|
456
|
+
const allTasks = response.data // Could be truncated!
|
|
457
|
+
|
|
458
|
+
// CORRECT: Handle pagination
|
|
459
|
+
const { data, info } = response
|
|
460
|
+
if (info.hasNextPage) {
|
|
461
|
+
// Load more or show pagination
|
|
462
|
+
}
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
## Checklist
|
|
466
|
+
|
|
467
|
+
Before finalizing entity API integration:
|
|
468
|
+
|
|
469
|
+
- [ ] Include `x-team-id` header for team entities
|
|
470
|
+
- [ ] Handle pagination (`info.hasNextPage`, `info.totalPages`)
|
|
471
|
+
- [ ] Use correct query parameters for filtering
|
|
472
|
+
- [ ] Check `success` field in response
|
|
473
|
+
- [ ] Handle error responses with appropriate UI feedback
|
|
474
|
+
- [ ] Use `metas` parameter only when metadata needed
|
|
475
|
+
- [ ] Invalidate queries after mutations
|
|
476
|
+
- [ ] Use proper HTTP methods (GET, POST, PATCH, DELETE)
|
|
477
|
+
|
|
478
|
+
## Related Skills
|
|
479
|
+
|
|
480
|
+
- `entity-system` - Entity definition (config, fields, types)
|
|
481
|
+
- `tanstack-query` - Data fetching patterns
|
|
482
|
+
- `better-auth` - Authentication patterns
|