@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,511 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cypress-api
|
|
3
|
+
description: |
|
|
4
|
+
API testing patterns with Cypress for CRUD operations.
|
|
5
|
+
Covers BaseAPIController, entity controllers, test structure, and BDD documentation.
|
|
6
|
+
Use this skill when writing API tests or creating new entity API controllers.
|
|
7
|
+
allowed-tools: Read, Glob, Grep, Bash(python:*), Bash(pnpm cy:run:*)
|
|
8
|
+
version: 1.0.0
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Cypress API Testing Skill
|
|
12
|
+
|
|
13
|
+
Patterns and tools for writing API tests with Cypress.
|
|
14
|
+
|
|
15
|
+
## Architecture Overview
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
contents/themes/{theme}/tests/cypress/
|
|
19
|
+
├── e2e/
|
|
20
|
+
│ └── api/ # API tests (this skill)
|
|
21
|
+
│ ├── entities/
|
|
22
|
+
│ │ ├── {entity}-crud.cy.ts # Entity CRUD tests
|
|
23
|
+
│ │ └── {entity}-crud.bdd.md # BDD documentation
|
|
24
|
+
│ └── {feature}/
|
|
25
|
+
│ └── {feature}.cy.ts
|
|
26
|
+
├── src/
|
|
27
|
+
│ └── controllers/
|
|
28
|
+
│ ├── BaseAPIController.js # Base class (DO NOT MODIFY)
|
|
29
|
+
│ └── {Entity}APIController.js # Entity-specific controllers
|
|
30
|
+
└── fixtures/
|
|
31
|
+
└── entities.json # AUTO-GENERATED entity config
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## When to Use This Skill
|
|
35
|
+
|
|
36
|
+
- Writing API tests for entity CRUD operations
|
|
37
|
+
- Creating entity API controllers
|
|
38
|
+
- Testing authentication (API key, session)
|
|
39
|
+
- Validating API responses and error handling
|
|
40
|
+
- Testing pagination and filtering
|
|
41
|
+
|
|
42
|
+
## Test Tag System
|
|
43
|
+
|
|
44
|
+
### Permanent Tags (COMMIT)
|
|
45
|
+
|
|
46
|
+
| Tag | Purpose | When to Use |
|
|
47
|
+
|-----|---------|-------------|
|
|
48
|
+
| `@api` | API tests | Tests in `e2e/api/` |
|
|
49
|
+
| `@feat-{entity}` | Entity-specific | `@feat-tasks`, `@feat-customers` |
|
|
50
|
+
| `@crud` | CRUD operations | Tests covering Create/Read/Update/Delete |
|
|
51
|
+
| `@smoke` | Critical path tests | Must-pass tests |
|
|
52
|
+
| `@regression` | Full test suite | All tests |
|
|
53
|
+
| `@security` | Security tests | Auth validation tests |
|
|
54
|
+
|
|
55
|
+
### Temporary Tags (NEVER COMMIT)
|
|
56
|
+
|
|
57
|
+
| Tag | Purpose | When to Use |
|
|
58
|
+
|-----|---------|-------------|
|
|
59
|
+
| `@in-develop` | Tests being fixed | During iteration loop |
|
|
60
|
+
| `@scope-{session}` | Session tests | All tests for current session |
|
|
61
|
+
|
|
62
|
+
**CRITICAL:** code-reviewer (Phase 16) BLOCKS if temporary tags remain.
|
|
63
|
+
|
|
64
|
+
## Test ID Convention
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
{ENTITY_SLUG_UPPER}_API_{NUMBER}
|
|
68
|
+
|
|
69
|
+
Examples:
|
|
70
|
+
- TASKS_API_001 → List entities
|
|
71
|
+
- TASKS_API_010 → Create entity
|
|
72
|
+
- TASKS_API_020 → Get by ID
|
|
73
|
+
- TASKS_API_030 → Update entity
|
|
74
|
+
- TASKS_API_040 → Delete entity
|
|
75
|
+
- TASKS_API_100 → Integration/lifecycle test
|
|
76
|
+
|
|
77
|
+
Number ranges:
|
|
78
|
+
- 001-009: LIST operations
|
|
79
|
+
- 010-019: CREATE operations
|
|
80
|
+
- 020-029: GET BY ID operations
|
|
81
|
+
- 030-039: UPDATE operations
|
|
82
|
+
- 040-049: DELETE operations
|
|
83
|
+
- 100+: Integration tests
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## BaseAPIController Pattern
|
|
87
|
+
|
|
88
|
+
### Key Methods
|
|
89
|
+
|
|
90
|
+
```javascript
|
|
91
|
+
class BaseAPIController {
|
|
92
|
+
constructor(baseUrl, apiKey, teamId, entityConfig) {
|
|
93
|
+
this.baseUrl = baseUrl
|
|
94
|
+
this.apiKey = apiKey
|
|
95
|
+
this.teamId = teamId
|
|
96
|
+
this.entitySlug = entityConfig.slug
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// CRUD Methods
|
|
100
|
+
list(options = {}) // GET /api/v1/{entity}
|
|
101
|
+
getById(id, options = {}) // GET /api/v1/{entity}/{id}
|
|
102
|
+
create(data, options = {}) // POST /api/v1/{entity}
|
|
103
|
+
update(id, data, options = {}) // PATCH /api/v1/{entity}/{id}
|
|
104
|
+
delete(id, options = {}) // DELETE /api/v1/{entity}/{id}
|
|
105
|
+
|
|
106
|
+
// Validation Methods
|
|
107
|
+
validateSuccessResponse(response, expectedStatus)
|
|
108
|
+
validatePaginatedResponse(response)
|
|
109
|
+
validateBaseEntityFields(entity)
|
|
110
|
+
|
|
111
|
+
// Utility Methods
|
|
112
|
+
setApiKey(key) // Change API key
|
|
113
|
+
setTeamId(teamId) // Change team context
|
|
114
|
+
getHeaders() // Get request headers
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Entity Controller Structure
|
|
119
|
+
|
|
120
|
+
```javascript
|
|
121
|
+
import BaseAPIController from './BaseAPIController'
|
|
122
|
+
import entitiesConfig from '../fixtures/entities.json'
|
|
123
|
+
|
|
124
|
+
const { slug } = entitiesConfig.entities.tasks
|
|
125
|
+
|
|
126
|
+
class TasksAPIController extends BaseAPIController {
|
|
127
|
+
constructor(baseUrl, apiKey, teamId) {
|
|
128
|
+
super(baseUrl, apiKey, teamId, { slug })
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Semantic aliases
|
|
132
|
+
getTasks(options = {}) {
|
|
133
|
+
return this.list(options)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
getTaskById(id, options = {}) {
|
|
137
|
+
return this.getById(id, options)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
createTask(data, options = {}) {
|
|
141
|
+
return this.create(data, options)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
updateTask(id, data, options = {}) {
|
|
145
|
+
return this.update(id, data, options)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
deleteTask(id, options = {}) {
|
|
149
|
+
return this.delete(id, options)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Data generators
|
|
153
|
+
generateRandomTaskData(overrides = {}) {
|
|
154
|
+
return {
|
|
155
|
+
title: `Test Task ${Date.now()}`,
|
|
156
|
+
description: 'Generated test task',
|
|
157
|
+
status: 'active',
|
|
158
|
+
...overrides
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Entity-specific validation
|
|
163
|
+
validateTaskObject(entity, allowMetas = false) {
|
|
164
|
+
this.validateBaseEntityFields(entity)
|
|
165
|
+
expect(entity).to.have.property('title')
|
|
166
|
+
expect(entity).to.have.property('status')
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Authentication
|
|
172
|
+
|
|
173
|
+
### Dual Auth System
|
|
174
|
+
|
|
175
|
+
```javascript
|
|
176
|
+
// API Key Authentication (primary for API tests)
|
|
177
|
+
const api = new TasksAPIController(baseUrl, SUPERADMIN_API_KEY, TEAM_ID)
|
|
178
|
+
|
|
179
|
+
// Headers sent:
|
|
180
|
+
// - Authorization: Bearer {apiKey}
|
|
181
|
+
// - x-team-id: {teamId}
|
|
182
|
+
|
|
183
|
+
// Session Authentication (for UAT tests)
|
|
184
|
+
// Uses cy.session() - see cypress-e2e skill
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Test Users & API Keys
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
// Test API keys (from fixtures or environment)
|
|
191
|
+
const SUPERADMIN_API_KEY = 'sk_test_...' // Full access
|
|
192
|
+
const MEMBER_API_KEY = 'sk_member_...' // Limited access
|
|
193
|
+
|
|
194
|
+
// Team IDs
|
|
195
|
+
const TEAM_ID = 'team-tmt-001'
|
|
196
|
+
|
|
197
|
+
// For session-based tests, see cypress-e2e skill for login helpers
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Auth Test Patterns
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
// Test without API key
|
|
204
|
+
it('should reject request without API key', () => {
|
|
205
|
+
const originalApiKey = api.apiKey
|
|
206
|
+
api.setApiKey(null)
|
|
207
|
+
|
|
208
|
+
api.list().then((response) => {
|
|
209
|
+
expect(response.status).to.eq(401)
|
|
210
|
+
expect(response.body.success).to.be.false
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
api.setApiKey(originalApiKey)
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
// Test without team context
|
|
217
|
+
it('should reject request without x-team-id', () => {
|
|
218
|
+
const originalTeamId = api.teamId
|
|
219
|
+
api.setTeamId(null)
|
|
220
|
+
|
|
221
|
+
api.list().then((response) => {
|
|
222
|
+
expect(response.status).to.eq(400)
|
|
223
|
+
expect(response.body.code).to.eq('TEAM_CONTEXT_REQUIRED')
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
api.setTeamId(originalTeamId)
|
|
227
|
+
})
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## HTTP Status Codes
|
|
231
|
+
|
|
232
|
+
| Code | Meaning | When Used |
|
|
233
|
+
|------|---------|-----------|
|
|
234
|
+
| 200 | OK | Successful GET, PATCH, DELETE |
|
|
235
|
+
| 201 | Created | Successful POST |
|
|
236
|
+
| 400 | Bad Request | Validation error, missing x-team-id |
|
|
237
|
+
| 401 | Unauthorized | Missing/invalid API key |
|
|
238
|
+
| 403 | Forbidden | Insufficient permissions |
|
|
239
|
+
| 404 | Not Found | Entity doesn't exist |
|
|
240
|
+
| 409 | Conflict | Duplicate entry, constraint violation |
|
|
241
|
+
| 500 | Server Error | Internal error |
|
|
242
|
+
|
|
243
|
+
## Error Codes
|
|
244
|
+
|
|
245
|
+
| Code | Description |
|
|
246
|
+
|------|-------------|
|
|
247
|
+
| `TEAM_CONTEXT_REQUIRED` | Missing x-team-id header |
|
|
248
|
+
| `MISSING_API_KEY` | No authentication provided |
|
|
249
|
+
| `INVALID_API_KEY` | API key doesn't exist or expired |
|
|
250
|
+
| `AUTHENTICATION_REQUIRED` | Must provide auth credentials |
|
|
251
|
+
| `INSUFFICIENT_PERMISSIONS` | User lacks required scope |
|
|
252
|
+
| `VALIDATION_ERROR` | Request body validation failed |
|
|
253
|
+
| `NOT_FOUND` | Entity doesn't exist |
|
|
254
|
+
| `CONFLICT` | Duplicate or constraint violation |
|
|
255
|
+
|
|
256
|
+
## Test Structure
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
describe('{Entity} API - CRUD Operations', {
|
|
260
|
+
tags: ['@api', '@feat-{entity}', '@crud', '@regression']
|
|
261
|
+
}, () => {
|
|
262
|
+
let api: any
|
|
263
|
+
let createdEntities: any[] = []
|
|
264
|
+
|
|
265
|
+
const SUPERADMIN_API_KEY = '...'
|
|
266
|
+
const TEAM_ID = 'team-tmt-001'
|
|
267
|
+
const BASE_URL = Cypress.config('baseUrl')
|
|
268
|
+
|
|
269
|
+
before(() => {
|
|
270
|
+
api = new EntityAPIController(BASE_URL, SUPERADMIN_API_KEY, TEAM_ID)
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
beforeEach(() => {
|
|
274
|
+
allure.epic('API')
|
|
275
|
+
allure.feature('Entities')
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
afterEach(() => {
|
|
279
|
+
// CRITICAL: Cleanup created entities
|
|
280
|
+
createdEntities.forEach((entity) => {
|
|
281
|
+
if (entity?.id) {
|
|
282
|
+
api.delete(entity.id)
|
|
283
|
+
}
|
|
284
|
+
})
|
|
285
|
+
createdEntities = []
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
// Tests...
|
|
289
|
+
})
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## BDD Documentation Format (API)
|
|
293
|
+
|
|
294
|
+
API tests use YAML frontmatter + `## @test` sections:
|
|
295
|
+
|
|
296
|
+
```markdown
|
|
297
|
+
---
|
|
298
|
+
feature: {Entity} API
|
|
299
|
+
priority: high
|
|
300
|
+
tags: [api, feat-{entity}, crud, regression]
|
|
301
|
+
grepTags: ["@api", "@feat-{entity}"]
|
|
302
|
+
coverage: N tests
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
# {Entity} API
|
|
306
|
+
|
|
307
|
+
> API tests for /api/v1/{entity} endpoints.
|
|
308
|
+
|
|
309
|
+
## Endpoints Covered
|
|
310
|
+
|
|
311
|
+
| Endpoint | Method | Description |
|
|
312
|
+
|----------|--------|-------------|
|
|
313
|
+
| `/api/v1/{entity}` | GET | List entities |
|
|
314
|
+
| `/api/v1/{entity}` | POST | Create entity |
|
|
315
|
+
| `/api/v1/{entity}/{id}` | GET | Get entity by ID |
|
|
316
|
+
| `/api/v1/{entity}/{id}` | PATCH | Update entity |
|
|
317
|
+
| `/api/v1/{entity}/{id}` | DELETE | Delete entity |
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## @test {ENTITY}_API_001: List entities
|
|
322
|
+
|
|
323
|
+
### Metadata
|
|
324
|
+
- **Priority:** Critical
|
|
325
|
+
- **Type:** Smoke
|
|
326
|
+
- **Tags:** api, {entity}, list
|
|
327
|
+
- **Grep:** `@smoke @feat-{entity}`
|
|
328
|
+
|
|
329
|
+
\`\`\`gherkin:en
|
|
330
|
+
Scenario: List entities with valid API key
|
|
331
|
+
|
|
332
|
+
Given I have a valid superadmin API key
|
|
333
|
+
And I have x-team-id header set
|
|
334
|
+
When I make a GET request to /api/v1/{entity}
|
|
335
|
+
Then the response status should be 200
|
|
336
|
+
And the response body should have success true
|
|
337
|
+
And the data should contain paginated results
|
|
338
|
+
\`\`\`
|
|
339
|
+
|
|
340
|
+
\`\`\`gherkin:es
|
|
341
|
+
Scenario: Listar entidades con API key válida
|
|
342
|
+
|
|
343
|
+
Given tengo una API key de superadmin válida
|
|
344
|
+
And tengo el header x-team-id configurado
|
|
345
|
+
When hago una solicitud GET a /api/v1/{entity}
|
|
346
|
+
Then el status de respuesta debería ser 200
|
|
347
|
+
And el body debería tener success true
|
|
348
|
+
And los datos deberían contener resultados paginados
|
|
349
|
+
\`\`\`
|
|
350
|
+
|
|
351
|
+
### Expected Results
|
|
352
|
+
- Status: 200 OK
|
|
353
|
+
- Response contains paginated data array
|
|
354
|
+
- Info contains total, page, limit
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## Response Format
|
|
359
|
+
|
|
360
|
+
### Success Response (200)
|
|
361
|
+
\`\`\`json
|
|
362
|
+
{
|
|
363
|
+
"success": true,
|
|
364
|
+
"data": [...],
|
|
365
|
+
"info": {
|
|
366
|
+
"total": 10,
|
|
367
|
+
"page": 1,
|
|
368
|
+
"limit": 10
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
\`\`\`
|
|
372
|
+
|
|
373
|
+
### Error Response (401)
|
|
374
|
+
\`\`\`json
|
|
375
|
+
{
|
|
376
|
+
"success": false,
|
|
377
|
+
"error": {
|
|
378
|
+
"message": "Authentication required",
|
|
379
|
+
"code": "AUTHENTICATION_REQUIRED"
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
\`\`\`
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
## Test Summary
|
|
387
|
+
|
|
388
|
+
| Test ID | Endpoint | Description | Tags |
|
|
389
|
+
|---------|----------|-------------|------|
|
|
390
|
+
| {ENTITY}_API_001 | GET / | List with valid auth | `@smoke` |
|
|
391
|
+
| {ENTITY}_API_010 | POST / | Create with valid data | `@smoke` |
|
|
392
|
+
| {ENTITY}_API_020 | GET /{id} | Get by valid ID | |
|
|
393
|
+
| {ENTITY}_API_030 | PATCH /{id} | Update with valid data | |
|
|
394
|
+
| {ENTITY}_API_040 | DELETE /{id} | Delete by valid ID | |
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
## Scripts
|
|
398
|
+
|
|
399
|
+
### Generate API Controller
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
# Generate API controller from template
|
|
403
|
+
python3 .claude/skills/cypress-api/scripts/generate-api-controller.py \
|
|
404
|
+
--entity tasks \
|
|
405
|
+
--theme default
|
|
406
|
+
|
|
407
|
+
# Preview without writing
|
|
408
|
+
python3 .claude/skills/cypress-api/scripts/generate-api-controller.py \
|
|
409
|
+
--entity tasks \
|
|
410
|
+
--theme default \
|
|
411
|
+
--dry-run
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### Generate API Test
|
|
415
|
+
|
|
416
|
+
```bash
|
|
417
|
+
# Generate API test file + BDD documentation
|
|
418
|
+
python3 .claude/skills/cypress-api/scripts/generate-api-test.py \
|
|
419
|
+
--entity tasks \
|
|
420
|
+
--theme default \
|
|
421
|
+
--with-bdd
|
|
422
|
+
|
|
423
|
+
# Preview without writing
|
|
424
|
+
python3 .claude/skills/cypress-api/scripts/generate-api-test.py \
|
|
425
|
+
--entity tasks \
|
|
426
|
+
--theme default \
|
|
427
|
+
--with-bdd \
|
|
428
|
+
--dry-run
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
## Test Execution Commands
|
|
432
|
+
|
|
433
|
+
```bash
|
|
434
|
+
# Run specific API test file
|
|
435
|
+
pnpm cy:run --spec "contents/themes/default/tests/cypress/e2e/api/entities/tasks-crud.cy.ts"
|
|
436
|
+
|
|
437
|
+
# Run all API tests
|
|
438
|
+
pnpm cy:run --env grepTags="@api"
|
|
439
|
+
|
|
440
|
+
# Run entity-specific API tests
|
|
441
|
+
pnpm cy:run --env grepTags="@feat-tasks,@api"
|
|
442
|
+
|
|
443
|
+
# Run smoke API tests
|
|
444
|
+
pnpm cy:run --env grepTags="@api,@smoke"
|
|
445
|
+
|
|
446
|
+
# Run @in-develop tests only (during iteration)
|
|
447
|
+
pnpm cy:run --env grepTags="@in-develop"
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
## Anti-Patterns
|
|
451
|
+
|
|
452
|
+
```javascript
|
|
453
|
+
// NEVER: Hardcoded entity slugs
|
|
454
|
+
const endpoint = '/api/v1/tasks'
|
|
455
|
+
|
|
456
|
+
// CORRECT: From entities.json
|
|
457
|
+
const { slug } = entitiesConfig.entities.tasks
|
|
458
|
+
const endpoint = `/api/v1/${slug}`
|
|
459
|
+
|
|
460
|
+
// NEVER: Fixed timeouts
|
|
461
|
+
cy.wait(3000)
|
|
462
|
+
|
|
463
|
+
// CORRECT: Use promise chaining
|
|
464
|
+
api.create(data).then((response) => {
|
|
465
|
+
// Handle response
|
|
466
|
+
})
|
|
467
|
+
|
|
468
|
+
// NEVER: Skip cleanup
|
|
469
|
+
afterEach(() => {
|
|
470
|
+
// Missing cleanup!
|
|
471
|
+
})
|
|
472
|
+
|
|
473
|
+
// CORRECT: Always cleanup created entities
|
|
474
|
+
afterEach(() => {
|
|
475
|
+
createdEntities.forEach((entity) => {
|
|
476
|
+
if (entity?.id) api.delete(entity.id)
|
|
477
|
+
})
|
|
478
|
+
createdEntities = []
|
|
479
|
+
})
|
|
480
|
+
|
|
481
|
+
// NEVER: Modify shared state without restoring
|
|
482
|
+
api.setApiKey(null)
|
|
483
|
+
// Tests continue with null key...
|
|
484
|
+
|
|
485
|
+
// CORRECT: Always restore original state
|
|
486
|
+
const original = api.apiKey
|
|
487
|
+
api.setApiKey(null)
|
|
488
|
+
// Test...
|
|
489
|
+
api.setApiKey(original)
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
## Checklist
|
|
493
|
+
|
|
494
|
+
Before finalizing API tests:
|
|
495
|
+
|
|
496
|
+
- [ ] Uses entity API controller (extends BaseAPIController)
|
|
497
|
+
- [ ] Uses correct test ID convention (`{ENTITY}_API_{NUMBER}`)
|
|
498
|
+
- [ ] Includes cleanup in `afterEach`
|
|
499
|
+
- [ ] Tests authentication (401 without key)
|
|
500
|
+
- [ ] Tests team context (400 without x-team-id)
|
|
501
|
+
- [ ] Includes permanent tags (`@api`, `@feat-{entity}`, `@crud`)
|
|
502
|
+
- [ ] NO temporary tags (`@in-develop`, `@scope-{session}`)
|
|
503
|
+
- [ ] Has corresponding `.bdd.md` documentation file
|
|
504
|
+
- [ ] BDD uses YAML frontmatter + `## @test` format
|
|
505
|
+
- [ ] BDD is bilingual (`:en` and `:es` gherkin blocks)
|
|
506
|
+
|
|
507
|
+
## Related Skills
|
|
508
|
+
|
|
509
|
+
- `cypress-e2e` - UAT testing patterns
|
|
510
|
+
- `cypress-selectors` - Selector architecture
|
|
511
|
+
- `better-auth` - Authentication patterns
|