@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,641 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: notion-integration
|
|
3
|
+
description: |
|
|
4
|
+
Notion integration patterns for knowledge management.
|
|
5
|
+
Covers API, databases, pages, and blocks.
|
|
6
|
+
Use this skill when implementing Notion features or syncing sessions with databases.
|
|
7
|
+
allowed-tools: Read, Glob, Grep, Bash
|
|
8
|
+
version: 1.0.0
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Notion Integration Skill
|
|
12
|
+
|
|
13
|
+
Integration patterns for syncing development sessions with Notion databases and pages.
|
|
14
|
+
|
|
15
|
+
## Architecture Overview
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
19
|
+
│ NOTION INTEGRATION │
|
|
20
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
21
|
+
│ │
|
|
22
|
+
│ ┌─────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
23
|
+
│ │ Claude │────►│ REST API │────►│ Notion │ │
|
|
24
|
+
│ │ Session │◄────│ Client │◄────│ API │ │
|
|
25
|
+
│ └─────────────┘ └──────────────┘ └──────────────┘ │
|
|
26
|
+
│ │ │ │
|
|
27
|
+
│ ▼ ▼ │
|
|
28
|
+
│ ┌─────────────┐ ┌──────────────┐ │
|
|
29
|
+
│ │ Session │ │ Databases │ │
|
|
30
|
+
│ │ Files │ │ & Pages │ │
|
|
31
|
+
│ └─────────────┘ └──────────────┘ │
|
|
32
|
+
│ │
|
|
33
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## When to Use This Skill
|
|
39
|
+
|
|
40
|
+
- Setting up Notion integration for the first time
|
|
41
|
+
- Syncing development sessions with Notion databases
|
|
42
|
+
- Creating database entries from Claude sessions
|
|
43
|
+
- Updating page properties and content
|
|
44
|
+
- Managing documentation in Notion
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Configuration
|
|
49
|
+
|
|
50
|
+
### .claude/config/workspace.json
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"taskManager": {
|
|
55
|
+
"enabled": true,
|
|
56
|
+
"provider": "notion",
|
|
57
|
+
"syncWithSession": true,
|
|
58
|
+
"autoUpdateStatus": true,
|
|
59
|
+
"config": {
|
|
60
|
+
"integrationToken": "${NOTION_TOKEN}",
|
|
61
|
+
"tasksDatabaseId": "your-database-id",
|
|
62
|
+
"defaultWorkspace": "your-workspace-id"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Environment Variables
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# .env.local
|
|
72
|
+
NOTION_TOKEN=secret_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Authentication
|
|
78
|
+
|
|
79
|
+
### Integration Token
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
// Bearer token authentication
|
|
83
|
+
const headers = {
|
|
84
|
+
'Authorization': `Bearer ${process.env.NOTION_TOKEN}`,
|
|
85
|
+
'Content-Type': 'application/json',
|
|
86
|
+
'Notion-Version': '2022-06-28' // Required API version
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// Base URL
|
|
90
|
+
const BASE_URL = 'https://api.notion.com/v1';
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Integration Setup
|
|
94
|
+
|
|
95
|
+
1. Go to https://www.notion.so/my-integrations
|
|
96
|
+
2. Create new integration
|
|
97
|
+
3. Copy the "Internal Integration Token"
|
|
98
|
+
4. Share databases/pages with the integration
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## API Patterns
|
|
103
|
+
|
|
104
|
+
### Common Endpoints
|
|
105
|
+
|
|
106
|
+
| Endpoint | Method | Description |
|
|
107
|
+
|----------|--------|-------------|
|
|
108
|
+
| `/users/me` | GET | Get bot user |
|
|
109
|
+
| `/users` | GET | List users |
|
|
110
|
+
| `/databases/{id}` | GET | Get database |
|
|
111
|
+
| `/databases/{id}/query` | POST | Query database |
|
|
112
|
+
| `/pages` | POST | Create page |
|
|
113
|
+
| `/pages/{id}` | GET/PATCH | Page operations |
|
|
114
|
+
| `/pages/{id}/properties/{id}` | GET | Get property value |
|
|
115
|
+
| `/blocks/{id}` | GET/PATCH/DELETE | Block operations |
|
|
116
|
+
| `/blocks/{id}/children` | GET/PATCH | Block children |
|
|
117
|
+
| `/search` | POST | Search pages/databases |
|
|
118
|
+
|
|
119
|
+
### Database Entry (Page) Structure
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
interface NotionPage {
|
|
123
|
+
id: string;
|
|
124
|
+
object: 'page';
|
|
125
|
+
parent: {
|
|
126
|
+
type: 'database_id';
|
|
127
|
+
database_id: string;
|
|
128
|
+
};
|
|
129
|
+
properties: {
|
|
130
|
+
// Title property (required)
|
|
131
|
+
Name: {
|
|
132
|
+
title: Array<{
|
|
133
|
+
type: 'text';
|
|
134
|
+
text: { content: string };
|
|
135
|
+
}>;
|
|
136
|
+
};
|
|
137
|
+
// Select property
|
|
138
|
+
Status: {
|
|
139
|
+
select: {
|
|
140
|
+
name: string;
|
|
141
|
+
color: string;
|
|
142
|
+
} | null;
|
|
143
|
+
};
|
|
144
|
+
// Multi-select property
|
|
145
|
+
Tags: {
|
|
146
|
+
multi_select: Array<{
|
|
147
|
+
name: string;
|
|
148
|
+
color: string;
|
|
149
|
+
}>;
|
|
150
|
+
};
|
|
151
|
+
// Date property
|
|
152
|
+
'Due Date': {
|
|
153
|
+
date: {
|
|
154
|
+
start: string;
|
|
155
|
+
end: string | null;
|
|
156
|
+
} | null;
|
|
157
|
+
};
|
|
158
|
+
// Person property
|
|
159
|
+
Assignee: {
|
|
160
|
+
people: Array<{
|
|
161
|
+
id: string;
|
|
162
|
+
name: string;
|
|
163
|
+
}>;
|
|
164
|
+
};
|
|
165
|
+
// Checkbox property
|
|
166
|
+
Completed: {
|
|
167
|
+
checkbox: boolean;
|
|
168
|
+
};
|
|
169
|
+
// URL property
|
|
170
|
+
URL: {
|
|
171
|
+
url: string | null;
|
|
172
|
+
};
|
|
173
|
+
// Rich text property
|
|
174
|
+
Description: {
|
|
175
|
+
rich_text: Array<{
|
|
176
|
+
type: 'text';
|
|
177
|
+
text: { content: string };
|
|
178
|
+
}>;
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
url: string;
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Database Operations
|
|
188
|
+
|
|
189
|
+
### Query Database
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
// Query with filter and sort
|
|
193
|
+
const response = await fetch(`${BASE_URL}/databases/${databaseId}/query`, {
|
|
194
|
+
method: 'POST',
|
|
195
|
+
headers,
|
|
196
|
+
body: JSON.stringify({
|
|
197
|
+
filter: {
|
|
198
|
+
and: [
|
|
199
|
+
{
|
|
200
|
+
property: 'Status',
|
|
201
|
+
select: { equals: 'In Progress' }
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
property: 'Assignee',
|
|
205
|
+
people: { contains: userId }
|
|
206
|
+
}
|
|
207
|
+
]
|
|
208
|
+
},
|
|
209
|
+
sorts: [
|
|
210
|
+
{ property: 'Due Date', direction: 'ascending' }
|
|
211
|
+
],
|
|
212
|
+
page_size: 100
|
|
213
|
+
})
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
const { results, has_more, next_cursor } = await response.json();
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Create Database Entry
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
// Create new page in database
|
|
223
|
+
const page = await fetch(`${BASE_URL}/pages`, {
|
|
224
|
+
method: 'POST',
|
|
225
|
+
headers,
|
|
226
|
+
body: JSON.stringify({
|
|
227
|
+
parent: { database_id: databaseId },
|
|
228
|
+
properties: {
|
|
229
|
+
Name: {
|
|
230
|
+
title: [{ text: { content: 'New Feature: User Auth' } }]
|
|
231
|
+
},
|
|
232
|
+
Status: {
|
|
233
|
+
select: { name: 'In Progress' }
|
|
234
|
+
},
|
|
235
|
+
Tags: {
|
|
236
|
+
multi_select: [
|
|
237
|
+
{ name: 'feature' },
|
|
238
|
+
{ name: 'backend' }
|
|
239
|
+
]
|
|
240
|
+
},
|
|
241
|
+
'Due Date': {
|
|
242
|
+
date: { start: '2024-01-15' }
|
|
243
|
+
},
|
|
244
|
+
Description: {
|
|
245
|
+
rich_text: [{ text: { content: 'Implement OAuth2 support' } }]
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
})
|
|
249
|
+
});
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Update Properties
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
// Update page properties
|
|
256
|
+
await fetch(`${BASE_URL}/pages/${pageId}`, {
|
|
257
|
+
method: 'PATCH',
|
|
258
|
+
headers,
|
|
259
|
+
body: JSON.stringify({
|
|
260
|
+
properties: {
|
|
261
|
+
Status: {
|
|
262
|
+
select: { name: 'Done' }
|
|
263
|
+
},
|
|
264
|
+
Completed: {
|
|
265
|
+
checkbox: true
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
})
|
|
269
|
+
});
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## Block Operations
|
|
275
|
+
|
|
276
|
+
Notion pages consist of blocks. Common block types:
|
|
277
|
+
|
|
278
|
+
### Block Types
|
|
279
|
+
|
|
280
|
+
| Type | Description |
|
|
281
|
+
|------|-------------|
|
|
282
|
+
| `paragraph` | Text paragraph |
|
|
283
|
+
| `heading_1/2/3` | Headings |
|
|
284
|
+
| `bulleted_list_item` | Bullet point |
|
|
285
|
+
| `numbered_list_item` | Numbered item |
|
|
286
|
+
| `to_do` | Checkbox item |
|
|
287
|
+
| `toggle` | Collapsible block |
|
|
288
|
+
| `code` | Code block |
|
|
289
|
+
| `callout` | Callout box |
|
|
290
|
+
| `quote` | Quote block |
|
|
291
|
+
| `divider` | Horizontal line |
|
|
292
|
+
| `table` | Table |
|
|
293
|
+
| `table_row` | Table row |
|
|
294
|
+
|
|
295
|
+
### Adding Content to Page
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
// Append blocks to page
|
|
299
|
+
await fetch(`${BASE_URL}/blocks/${pageId}/children`, {
|
|
300
|
+
method: 'PATCH',
|
|
301
|
+
headers,
|
|
302
|
+
body: JSON.stringify({
|
|
303
|
+
children: [
|
|
304
|
+
{
|
|
305
|
+
object: 'block',
|
|
306
|
+
type: 'heading_2',
|
|
307
|
+
heading_2: {
|
|
308
|
+
rich_text: [{ type: 'text', text: { content: 'Session Progress' } }]
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
object: 'block',
|
|
313
|
+
type: 'paragraph',
|
|
314
|
+
paragraph: {
|
|
315
|
+
rich_text: [{ type: 'text', text: { content: 'Phase: Backend Development' } }]
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
object: 'block',
|
|
320
|
+
type: 'to_do',
|
|
321
|
+
to_do: {
|
|
322
|
+
rich_text: [{ type: 'text', text: { content: 'API endpoints' } }],
|
|
323
|
+
checked: true
|
|
324
|
+
}
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
object: 'block',
|
|
328
|
+
type: 'to_do',
|
|
329
|
+
to_do: {
|
|
330
|
+
rich_text: [{ type: 'text', text: { content: 'Frontend components' } }],
|
|
331
|
+
checked: false
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
object: 'block',
|
|
336
|
+
type: 'code',
|
|
337
|
+
code: {
|
|
338
|
+
rich_text: [{ type: 'text', text: { content: 'npm run test' } }],
|
|
339
|
+
language: 'bash'
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
]
|
|
343
|
+
})
|
|
344
|
+
});
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## Session Sync Patterns
|
|
350
|
+
|
|
351
|
+
### Linking Session to Database Entry
|
|
352
|
+
|
|
353
|
+
```markdown
|
|
354
|
+
# In requirements.md
|
|
355
|
+
|
|
356
|
+
## Notion Task
|
|
357
|
+
- **Page ID:** abc123-def456-...
|
|
358
|
+
- **URL:** https://notion.so/workspace/Task-Name-abc123def456
|
|
359
|
+
- **Status:** In Progress
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Status Mapping
|
|
363
|
+
|
|
364
|
+
| Session Event | Notion Status |
|
|
365
|
+
|---------------|---------------|
|
|
366
|
+
| Session created | "In Progress" |
|
|
367
|
+
| Blocked | "Blocked" |
|
|
368
|
+
| Session closed (success) | "Done" |
|
|
369
|
+
| Session closed (partial) | "In Review" |
|
|
370
|
+
|
|
371
|
+
### Progress Updates
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
// Update page with progress
|
|
375
|
+
const progressBlocks = [
|
|
376
|
+
{
|
|
377
|
+
object: 'block',
|
|
378
|
+
type: 'divider',
|
|
379
|
+
divider: {}
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
object: 'block',
|
|
383
|
+
type: 'heading_3',
|
|
384
|
+
heading_3: {
|
|
385
|
+
rich_text: [{
|
|
386
|
+
type: 'text',
|
|
387
|
+
text: { content: `Update: ${new Date().toISOString().split('T')[0]}` }
|
|
388
|
+
}]
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
object: 'block',
|
|
393
|
+
type: 'bulleted_list_item',
|
|
394
|
+
bulleted_list_item: {
|
|
395
|
+
rich_text: [{ type: 'text', text: { content: 'API endpoints completed' } }]
|
|
396
|
+
}
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
object: 'block',
|
|
400
|
+
type: 'bulleted_list_item',
|
|
401
|
+
bulleted_list_item: {
|
|
402
|
+
rich_text: [{ type: 'text', text: { content: 'Tests written and passing' } }]
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
];
|
|
406
|
+
|
|
407
|
+
await fetch(`${BASE_URL}/blocks/${pageId}/children`, {
|
|
408
|
+
method: 'PATCH',
|
|
409
|
+
headers,
|
|
410
|
+
body: JSON.stringify({ children: progressBlocks })
|
|
411
|
+
});
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## Rich Text Formatting
|
|
417
|
+
|
|
418
|
+
### Text with Formatting
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
const richText = [
|
|
422
|
+
{ type: 'text', text: { content: 'Normal text, ' } },
|
|
423
|
+
{
|
|
424
|
+
type: 'text',
|
|
425
|
+
text: { content: 'bold text' },
|
|
426
|
+
annotations: { bold: true }
|
|
427
|
+
},
|
|
428
|
+
{ type: 'text', text: { content: ', ' } },
|
|
429
|
+
{
|
|
430
|
+
type: 'text',
|
|
431
|
+
text: { content: 'italic' },
|
|
432
|
+
annotations: { italic: true }
|
|
433
|
+
},
|
|
434
|
+
{ type: 'text', text: { content: ', ' } },
|
|
435
|
+
{
|
|
436
|
+
type: 'text',
|
|
437
|
+
text: { content: 'code' },
|
|
438
|
+
annotations: { code: true }
|
|
439
|
+
},
|
|
440
|
+
{ type: 'text', text: { content: ', and ' } },
|
|
441
|
+
{
|
|
442
|
+
type: 'text',
|
|
443
|
+
text: { content: 'link', link: { url: 'https://example.com' } }
|
|
444
|
+
}
|
|
445
|
+
];
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### Available Annotations
|
|
449
|
+
|
|
450
|
+
```typescript
|
|
451
|
+
interface Annotations {
|
|
452
|
+
bold: boolean;
|
|
453
|
+
italic: boolean;
|
|
454
|
+
strikethrough: boolean;
|
|
455
|
+
underline: boolean;
|
|
456
|
+
code: boolean;
|
|
457
|
+
color: 'default' | 'gray' | 'brown' | 'orange' | 'yellow' |
|
|
458
|
+
'green' | 'blue' | 'purple' | 'pink' | 'red' |
|
|
459
|
+
'gray_background' | 'brown_background' | /* etc */;
|
|
460
|
+
}
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
---
|
|
464
|
+
|
|
465
|
+
## Rate Limiting
|
|
466
|
+
|
|
467
|
+
### Limits
|
|
468
|
+
|
|
469
|
+
| Type | Limit |
|
|
470
|
+
|------|-------|
|
|
471
|
+
| Requests | 3 requests/second average |
|
|
472
|
+
| Burst | Short bursts allowed |
|
|
473
|
+
|
|
474
|
+
### Handling Rate Limits
|
|
475
|
+
|
|
476
|
+
```typescript
|
|
477
|
+
// Notion returns 429 with Retry-After header
|
|
478
|
+
if (response.status === 429) {
|
|
479
|
+
const retryAfter = response.headers.get('Retry-After') || '1';
|
|
480
|
+
await sleep(parseInt(retryAfter) * 1000);
|
|
481
|
+
// Retry request
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// Implement exponential backoff
|
|
485
|
+
async function fetchWithRetry(url: string, options: RequestInit, maxRetries = 3) {
|
|
486
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
487
|
+
const response = await fetch(url, options);
|
|
488
|
+
if (response.status !== 429) return response;
|
|
489
|
+
|
|
490
|
+
const delay = Math.pow(2, i) * 1000;
|
|
491
|
+
await sleep(delay);
|
|
492
|
+
}
|
|
493
|
+
throw new Error('Max retries exceeded');
|
|
494
|
+
}
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
---
|
|
498
|
+
|
|
499
|
+
## Error Handling
|
|
500
|
+
|
|
501
|
+
### Common Error Codes
|
|
502
|
+
|
|
503
|
+
| Code | Description | Resolution |
|
|
504
|
+
|------|-------------|------------|
|
|
505
|
+
| 400 | Invalid request | Check body format |
|
|
506
|
+
| 401 | Unauthorized | Check token |
|
|
507
|
+
| 403 | No access | Share page with integration |
|
|
508
|
+
| 404 | Not found | Verify page/database ID |
|
|
509
|
+
| 409 | Conflict | Transaction conflict, retry |
|
|
510
|
+
| 429 | Rate limited | Wait and retry |
|
|
511
|
+
|
|
512
|
+
### Error Response Format
|
|
513
|
+
|
|
514
|
+
```json
|
|
515
|
+
{
|
|
516
|
+
"object": "error",
|
|
517
|
+
"status": 400,
|
|
518
|
+
"code": "validation_error",
|
|
519
|
+
"message": "body failed validation..."
|
|
520
|
+
}
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
---
|
|
524
|
+
|
|
525
|
+
## Testing Patterns
|
|
526
|
+
|
|
527
|
+
### Mock API Responses
|
|
528
|
+
|
|
529
|
+
```typescript
|
|
530
|
+
// __mocks__/notion.ts
|
|
531
|
+
export const mockPage = {
|
|
532
|
+
id: "abc123-def456",
|
|
533
|
+
object: "page",
|
|
534
|
+
properties: {
|
|
535
|
+
Name: { title: [{ text: { content: "Test Task" } }] },
|
|
536
|
+
Status: { select: { name: "In Progress" } }
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
export const mockQueryDatabase = jest.fn().mockResolvedValue({
|
|
541
|
+
results: [mockPage],
|
|
542
|
+
has_more: false
|
|
543
|
+
});
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
### Integration Tests
|
|
547
|
+
|
|
548
|
+
```typescript
|
|
549
|
+
describe('Notion Integration', () => {
|
|
550
|
+
it('should query database', async () => {
|
|
551
|
+
const results = await notion.queryDatabase(databaseId, {
|
|
552
|
+
filter: { property: 'Status', select: { equals: 'In Progress' } }
|
|
553
|
+
});
|
|
554
|
+
expect(results.length).toBeGreaterThan(0);
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
it('should create page', async () => {
|
|
558
|
+
const page = await notion.createPage({
|
|
559
|
+
parent: { database_id: databaseId },
|
|
560
|
+
properties: {
|
|
561
|
+
Name: { title: [{ text: { content: 'Test' } }] }
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
expect(page.id).toBeDefined();
|
|
565
|
+
});
|
|
566
|
+
});
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
---
|
|
570
|
+
|
|
571
|
+
## Anti-Patterns
|
|
572
|
+
|
|
573
|
+
### DON'T: Forget Notion-Version Header
|
|
574
|
+
|
|
575
|
+
```typescript
|
|
576
|
+
// BAD - Missing version header
|
|
577
|
+
fetch(url, {
|
|
578
|
+
headers: { 'Authorization': `Bearer ${token}` }
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
// GOOD - Include version
|
|
582
|
+
fetch(url, {
|
|
583
|
+
headers: {
|
|
584
|
+
'Authorization': `Bearer ${token}`,
|
|
585
|
+
'Notion-Version': '2022-06-28'
|
|
586
|
+
}
|
|
587
|
+
});
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
### DON'T: Assume Integration Has Access
|
|
591
|
+
|
|
592
|
+
```typescript
|
|
593
|
+
// BAD - Assume access exists
|
|
594
|
+
const page = await notion.getPage(pageId);
|
|
595
|
+
|
|
596
|
+
// GOOD - Handle access errors
|
|
597
|
+
try {
|
|
598
|
+
const page = await notion.getPage(pageId);
|
|
599
|
+
} catch (error) {
|
|
600
|
+
if (error.code === 'object_not_found') {
|
|
601
|
+
console.error('Page not shared with integration');
|
|
602
|
+
// Guide user to share the page
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
### DON'T: Send Empty Arrays
|
|
608
|
+
|
|
609
|
+
```typescript
|
|
610
|
+
// BAD - Empty arrays can cause errors
|
|
611
|
+
properties: {
|
|
612
|
+
Tags: { multi_select: [] } // Remove tags
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// GOOD - Omit property or use null where supported
|
|
616
|
+
properties: {
|
|
617
|
+
// Don't include Tags to keep existing values
|
|
618
|
+
}
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
---
|
|
622
|
+
|
|
623
|
+
## Checklist
|
|
624
|
+
|
|
625
|
+
Before using Notion integration:
|
|
626
|
+
|
|
627
|
+
- [ ] Integration created at notion.so/my-integrations
|
|
628
|
+
- [ ] Token stored in environment variables
|
|
629
|
+
- [ ] Database shared with integration
|
|
630
|
+
- [ ] Notion-Version header set (2022-06-28)
|
|
631
|
+
- [ ] Property names match database schema exactly
|
|
632
|
+
- [ ] Rate limiting handled
|
|
633
|
+
- [ ] Error handling for 403/404
|
|
634
|
+
|
|
635
|
+
---
|
|
636
|
+
|
|
637
|
+
## Related Skills
|
|
638
|
+
|
|
639
|
+
- `session-management` - Session lifecycle
|
|
640
|
+
- `scheduled-actions` - Background task processing
|
|
641
|
+
- `service-layer` - API implementation patterns
|