@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,364 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nextjs-api-development
|
|
3
|
+
description: |
|
|
4
|
+
REST API development with Next.js 15 App Router.
|
|
5
|
+
Dual authentication (API Key + Session), dynamic entities, metadata system.
|
|
6
|
+
Use this skill to create endpoints, validate APIs, or understand API patterns.
|
|
7
|
+
allowed-tools: Read, Glob, Grep, Bash(python:*)
|
|
8
|
+
version: 1.1.0
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Next.js API Development Skill
|
|
12
|
+
|
|
13
|
+
Patterns and tools for REST API development with Next.js 15 App Router.
|
|
14
|
+
|
|
15
|
+
## Architecture Overview
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
app/api/v1/
|
|
19
|
+
├── [entity]/ # Dynamic CRUD (auto-generated from registry)
|
|
20
|
+
│ ├── route.ts # GET (list) / POST (create)
|
|
21
|
+
│ └── [id]/route.ts # GET (read) / PATCH (update) / DELETE
|
|
22
|
+
├── (contents)/ # Custom overrides (parentheses = not in URL)
|
|
23
|
+
│ └── tasks/ # Example: custom implementation
|
|
24
|
+
├── users/ # Core endpoints (not dynamic)
|
|
25
|
+
├── api-keys/ # API key management
|
|
26
|
+
├── auth/ # Authentication endpoints
|
|
27
|
+
├── billing/ # Billing & subscriptions
|
|
28
|
+
├── teams/ # Team management
|
|
29
|
+
└── theme/ # Theme-specific endpoints
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
> **📍 Context-Aware Paths:** Core API routes (`app/api/v1/`) are read-only in consumer projects.
|
|
33
|
+
> Create custom endpoints in `contents/themes/{theme}/app/api/` or override via `(contents)/` pattern.
|
|
34
|
+
> See `core-theme-responsibilities` skill for complete rules.
|
|
35
|
+
|
|
36
|
+
## When to Use This Skill
|
|
37
|
+
|
|
38
|
+
- Creating new API endpoints
|
|
39
|
+
- Implementing dual authentication
|
|
40
|
+
- Adding custom business logic to entities
|
|
41
|
+
- Debugging API issues
|
|
42
|
+
- Testing API endpoints
|
|
43
|
+
- Understanding API patterns
|
|
44
|
+
|
|
45
|
+
## Core Patterns
|
|
46
|
+
|
|
47
|
+
### Route Handler Pattern (MANDATORY)
|
|
48
|
+
|
|
49
|
+
All routes MUST use `withApiLogging` wrapper and `addCorsHeaders`:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { NextRequest, NextResponse } from 'next/server'
|
|
53
|
+
import { queryWithRLS, mutateWithRLS } from '@/core/lib/db'
|
|
54
|
+
import {
|
|
55
|
+
createApiResponse,
|
|
56
|
+
createApiError,
|
|
57
|
+
createPaginationMeta,
|
|
58
|
+
parsePaginationParams,
|
|
59
|
+
withApiLogging,
|
|
60
|
+
handleCorsPreflightRequest,
|
|
61
|
+
addCorsHeaders,
|
|
62
|
+
} from '@/core/lib/api/helpers'
|
|
63
|
+
import { authenticateRequest } from '@/core/lib/api/auth/dual-auth'
|
|
64
|
+
|
|
65
|
+
// Handle CORS preflight
|
|
66
|
+
export async function OPTIONS() {
|
|
67
|
+
return handleCorsPreflightRequest()
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// GET /api/v1/[endpoint] - List resources
|
|
71
|
+
export const GET = withApiLogging(async (req: NextRequest): Promise<NextResponse> => {
|
|
72
|
+
try {
|
|
73
|
+
// 1. Authenticate (API Key OR Session)
|
|
74
|
+
const authResult = await authenticateRequest(req)
|
|
75
|
+
|
|
76
|
+
if (!authResult.success) {
|
|
77
|
+
return NextResponse.json(
|
|
78
|
+
{ success: false, error: 'Authentication required', code: 'AUTHENTICATION_FAILED' },
|
|
79
|
+
{ status: 401 }
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (authResult.rateLimitResponse) {
|
|
84
|
+
return authResult.rateLimitResponse as NextResponse
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 2. Parse pagination
|
|
88
|
+
const { page, limit, offset } = parsePaginationParams(req)
|
|
89
|
+
|
|
90
|
+
// 3. Fetch data with RLS
|
|
91
|
+
const data = await queryWithRLS(
|
|
92
|
+
`SELECT * FROM "table" WHERE 1=1 ORDER BY "createdAt" DESC LIMIT $1 OFFSET $2`,
|
|
93
|
+
[limit, offset],
|
|
94
|
+
authResult.user!.id
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
// 4. Create response with pagination
|
|
98
|
+
const paginationMeta = createPaginationMeta(page, limit, total)
|
|
99
|
+
const response = createApiResponse(data, paginationMeta)
|
|
100
|
+
return addCorsHeaders(response)
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.error('[ENDPOINT] Error:', error)
|
|
103
|
+
const response = createApiError('Failed to fetch data', 500)
|
|
104
|
+
return addCorsHeaders(response)
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Response Helpers (MANDATORY)
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { createApiResponse, createApiError } from '@/core/lib/api/helpers'
|
|
113
|
+
|
|
114
|
+
// Success responses - always wrap with addCorsHeaders
|
|
115
|
+
const response = createApiResponse(data)
|
|
116
|
+
return addCorsHeaders(response)
|
|
117
|
+
|
|
118
|
+
const response = createApiResponse(data, { created: true }, 201)
|
|
119
|
+
return addCorsHeaders(response)
|
|
120
|
+
|
|
121
|
+
const response = createApiResponse(data, paginationMeta)
|
|
122
|
+
return addCorsHeaders(response)
|
|
123
|
+
|
|
124
|
+
// Error responses - always wrap with addCorsHeaders
|
|
125
|
+
const response = createApiError('Not found', 404)
|
|
126
|
+
return addCorsHeaders(response)
|
|
127
|
+
|
|
128
|
+
const response = createApiError('Validation error', 400, zodError.issues, 'VALIDATION_ERROR')
|
|
129
|
+
return addCorsHeaders(response)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Response Format
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
// Success
|
|
136
|
+
{
|
|
137
|
+
"success": true,
|
|
138
|
+
"data": { /* entity data */ },
|
|
139
|
+
"info": {
|
|
140
|
+
"timestamp": "2024-01-17T10:30:00Z",
|
|
141
|
+
"pagination": { /* if applicable */ }
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Error
|
|
146
|
+
{
|
|
147
|
+
"success": false,
|
|
148
|
+
"error": "Error message",
|
|
149
|
+
"code": "ERROR_CODE",
|
|
150
|
+
"details": { /* optional */ },
|
|
151
|
+
"info": {
|
|
152
|
+
"timestamp": "2024-01-17T10:30:00Z"
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Route Types
|
|
158
|
+
|
|
159
|
+
### 1. Dynamic Entity Routes
|
|
160
|
+
|
|
161
|
+
For standard CRUD operations. Automatically generated from EntityRegistry.
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
GET /api/v1/products → List products
|
|
165
|
+
POST /api/v1/products → Create product
|
|
166
|
+
GET /api/v1/products/123 → Read product
|
|
167
|
+
PATCH /api/v1/products/123 → Update product
|
|
168
|
+
DELETE /api/v1/products/123 → Delete product
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**When to use:** Standard CRUD, basic validation, standard pagination.
|
|
172
|
+
|
|
173
|
+
### 2. Custom Override Routes
|
|
174
|
+
|
|
175
|
+
For special business logic. Use `(contents)/` folder.
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
// app/api/v1/(contents)/tasks/route.ts
|
|
179
|
+
export const POST = withApiLogging(async (req: NextRequest): Promise<NextResponse> => {
|
|
180
|
+
const authResult = await authenticateRequest(req)
|
|
181
|
+
|
|
182
|
+
// Custom logic: Admin can create for other users
|
|
183
|
+
if (authResult.user?.role === 'admin' && body.userId) {
|
|
184
|
+
task.userId = body.userId
|
|
185
|
+
} else {
|
|
186
|
+
task.userId = authResult.user!.id
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// ... rest of implementation
|
|
190
|
+
const response = createApiResponse(data, { created: true }, 201)
|
|
191
|
+
return addCorsHeaders(response)
|
|
192
|
+
})
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**When to use:** Complex validation, admin-level operations, external integrations.
|
|
196
|
+
|
|
197
|
+
### 3. Core Endpoints
|
|
198
|
+
|
|
199
|
+
System endpoints that cannot be overridden.
|
|
200
|
+
|
|
201
|
+
- `/api/v1/users` - User management
|
|
202
|
+
- `/api/v1/api-keys` - API key management
|
|
203
|
+
- `/api/v1/auth` - Authentication
|
|
204
|
+
|
|
205
|
+
## Input Validation
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
import { z } from 'zod'
|
|
209
|
+
|
|
210
|
+
const CreateProductSchema = z.object({
|
|
211
|
+
title: z.string().min(1).max(255),
|
|
212
|
+
price: z.number().positive(),
|
|
213
|
+
status: z.enum(['active', 'inactive']).default('active'),
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
export const POST = withApiLogging(async (req: NextRequest): Promise<NextResponse> => {
|
|
217
|
+
try {
|
|
218
|
+
const body = CreateProductSchema.parse(await req.json())
|
|
219
|
+
// Validated body ready to use
|
|
220
|
+
} catch (error) {
|
|
221
|
+
if (error instanceof z.ZodError) {
|
|
222
|
+
const response = createApiError('Validation error', 400, error.issues, 'VALIDATION_ERROR')
|
|
223
|
+
return addCorsHeaders(response)
|
|
224
|
+
}
|
|
225
|
+
throw error
|
|
226
|
+
}
|
|
227
|
+
})
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Scripts
|
|
231
|
+
|
|
232
|
+
### Scaffold New Endpoint
|
|
233
|
+
```bash
|
|
234
|
+
# Basic endpoint
|
|
235
|
+
python .claude/skills/nextjs-api-development/scripts/scaffold-endpoint.py \
|
|
236
|
+
--name products \
|
|
237
|
+
--methods GET,POST \
|
|
238
|
+
--auth required
|
|
239
|
+
|
|
240
|
+
# With [id] route for single resource operations
|
|
241
|
+
python .claude/skills/nextjs-api-development/scripts/scaffold-endpoint.py \
|
|
242
|
+
--name products \
|
|
243
|
+
--methods GET,POST \
|
|
244
|
+
--auth required \
|
|
245
|
+
--with-id
|
|
246
|
+
|
|
247
|
+
# Preview without creating files
|
|
248
|
+
python .claude/skills/nextjs-api-development/scripts/scaffold-endpoint.py \
|
|
249
|
+
--name products \
|
|
250
|
+
--dry-run
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Generate CRUD Tests
|
|
254
|
+
```bash
|
|
255
|
+
# Generate test file only
|
|
256
|
+
python .claude/skills/nextjs-api-development/scripts/generate-crud-tests.py \
|
|
257
|
+
--entity products
|
|
258
|
+
|
|
259
|
+
# Also generate API Controller
|
|
260
|
+
python .claude/skills/nextjs-api-development/scripts/generate-crud-tests.py \
|
|
261
|
+
--entity products \
|
|
262
|
+
--with-controller
|
|
263
|
+
|
|
264
|
+
# Preview
|
|
265
|
+
python .claude/skills/nextjs-api-development/scripts/generate-crud-tests.py \
|
|
266
|
+
--entity products \
|
|
267
|
+
--dry-run
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Validate API Structure
|
|
271
|
+
```bash
|
|
272
|
+
python .claude/skills/nextjs-api-development/scripts/validate-api.py \
|
|
273
|
+
--path app/api/v1/
|
|
274
|
+
|
|
275
|
+
# Strict mode (exit with error if violations found)
|
|
276
|
+
python .claude/skills/nextjs-api-development/scripts/validate-api.py \
|
|
277
|
+
--path app/api/v1/ \
|
|
278
|
+
--strict
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Testing Pattern
|
|
282
|
+
|
|
283
|
+
Tests use API Controllers that extend `BaseAPIController`:
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
// In test file
|
|
287
|
+
const ProductsAPIController = require('../../../src/controllers/ProductsAPIController.js')
|
|
288
|
+
|
|
289
|
+
describe('Products API - CRUD Operations', {
|
|
290
|
+
tags: ['@api', '@feat-products', '@crud', '@regression']
|
|
291
|
+
}, () => {
|
|
292
|
+
let productsAPI: any
|
|
293
|
+
|
|
294
|
+
const SUPERADMIN_API_KEY = Cypress.env('SUPERADMIN_API_KEY')
|
|
295
|
+
const TEAM_ID = Cypress.env('TEAM_ID')
|
|
296
|
+
|
|
297
|
+
before(() => {
|
|
298
|
+
productsAPI = new ProductsAPIController(BASE_URL, SUPERADMIN_API_KEY, TEAM_ID)
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
it('should list products', () => {
|
|
302
|
+
productsAPI.getProducts().then((response: any) => {
|
|
303
|
+
productsAPI.validateSuccessResponse(response, 200)
|
|
304
|
+
expect(response.body.data).to.be.an('array')
|
|
305
|
+
})
|
|
306
|
+
})
|
|
307
|
+
})
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## Security Best Practices
|
|
311
|
+
|
|
312
|
+
### SQL Injection Prevention
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
// ✅ CORRECT - Parameterized queries with queryWithRLS
|
|
316
|
+
const result = await queryWithRLS(
|
|
317
|
+
`SELECT * FROM products WHERE "userId" = $1 AND status = $2 LIMIT $3`,
|
|
318
|
+
[userId, status, limit],
|
|
319
|
+
authResult.user!.id
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
// ❌ NEVER - String concatenation
|
|
323
|
+
const query = `SELECT * FROM products WHERE userId = '${userId}'`
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## Anti-Patterns
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
// ❌ NEVER: Use export async function instead of withApiLogging
|
|
330
|
+
export async function GET(request: NextRequest) { }
|
|
331
|
+
|
|
332
|
+
// ❌ NEVER: Return response without addCorsHeaders
|
|
333
|
+
return createApiResponse(data)
|
|
334
|
+
|
|
335
|
+
// ❌ NEVER: Use raw NextResponse.json
|
|
336
|
+
return NextResponse.json({ data })
|
|
337
|
+
|
|
338
|
+
// ❌ NEVER: Skip authentication
|
|
339
|
+
export async function GET(request: NextRequest) {
|
|
340
|
+
const data = await db.query('SELECT * FROM products')
|
|
341
|
+
return createApiResponse(data)
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// ✅ CORRECT: Full pattern
|
|
345
|
+
export const GET = withApiLogging(async (req: NextRequest): Promise<NextResponse> => {
|
|
346
|
+
const authResult = await authenticateRequest(req)
|
|
347
|
+
// ...
|
|
348
|
+
const response = createApiResponse(data)
|
|
349
|
+
return addCorsHeaders(response)
|
|
350
|
+
})
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
## Checklist for New Endpoint
|
|
354
|
+
|
|
355
|
+
- [ ] Uses `withApiLogging` wrapper
|
|
356
|
+
- [ ] Has `OPTIONS` handler using `handleCorsPreflightRequest()`
|
|
357
|
+
- [ ] All responses wrapped with `addCorsHeaders()`
|
|
358
|
+
- [ ] Dual authentication implemented
|
|
359
|
+
- [ ] Input validation with Zod schema
|
|
360
|
+
- [ ] Response helpers used (`createApiResponse`, `createApiError`)
|
|
361
|
+
- [ ] Proper error handling with try/catch
|
|
362
|
+
- [ ] Pagination for list endpoints using `parsePaginationParams`
|
|
363
|
+
- [ ] API scopes added to `core/lib/api/keys.ts`
|
|
364
|
+
- [ ] Cypress tests created with API Controller pattern
|