opencastle 0.1.0
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 +215 -0
- package/bin/cli.mjs +69 -0
- package/dist/cli/adapters/claude-code.d.ts +22 -0
- package/dist/cli/adapters/claude-code.d.ts.map +1 -0
- package/dist/cli/adapters/claude-code.js +237 -0
- package/dist/cli/adapters/claude-code.js.map +1 -0
- package/dist/cli/adapters/cursor.d.ts +20 -0
- package/dist/cli/adapters/cursor.d.ts.map +1 -0
- package/dist/cli/adapters/cursor.js +231 -0
- package/dist/cli/adapters/cursor.js.map +1 -0
- package/dist/cli/adapters/vscode.d.ts +20 -0
- package/dist/cli/adapters/vscode.d.ts.map +1 -0
- package/dist/cli/adapters/vscode.js +132 -0
- package/dist/cli/adapters/vscode.js.map +1 -0
- package/dist/cli/copy.d.ts +14 -0
- package/dist/cli/copy.d.ts.map +1 -0
- package/dist/cli/copy.js +62 -0
- package/dist/cli/copy.js.map +1 -0
- package/dist/cli/dashboard.d.ts +3 -0
- package/dist/cli/dashboard.d.ts.map +1 -0
- package/dist/cli/dashboard.js +183 -0
- package/dist/cli/dashboard.js.map +1 -0
- package/dist/cli/diff.d.ts +3 -0
- package/dist/cli/diff.d.ts.map +1 -0
- package/dist/cli/diff.js +27 -0
- package/dist/cli/diff.js.map +1 -0
- package/dist/cli/eject.d.ts +3 -0
- package/dist/cli/eject.d.ts.map +1 -0
- package/dist/cli/eject.js +27 -0
- package/dist/cli/eject.js.map +1 -0
- package/dist/cli/init.d.ts +3 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +92 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/manifest.d.ts +14 -0
- package/dist/cli/manifest.d.ts.map +1 -0
- package/dist/cli/manifest.js +34 -0
- package/dist/cli/manifest.js.map +1 -0
- package/dist/cli/mcp.d.ts +14 -0
- package/dist/cli/mcp.d.ts.map +1 -0
- package/dist/cli/mcp.js +35 -0
- package/dist/cli/mcp.js.map +1 -0
- package/dist/cli/prompt.d.ts +12 -0
- package/dist/cli/prompt.d.ts.map +1 -0
- package/dist/cli/prompt.js +104 -0
- package/dist/cli/prompt.js.map +1 -0
- package/dist/cli/run/adapters/claude-code.d.ts +16 -0
- package/dist/cli/run/adapters/claude-code.d.ts.map +1 -0
- package/dist/cli/run/adapters/claude-code.js +82 -0
- package/dist/cli/run/adapters/claude-code.js.map +1 -0
- package/dist/cli/run/adapters/copilot.d.ts +16 -0
- package/dist/cli/run/adapters/copilot.d.ts.map +1 -0
- package/dist/cli/run/adapters/copilot.js +84 -0
- package/dist/cli/run/adapters/copilot.js.map +1 -0
- package/dist/cli/run/adapters/cursor.d.ts +16 -0
- package/dist/cli/run/adapters/cursor.d.ts.map +1 -0
- package/dist/cli/run/adapters/cursor.js +81 -0
- package/dist/cli/run/adapters/cursor.js.map +1 -0
- package/dist/cli/run/adapters/index.d.ts +14 -0
- package/dist/cli/run/adapters/index.d.ts.map +1 -0
- package/dist/cli/run/adapters/index.js +35 -0
- package/dist/cli/run/adapters/index.js.map +1 -0
- package/dist/cli/run/executor.d.ts +15 -0
- package/dist/cli/run/executor.d.ts.map +1 -0
- package/dist/cli/run/executor.js +249 -0
- package/dist/cli/run/executor.js.map +1 -0
- package/dist/cli/run/reporter.d.ts +10 -0
- package/dist/cli/run/reporter.d.ts.map +1 -0
- package/dist/cli/run/reporter.js +112 -0
- package/dist/cli/run/reporter.js.map +1 -0
- package/dist/cli/run/schema.d.ts +28 -0
- package/dist/cli/run/schema.d.ts.map +1 -0
- package/dist/cli/run/schema.js +511 -0
- package/dist/cli/run/schema.js.map +1 -0
- package/dist/cli/run.d.ts +6 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +123 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/stack-config.d.ts +12 -0
- package/dist/cli/stack-config.d.ts.map +1 -0
- package/dist/cli/stack-config.js +146 -0
- package/dist/cli/stack-config.js.map +1 -0
- package/dist/cli/types.d.ts +169 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +2 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/cli/update.d.ts +3 -0
- package/dist/cli/update.d.ts.map +1 -0
- package/dist/cli/update.js +50 -0
- package/dist/cli/update.js.map +1 -0
- package/package.json +48 -0
- package/src/cli/adapters/claude-code.ts +287 -0
- package/src/cli/adapters/cursor.ts +377 -0
- package/src/cli/adapters/vscode.ts +168 -0
- package/src/cli/copy.ts +79 -0
- package/src/cli/dashboard.ts +225 -0
- package/src/cli/diff.ts +44 -0
- package/src/cli/eject.ts +39 -0
- package/src/cli/init.ts +120 -0
- package/src/cli/manifest.ts +45 -0
- package/src/cli/mcp.ts +49 -0
- package/src/cli/prompt.ts +115 -0
- package/src/cli/run/adapters/claude-code.ts +95 -0
- package/src/cli/run/adapters/copilot.ts +97 -0
- package/src/cli/run/adapters/cursor.ts +94 -0
- package/src/cli/run/adapters/index.ts +40 -0
- package/src/cli/run/executor.ts +292 -0
- package/src/cli/run/reporter.ts +129 -0
- package/src/cli/run/schema.ts +595 -0
- package/src/cli/run.ts +137 -0
- package/src/cli/stack-config.ts +180 -0
- package/src/cli/types.ts +207 -0
- package/src/cli/update.ts +75 -0
- package/src/dashboard/astro.config.mjs +6 -0
- package/src/dashboard/package-lock.json +5455 -0
- package/src/dashboard/package.json +14 -0
- package/src/dashboard/public/data/delegations.ndjson +35 -0
- package/src/dashboard/public/data/panels.ndjson +13 -0
- package/src/dashboard/public/data/sessions.ndjson +50 -0
- package/src/dashboard/public/icon-192.png +0 -0
- package/src/dashboard/scripts/generate-seed-data.ts +355 -0
- package/src/dashboard/src/layouts/Layout.astro +25 -0
- package/src/dashboard/src/pages/index.astro +1070 -0
- package/src/dashboard/src/styles/dashboard.css +1078 -0
- package/src/dashboard/tsconfig.json +6 -0
- package/src/orchestrator/agent-workflows/README.md +22 -0
- package/src/orchestrator/agent-workflows/bug-fix.md +128 -0
- package/src/orchestrator/agent-workflows/data-pipeline.md +145 -0
- package/src/orchestrator/agent-workflows/database-migration.md +159 -0
- package/src/orchestrator/agent-workflows/feature-implementation.md +223 -0
- package/src/orchestrator/agent-workflows/performance-optimization.md +125 -0
- package/src/orchestrator/agent-workflows/refactoring.md +142 -0
- package/src/orchestrator/agent-workflows/schema-changes.md +164 -0
- package/src/orchestrator/agent-workflows/security-audit.md +148 -0
- package/src/orchestrator/agent-workflows/shared-delivery-phase.md +33 -0
- package/src/orchestrator/agents/api-designer.agent.md +68 -0
- package/src/orchestrator/agents/architect.agent.md +129 -0
- package/src/orchestrator/agents/content-engineer.agent.md +57 -0
- package/src/orchestrator/agents/copywriter.agent.md +95 -0
- package/src/orchestrator/agents/data-expert.agent.md +63 -0
- package/src/orchestrator/agents/database-engineer.agent.md +62 -0
- package/src/orchestrator/agents/developer.agent.md +66 -0
- package/src/orchestrator/agents/devops-expert.agent.md +57 -0
- package/src/orchestrator/agents/documentation-writer.agent.md +60 -0
- package/src/orchestrator/agents/performance-expert.agent.md +58 -0
- package/src/orchestrator/agents/release-manager.agent.md +72 -0
- package/src/orchestrator/agents/researcher.agent.md +145 -0
- package/src/orchestrator/agents/reviewer.agent.md +62 -0
- package/src/orchestrator/agents/security-expert.agent.md +64 -0
- package/src/orchestrator/agents/seo-specialist.agent.md +67 -0
- package/src/orchestrator/agents/team-lead.agent.md +644 -0
- package/src/orchestrator/agents/testing-expert.agent.md +85 -0
- package/src/orchestrator/agents/ui-ux-expert.agent.md +63 -0
- package/src/orchestrator/copilot-instructions.md +3 -0
- package/src/orchestrator/customizations/AGENT-EXPERTISE.md +325 -0
- package/src/orchestrator/customizations/AGENT-FAILURES.md +69 -0
- package/src/orchestrator/customizations/AGENT-PERFORMANCE.md +58 -0
- package/src/orchestrator/customizations/DISPUTES.md +162 -0
- package/src/orchestrator/customizations/KNOWLEDGE-GRAPH.md +10 -0
- package/src/orchestrator/customizations/LESSONS-LEARNED.md +70 -0
- package/src/orchestrator/customizations/README.md +59 -0
- package/src/orchestrator/customizations/agents/agent-registry.md +46 -0
- package/src/orchestrator/customizations/agents/skill-matrix.md +142 -0
- package/src/orchestrator/customizations/logs/README.md +181 -0
- package/src/orchestrator/customizations/logs/delegations.ndjson +1 -0
- package/src/orchestrator/customizations/logs/panels.ndjson +1 -0
- package/src/orchestrator/customizations/logs/sessions.ndjson +1 -0
- package/src/orchestrator/customizations/project/docs-structure.md +23 -0
- package/src/orchestrator/customizations/project/tracker-config.md +45 -0
- package/src/orchestrator/customizations/project.instructions.md +64 -0
- package/src/orchestrator/customizations/stack/api-config.md +37 -0
- package/src/orchestrator/customizations/stack/cms-config.md +26 -0
- package/src/orchestrator/customizations/stack/data-pipeline-config.md +41 -0
- package/src/orchestrator/customizations/stack/database-config.md +44 -0
- package/src/orchestrator/customizations/stack/deployment-config.md +45 -0
- package/src/orchestrator/customizations/stack/testing-config.md +56 -0
- package/src/orchestrator/instructions/ai-optimization.instructions.md +143 -0
- package/src/orchestrator/instructions/general.instructions.md +194 -0
- package/src/orchestrator/mcp.json +55 -0
- package/src/orchestrator/prompts/bootstrap-customizations.prompt.md +235 -0
- package/src/orchestrator/prompts/brainstorm.prompt.md +115 -0
- package/src/orchestrator/prompts/bug-fix.prompt.md +141 -0
- package/src/orchestrator/prompts/create-skill.prompt.md +103 -0
- package/src/orchestrator/prompts/generate-task-spec.prompt.md +154 -0
- package/src/orchestrator/prompts/implement-feature.prompt.md +124 -0
- package/src/orchestrator/prompts/metrics-report.prompt.md +142 -0
- package/src/orchestrator/prompts/quick-refinement.prompt.md +137 -0
- package/src/orchestrator/prompts/resolve-pr-comments.prompt.md +100 -0
- package/src/orchestrator/skills/accessibility-standards/SKILL.md +164 -0
- package/src/orchestrator/skills/agent-hooks/SKILL.md +147 -0
- package/src/orchestrator/skills/agent-memory/SKILL.md +144 -0
- package/src/orchestrator/skills/api-patterns/SKILL.md +106 -0
- package/src/orchestrator/skills/browser-testing/SKILL.md +203 -0
- package/src/orchestrator/skills/code-commenting/SKILL.md +133 -0
- package/src/orchestrator/skills/contentful-cms/SKILL.md +43 -0
- package/src/orchestrator/skills/context-map/SKILL.md +135 -0
- package/src/orchestrator/skills/convex-database/SKILL.md +80 -0
- package/src/orchestrator/skills/data-engineering/SKILL.md +99 -0
- package/src/orchestrator/skills/deployment-infrastructure/SKILL.md +49 -0
- package/src/orchestrator/skills/documentation-standards/SKILL.md +85 -0
- package/src/orchestrator/skills/fast-review/SKILL.md +327 -0
- package/src/orchestrator/skills/frontend-design/SKILL.md +42 -0
- package/src/orchestrator/skills/jira-management/SKILL.md +168 -0
- package/src/orchestrator/skills/memory-merger/SKILL.md +123 -0
- package/src/orchestrator/skills/nextjs-patterns/SKILL.md +75 -0
- package/src/orchestrator/skills/nx-workspace/SKILL.md +192 -0
- package/src/orchestrator/skills/panel-majority-vote/SKILL.md +184 -0
- package/src/orchestrator/skills/panel-majority-vote/panel-report.template.md +38 -0
- package/src/orchestrator/skills/performance-optimization/SKILL.md +101 -0
- package/src/orchestrator/skills/react-development/SKILL.md +117 -0
- package/src/orchestrator/skills/sanity-cms/SKILL.md +18 -0
- package/src/orchestrator/skills/security-hardening/SKILL.md +118 -0
- package/src/orchestrator/skills/self-improvement/SKILL.md +137 -0
- package/src/orchestrator/skills/seo-patterns/SKILL.md +40 -0
- package/src/orchestrator/skills/session-checkpoints/SKILL.md +205 -0
- package/src/orchestrator/skills/slack-notifications/SKILL.md +211 -0
- package/src/orchestrator/skills/strapi-cms/SKILL.md +43 -0
- package/src/orchestrator/skills/supabase-database/SKILL.md +24 -0
- package/src/orchestrator/skills/task-management/SKILL.md +143 -0
- package/src/orchestrator/skills/team-lead-reference/SKILL.md +317 -0
- package/src/orchestrator/skills/teams-notifications/SKILL.md +249 -0
- package/src/orchestrator/skills/testing-workflow/SKILL.md +134 -0
- package/src/orchestrator/skills/validation-gates/SKILL.md +100 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-memory
|
|
3
|
+
description: "Agent expertise tracking and cross-session knowledge graph. Use when delegating tasks to track agent strengths/weaknesses, or when building context about file relationships and patterns."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Agent Memory Protocol
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
|
|
10
|
+
Track which agents have expertise with which files, patterns, and tools across sessions. This information helps the Team Lead make better delegation decisions by matching tasks to agents with proven track records.
|
|
11
|
+
|
|
12
|
+
## Expertise File
|
|
13
|
+
|
|
14
|
+
Location: `.github/customizations/AGENT-EXPERTISE.md` — a structured record of agent performance per domain.
|
|
15
|
+
|
|
16
|
+
Template structure:
|
|
17
|
+
|
|
18
|
+
```markdown
|
|
19
|
+
# Agent Expertise Registry
|
|
20
|
+
|
|
21
|
+
## Developer
|
|
22
|
+
### Strong Areas
|
|
23
|
+
| Area | Evidence | Last Updated |
|
|
24
|
+
|------|----------|-------------|
|
|
25
|
+
| Feature implementation | Successfully built 5 pages (TAS-XX, TAS-YY) | YYYY-MM-DD |
|
|
26
|
+
| Server-side logic | Fixed auth flow (TAS-ZZ) | YYYY-MM-DD |
|
|
27
|
+
|
|
28
|
+
### Weak Areas
|
|
29
|
+
| Area | Evidence | Last Updated |
|
|
30
|
+
|------|----------|-------------|
|
|
31
|
+
| CSS Modules | Required 2 retries on styling task (TAS-AA) | YYYY-MM-DD |
|
|
32
|
+
|
|
33
|
+
### File Familiarity
|
|
34
|
+
- `apps/tastebeer.eu/app/places/` — 3 tasks completed
|
|
35
|
+
- `libs/queries/src/lib/` — 2 tasks completed
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Memory Update Triggers
|
|
39
|
+
|
|
40
|
+
| Trigger | Action |
|
|
41
|
+
|---------|--------|
|
|
42
|
+
| Agent completes task successfully on first attempt | Add/update Strong Area entry |
|
|
43
|
+
| Agent requires 2+ retries | Add/update Weak Area entry |
|
|
44
|
+
| Agent modifies a file | Update File Familiarity count |
|
|
45
|
+
| Agent fails a task entirely (DLQ) | Add Weak Area with failure reference |
|
|
46
|
+
| >3 months since last update in an area | Mark as "stale" — needs re-evaluation |
|
|
47
|
+
|
|
48
|
+
## Memory Retrieval Protocol
|
|
49
|
+
|
|
50
|
+
1. Before delegating, check `.github/customizations/AGENT-EXPERTISE.md` for the candidate agent
|
|
51
|
+
2. If the task matches a Strong Area, include in the prompt: *"You have prior experience with [area] from [TAS-XX]. Apply the same patterns."*
|
|
52
|
+
3. If the task matches a Weak Area, either: (a) add extra context to the prompt to compensate, or (b) consider a different agent
|
|
53
|
+
4. If the file has high familiarity, mention it: *"You've worked on [file] before in [TAS-XX]."*
|
|
54
|
+
|
|
55
|
+
## Memory Pruning Rules
|
|
56
|
+
|
|
57
|
+
- Remove entries older than 6 months without recent updates
|
|
58
|
+
- Consolidate similar entries (e.g., 5 "App Router pages" entries → 1 entry with count)
|
|
59
|
+
- Remove File Familiarity entries for files that no longer exist
|
|
60
|
+
- The Team Lead should prune at the start of major feature work (not every session)
|
|
61
|
+
|
|
62
|
+
## Integration with Delegation
|
|
63
|
+
|
|
64
|
+
Add relevant expertise context to delegation prompts. Example addition:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
### Agent Context (from expertise registry)
|
|
68
|
+
- Strong: Server Components, GROQ queries (3 successful tasks)
|
|
69
|
+
- Weak: CSS Modules (1 retry on TAS-AA)
|
|
70
|
+
- Familiar files: libs/queries/src/lib/search/ (2 tasks)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Cross-Session Knowledge Graph
|
|
74
|
+
|
|
75
|
+
### Purpose
|
|
76
|
+
|
|
77
|
+
Capture structured relationships between concepts, files, agents, and decisions. Goes beyond flat lesson lists to show how pieces of the system connect.
|
|
78
|
+
|
|
79
|
+
### Entity Types
|
|
80
|
+
|
|
81
|
+
| Entity Type | Examples | Notation |
|
|
82
|
+
|-------------|----------|----------|
|
|
83
|
+
| `File` | `libs/queries/src/lib/search/searchModule.ts` | `F:path` |
|
|
84
|
+
| `Agent` | Developer, Security Expert | `A:name` |
|
|
85
|
+
| `Pattern` | Server Component data fetching, RLS policy structure | `P:name` |
|
|
86
|
+
| `Decision` | "Use Jotai over Redux" (from DECISIONS.md) | `D:name` |
|
|
87
|
+
| `Bug` | Known issue KI-XXX | `B:id` |
|
|
88
|
+
| `Lesson` | LES-XXX from LESSONS-LEARNED.md | `L:id` |
|
|
89
|
+
|
|
90
|
+
### Relationship Types
|
|
91
|
+
|
|
92
|
+
| Relationship | Meaning | Example |
|
|
93
|
+
|-------------|---------|---------|
|
|
94
|
+
| `depends-on` | X requires Y to function | `F:places/page.tsx depends-on F:searchModule.ts` |
|
|
95
|
+
| `caused-by` | X was caused by Y | `B:KI-042 caused-by D:use-server-components` |
|
|
96
|
+
| `expert-in` | Agent X has expertise in Y | `A:Content Engineer expert-in P:GROQ-queries` |
|
|
97
|
+
| `related-to` | Loose conceptual connection | `L:LES-15 related-to P:RLS-policies` |
|
|
98
|
+
| `obsoletes` | X replaces/supersedes Y | `D:use-app-router obsoletes D:use-pages-router` |
|
|
99
|
+
| `blocks` | X prevents Y from working | `B:KI-099 blocks F:auth/middleware.ts` |
|
|
100
|
+
|
|
101
|
+
### Knowledge Graph File
|
|
102
|
+
|
|
103
|
+
Location: `.github/customizations/KNOWLEDGE-GRAPH.md` — an append-only relationship log.
|
|
104
|
+
|
|
105
|
+
Template structure:
|
|
106
|
+
|
|
107
|
+
```markdown
|
|
108
|
+
# Knowledge Graph
|
|
109
|
+
|
|
110
|
+
## Relationships
|
|
111
|
+
|
|
112
|
+
| Source | Relationship | Target | Added | Context |
|
|
113
|
+
|--------|-------------|--------|-------|---------|
|
|
114
|
+
| A:Security Expert | expert-in | P:RLS-policies | 2026-02-23 | Completed 3 RLS audits |
|
|
115
|
+
| F:searchModule.ts | depends-on | F:sanity-client.ts | 2026-02-23 | Search uses Sanity client |
|
|
116
|
+
| L:LES-15 | related-to | P:cookie-sessions | 2026-02-23 | Lesson about auth token format |
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### When to Add Relationships
|
|
120
|
+
|
|
121
|
+
| Trigger | What to Record |
|
|
122
|
+
|---------|---------------|
|
|
123
|
+
| Agent completes a task touching multiple files | `depends-on` between the files |
|
|
124
|
+
| A lesson is added that relates to a pattern | `related-to` between lesson and pattern |
|
|
125
|
+
| An agent demonstrates expertise | `expert-in` between agent and domain |
|
|
126
|
+
| A decision causes a known issue | `caused-by` between bug and decision |
|
|
127
|
+
| A new pattern supersedes an old approach | `obsoletes` between decisions/patterns |
|
|
128
|
+
|
|
129
|
+
### Query Patterns
|
|
130
|
+
|
|
131
|
+
When gathering context for a delegation:
|
|
132
|
+
|
|
133
|
+
1. Find the target file(s) in the graph
|
|
134
|
+
2. Follow `depends-on` edges to identify related files the agent might need to read
|
|
135
|
+
3. Follow `expert-in` edges to confirm the right agent is assigned
|
|
136
|
+
4. Follow `related-to` edges from relevant lessons to discover applicable patterns
|
|
137
|
+
5. Check for `blocks` edges that might indicate known issues affecting the task
|
|
138
|
+
|
|
139
|
+
### Maintenance Rules
|
|
140
|
+
|
|
141
|
+
- Add relationships as you discover them — don't batch
|
|
142
|
+
- Review and prune at the start of major features (remove obsolete relationships)
|
|
143
|
+
- Keep the graph focused — max ~100 active relationships. Archive old ones quarterly
|
|
144
|
+
- Relationships are append-only during a session; pruning happens between sessions
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: api-patterns
|
|
3
|
+
description: "API design patterns for route handlers, Server Actions, Zod validation, and external API integration. Use when creating API routes, Server Actions, or integrating external services."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# API Patterns
|
|
7
|
+
|
|
8
|
+
Generic API design patterns for Next.js App Router projects. For project-specific endpoints, actions, and external API inventory, see [api-config.md](../../customizations/stack/api-config.md).
|
|
9
|
+
|
|
10
|
+
## Architecture
|
|
11
|
+
|
|
12
|
+
This project uses **Next.js App Router** API patterns:
|
|
13
|
+
|
|
14
|
+
- **Server Actions** (preferred for mutations) — form submissions, data writes, auth operations
|
|
15
|
+
- **Route Handlers** (`route.ts`) — analytics endpoints, autocomplete, external integrations
|
|
16
|
+
- **Proxy layer** — IP rate limiting, fingerprinting, bot detection
|
|
17
|
+
|
|
18
|
+
## Code Patterns
|
|
19
|
+
|
|
20
|
+
### Route Handler
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
// app/api/example/route.ts
|
|
24
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
25
|
+
import { z } from 'zod';
|
|
26
|
+
|
|
27
|
+
const schema = z.object({ query: z.string().min(1).max(200) });
|
|
28
|
+
|
|
29
|
+
export async function GET(request: NextRequest) {
|
|
30
|
+
const params = Object.fromEntries(request.nextUrl.searchParams);
|
|
31
|
+
const result = schema.safeParse(params);
|
|
32
|
+
if (!result.success) {
|
|
33
|
+
return NextResponse.json({ error: 'Invalid input' }, { status: 400 });
|
|
34
|
+
}
|
|
35
|
+
// ... process
|
|
36
|
+
return NextResponse.json(data);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Server Action
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
'use server';
|
|
44
|
+
import { createServerClient } from '@libs/supabase-auth';
|
|
45
|
+
import { revalidatePath } from 'next/cache';
|
|
46
|
+
|
|
47
|
+
export async function submitAction(formData: FormData) {
|
|
48
|
+
const supabase = await createServerClient();
|
|
49
|
+
const { data: { user } } = await supabase.auth.getUser();
|
|
50
|
+
if (!user) return { error: 'Unauthorized' };
|
|
51
|
+
// ... validate and process
|
|
52
|
+
revalidatePath('/places');
|
|
53
|
+
return { success: true };
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Design Principles
|
|
58
|
+
|
|
59
|
+
- Prefer Server Actions for mutations over API routes
|
|
60
|
+
- Always validate input with Zod schemas on the server side
|
|
61
|
+
- Return appropriate HTTP status codes and error messages
|
|
62
|
+
- Protect sensitive routes with middleware or role checks
|
|
63
|
+
- Rate limit public endpoints to prevent abuse
|
|
64
|
+
- Use Web `Request`/`Response` APIs with `NextRequest`/`NextResponse`
|
|
65
|
+
- Use CDN caching headers for public, cacheable responses
|
|
66
|
+
- Document new API endpoints in project documentation
|
|
67
|
+
|
|
68
|
+
## API Design Principles
|
|
69
|
+
|
|
70
|
+
### Route Architecture
|
|
71
|
+
- RESTful resource naming: `/api/v1/places`, `/api/v1/places/:slug`
|
|
72
|
+
- Use HTTP methods correctly: `GET` (read), `POST` (create), `PATCH` (partial update), `DELETE` (remove)
|
|
73
|
+
- Group related endpoints under a common prefix
|
|
74
|
+
- Keep URLs noun-based, not verb-based (`/api/places` not `/api/getPlaces`)
|
|
75
|
+
|
|
76
|
+
### Request/Response Schemas
|
|
77
|
+
- Define Zod schemas for all request bodies, query params, and responses
|
|
78
|
+
- Use consistent envelope format for responses:
|
|
79
|
+
```json
|
|
80
|
+
{ "data": ..., "meta": { "total": 42, "page": 1 } }
|
|
81
|
+
```
|
|
82
|
+
- Error responses follow a standard shape:
|
|
83
|
+
```json
|
|
84
|
+
{ "error": { "code": "VALIDATION_ERROR", "message": "...", "details": [...] } }
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Error Handling
|
|
88
|
+
- Use appropriate HTTP status codes (400, 401, 403, 404, 422, 429, 500)
|
|
89
|
+
- Return machine-readable error codes alongside human-readable messages
|
|
90
|
+
- Never leak internal errors — sanitize stack traces in production
|
|
91
|
+
- Provide actionable error messages when possible
|
|
92
|
+
|
|
93
|
+
### Pagination & Filtering
|
|
94
|
+
- Cursor-based pagination for large datasets (offset-based as fallback)
|
|
95
|
+
- Consistent query parameter names: `limit`, `cursor`, `sort`, `order`
|
|
96
|
+
- Filter parameters match field names: `?type=brewery&city=prague`
|
|
97
|
+
|
|
98
|
+
### Versioning
|
|
99
|
+
- URL-based versioning: `/api/v1/...`
|
|
100
|
+
- Never break existing contracts — add fields, never remove or rename
|
|
101
|
+
- Deprecation notices in response headers before removal
|
|
102
|
+
|
|
103
|
+
### Rate Limiting & Caching
|
|
104
|
+
- Define rate limits per endpoint sensitivity
|
|
105
|
+
- Set `Cache-Control` headers appropriate to content freshness
|
|
106
|
+
- Use `ETag` / `If-None-Match` for conditional requests where applicable
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: browser-testing
|
|
3
|
+
description: "Chrome DevTools MCP automation patterns for validating UI changes in real browsers. Use when performing E2E browser testing, validating visual changes, testing user interactions, or debugging UI issues with Chrome DevTools."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Browser Testing with Chrome DevTools MCP
|
|
7
|
+
|
|
8
|
+
Generic browser testing methodology using Chrome DevTools MCP. For project-specific test app, selectors, suites, and breakpoint config, see [testing-config.md](../../customizations/stack/testing-config.md).
|
|
9
|
+
|
|
10
|
+
## Purpose
|
|
11
|
+
|
|
12
|
+
After any UI change, validate in a real browser:
|
|
13
|
+
1. Start dev server if not running.
|
|
14
|
+
2. Navigate to affected pages.
|
|
15
|
+
3. Interact with UI elements (click, fill, filter).
|
|
16
|
+
4. Validate behavior and appearance.
|
|
17
|
+
5. Test edge cases (empty states, errors, boundaries).
|
|
18
|
+
6. Document findings with screenshots and pass/fail.
|
|
19
|
+
|
|
20
|
+
## Pre-Test Build Verification
|
|
21
|
+
|
|
22
|
+
**CRITICAL: Always build before browser testing.** Testing stale code wastes time. See [testing-config.md](../../customizations/stack/testing-config.md) for the specific build and serve commands.
|
|
23
|
+
|
|
24
|
+
## Chrome MCP Tools Reference
|
|
25
|
+
|
|
26
|
+
### Navigation
|
|
27
|
+
|
|
28
|
+
```javascript
|
|
29
|
+
// Navigate to page
|
|
30
|
+
mcp_chrome-devtoo_navigate_page({ type: 'url', url: 'http://localhost:<port>/places' })
|
|
31
|
+
// Reload
|
|
32
|
+
mcp_chrome-devtoo_navigate_page({ type: 'reload' })
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Interaction
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
mcp_chrome-devtoo_click({ uid: 'element_uid' })
|
|
39
|
+
mcp_chrome-devtoo_type({ uid: 'input_uid', text: 'search query' })
|
|
40
|
+
mcp_chrome-devtoo_wait_for({ text: 'Expected text' })
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Validation (preferred — lightweight)
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
// Count elements
|
|
47
|
+
mcp_chrome-devtoo_evaluate_script({
|
|
48
|
+
function: '() => document.querySelectorAll(".place-card").length'
|
|
49
|
+
})
|
|
50
|
+
// Check URL
|
|
51
|
+
mcp_chrome-devtoo_evaluate_script({
|
|
52
|
+
function: '() => window.location.href'
|
|
53
|
+
})
|
|
54
|
+
// Verify element exists
|
|
55
|
+
mcp_chrome-devtoo_evaluate_script({
|
|
56
|
+
function: '() => !!document.querySelector("[data-testid=filter-topbar]")'
|
|
57
|
+
})
|
|
58
|
+
// Get text content
|
|
59
|
+
mcp_chrome-devtoo_evaluate_script({
|
|
60
|
+
function: '() => document.querySelector("h1")?.textContent'
|
|
61
|
+
})
|
|
62
|
+
// Check URL params
|
|
63
|
+
mcp_chrome-devtoo_evaluate_script({
|
|
64
|
+
function: '() => new URL(window.location.href).searchParams.toString()'
|
|
65
|
+
})
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Screenshots (use sparingly — MAX 3 per session)
|
|
69
|
+
|
|
70
|
+
```javascript
|
|
71
|
+
mcp_chrome-devtoo_take_screenshot({ format: 'png' })
|
|
72
|
+
mcp_chrome-devtoo_take_snapshot() // DOM snapshot, lighter than screenshot
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Performance
|
|
76
|
+
|
|
77
|
+
```javascript
|
|
78
|
+
mcp_chrome-devtoo_performance_start_trace({ reload: true, autoStop: true })
|
|
79
|
+
mcp_chrome-devtoo_performance_analyze_insight({ insightSetId: 'set_id', insightName: 'LCPBreakdown' })
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Testing Workflow
|
|
83
|
+
|
|
84
|
+
### 1. Setup
|
|
85
|
+
|
|
86
|
+
Start the dev server (see [testing-config.md](../../customizations/stack/testing-config.md) for app and port).
|
|
87
|
+
|
|
88
|
+
### 2. Initial State
|
|
89
|
+
|
|
90
|
+
```javascript
|
|
91
|
+
mcp_chrome-devtoo_navigate_page({ type: 'url', url: 'http://localhost:<port>/places' })
|
|
92
|
+
mcp_chrome-devtoo_wait_for({ text: 'places' })
|
|
93
|
+
mcp_chrome-devtoo_evaluate_script({
|
|
94
|
+
function: '() => ({ url: window.location.href, title: document.title })'
|
|
95
|
+
})
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 3. Test Interactions
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
mcp_chrome-devtoo_click({ uid: 'filter_uid' })
|
|
102
|
+
mcp_chrome-devtoo_evaluate_script({
|
|
103
|
+
function: '() => document.querySelectorAll(".place-card").length'
|
|
104
|
+
})
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 4. Test Edge Cases
|
|
108
|
+
|
|
109
|
+
```javascript
|
|
110
|
+
mcp_chrome-devtoo_navigate_page({
|
|
111
|
+
type: 'url', url: 'http://localhost:<port>/places?q=nonexistent-venue-xyz'
|
|
112
|
+
})
|
|
113
|
+
mcp_chrome-devtoo_evaluate_script({
|
|
114
|
+
function: '() => !!document.querySelector("[data-testid=empty-state]")'
|
|
115
|
+
})
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 5. Console Error Check
|
|
119
|
+
|
|
120
|
+
```javascript
|
|
121
|
+
mcp_chrome-devtoo_list_console_messages()
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 6. Responsive Breakpoint Testing (MANDATORY)
|
|
125
|
+
|
|
126
|
+
**Every UI change MUST be tested at all three breakpoints.** Do not test at desktop only — most layout bugs surface at mobile or tablet widths. See [testing-config.md](../../customizations/stack/testing-config.md) for project-specific breakpoint values.
|
|
127
|
+
|
|
128
|
+
#### How to Resize
|
|
129
|
+
|
|
130
|
+
```javascript
|
|
131
|
+
// Mobile (iPhone-like)
|
|
132
|
+
mcp_chrome-devtoo_resize_page({ width: 375, height: 812 })
|
|
133
|
+
|
|
134
|
+
// Tablet (iPad-like)
|
|
135
|
+
mcp_chrome-devtoo_resize_page({ width: 768, height: 1024 })
|
|
136
|
+
|
|
137
|
+
// Desktop (standard)
|
|
138
|
+
mcp_chrome-devtoo_resize_page({ width: 1440, height: 900 })
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### Per-Breakpoint Verification
|
|
142
|
+
|
|
143
|
+
At **each** viewport size, verify:
|
|
144
|
+
|
|
145
|
+
**Mobile (375 x 812):**
|
|
146
|
+
- [ ] Sidebar/filter panel hidden — accessible via drawer/hamburger
|
|
147
|
+
- [ ] Cards stack vertically, no horizontal overflow
|
|
148
|
+
- [ ] Text truncates or wraps cleanly — no overflow or overlap
|
|
149
|
+
- [ ] Touch targets >= 44px
|
|
150
|
+
- [ ] Badges, tags, and pills wrap without horizontal scroll
|
|
151
|
+
- [ ] Map/list toggle works
|
|
152
|
+
|
|
153
|
+
**Tablet (768 x 1024):**
|
|
154
|
+
- [ ] Layout adapts — may show 2-column grid or collapsed sidebar
|
|
155
|
+
- [ ] Interactive elements have adequate spacing
|
|
156
|
+
- [ ] Images and cards resize proportionally
|
|
157
|
+
|
|
158
|
+
**Desktop (1440 x 900):**
|
|
159
|
+
- [ ] Full layout visible — sidebar + content columns
|
|
160
|
+
- [ ] Filter sidebar, content area, and any panels properly aligned
|
|
161
|
+
- [ ] No excessive whitespace or stretched elements
|
|
162
|
+
|
|
163
|
+
#### Responsive Testing Anti-Patterns
|
|
164
|
+
|
|
165
|
+
| Anti-Pattern | Correct Approach |
|
|
166
|
+
|---|---|
|
|
167
|
+
| Testing only at desktop width | Test at all 3 breakpoints (Mobile -> Tablet -> Desktop) |
|
|
168
|
+
| Skipping resize because "it uses Tailwind" | Tailwind classes can be wrong — always verify visually |
|
|
169
|
+
| Only checking layout, not interactions | Test filter drawers, dropdowns, and modals at each size |
|
|
170
|
+
| Taking 3 screenshots (one per breakpoint) | Use `evaluate_script()` to check layout; save screenshots for failures |
|
|
171
|
+
|
|
172
|
+
## Regression Re-Test Workflow
|
|
173
|
+
|
|
174
|
+
When re-testing after a fix:
|
|
175
|
+
1. Read previous `result.json` for failing tests.
|
|
176
|
+
2. Run build + lint to verify fix compiles.
|
|
177
|
+
3. Start dev server.
|
|
178
|
+
4. Re-run ALL tests from previous suite (fixes can regress other tests).
|
|
179
|
+
5. Compare results — every test must PASS.
|
|
180
|
+
6. Write updated `result.json`.
|
|
181
|
+
|
|
182
|
+
If any test still fails: analyze, fix, repeat. Do NOT stop.
|
|
183
|
+
|
|
184
|
+
## Validation Checklist
|
|
185
|
+
|
|
186
|
+
- [ ] Page loads without errors (check console)
|
|
187
|
+
- [ ] Changed component renders correctly
|
|
188
|
+
- [ ] Interactive elements respond to clicks/input
|
|
189
|
+
- [ ] Filters/sorting produce correct results
|
|
190
|
+
- [ ] URL parameters sync with UI state
|
|
191
|
+
- [ ] Empty states display when appropriate
|
|
192
|
+
- [ ] Error states handle gracefully
|
|
193
|
+
- [ ] Loading states appear during async operations
|
|
194
|
+
- [ ] Keyboard navigation works, focus is visible
|
|
195
|
+
- [ ] **Responsive: Tested at Mobile, Tablet, and Desktop breakpoints**
|
|
196
|
+
- [ ] **Responsive: No horizontal overflow at any breakpoint**
|
|
197
|
+
- [ ] **Responsive: Interactions work at every breakpoint (drawers, dropdowns, modals)**
|
|
198
|
+
|
|
199
|
+
## Context Management
|
|
200
|
+
|
|
201
|
+
- ONE focus area per session.
|
|
202
|
+
- MAX 3 screenshots — use `evaluate_script()` for most checks.
|
|
203
|
+
- Clear browser state between unrelated test flows.
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-commenting
|
|
3
|
+
description: "Guidelines for writing self-explanatory code with minimal comments. Covers when to comment (WHY not WHAT), anti-patterns to avoid, annotation tags, and public API documentation. Use when writing or reviewing code comments."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Self-explanatory Code Commenting
|
|
7
|
+
|
|
8
|
+
## Core Principle
|
|
9
|
+
|
|
10
|
+
**Write code that speaks for itself. Comment only when necessary to explain WHY, not WHAT.**
|
|
11
|
+
We do not need comments most of the time.
|
|
12
|
+
|
|
13
|
+
## Decision Framework
|
|
14
|
+
|
|
15
|
+
Before writing a comment, ask:
|
|
16
|
+
|
|
17
|
+
1. **Is the code self-explanatory?** → No comment needed
|
|
18
|
+
2. **Would a better variable/function name eliminate the need?** → Refactor instead
|
|
19
|
+
3. **Does this explain WHY, not WHAT?** → Good comment
|
|
20
|
+
4. **Will this help future maintainers?** → Good comment
|
|
21
|
+
|
|
22
|
+
## Comments to AVOID
|
|
23
|
+
|
|
24
|
+
**Obvious Comments**
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
let counter = 0; // Initialize counter to zero
|
|
28
|
+
counter++; // Increment counter by one
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Redundant Comments**
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
function getUserName() {
|
|
35
|
+
return user.name; // Return the user's name
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Outdated Comments**
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
// Calculate tax at 5% rate
|
|
43
|
+
const tax = price * 0.08; // Actually 8%
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Comments to WRITE
|
|
47
|
+
|
|
48
|
+
**Complex Business Logic**
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
// Apply progressive tax brackets: 10% up to 10k, 20% above
|
|
52
|
+
const tax = calculateProgressiveTax(income, [0.1, 0.2], [10000]);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Non-obvious Algorithms**
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
// Using Floyd-Warshall for all-pairs shortest paths
|
|
59
|
+
// because we need distances between all nodes
|
|
60
|
+
for (let k = 0; k < vertices; k++) { /* ... */ }
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Regex Patterns**
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
// Match email format: username@domain.extension
|
|
67
|
+
const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**API Constraints or Gotchas**
|
|
71
|
+
|
|
72
|
+
```javascript
|
|
73
|
+
// GitHub API rate limit: 5000 requests/hour for authenticated users
|
|
74
|
+
await rateLimiter.wait();
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Public APIs
|
|
78
|
+
|
|
79
|
+
```javascript
|
|
80
|
+
/**
|
|
81
|
+
* Calculate compound interest using the standard formula.
|
|
82
|
+
*
|
|
83
|
+
* @param {number} principal - Initial amount invested
|
|
84
|
+
* @param {number} rate - Annual interest rate (as decimal, e.g., 0.05 for 5%)
|
|
85
|
+
* @param {number} time - Time period in years
|
|
86
|
+
* @param {number} compoundFrequency - How many times per year interest compounds (default: 1)
|
|
87
|
+
* @returns {number} Final amount after compound interest
|
|
88
|
+
*/
|
|
89
|
+
function calculateCompoundInterest(principal, rate, time, compoundFrequency = 1) {
|
|
90
|
+
// ... implementation
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Configuration and Constants
|
|
95
|
+
|
|
96
|
+
```javascript
|
|
97
|
+
const MAX_RETRIES = 3; // Based on network reliability studies
|
|
98
|
+
const API_TIMEOUT = 5000; // AWS Lambda timeout is 15s, leaving buffer
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Annotation Tags
|
|
102
|
+
|
|
103
|
+
```javascript
|
|
104
|
+
// TODO: Replace with proper user authentication after security review
|
|
105
|
+
// FIXME: Memory leak in production - investigate connection pooling
|
|
106
|
+
// HACK: Workaround for bug in library v2.1.0 - remove after upgrade
|
|
107
|
+
// NOTE: This implementation assumes UTC timezone for all calculations
|
|
108
|
+
// WARNING: This function modifies the original array instead of creating a copy
|
|
109
|
+
// PERF: Consider caching this result if called frequently in hot path
|
|
110
|
+
// SECURITY: Validate input to prevent SQL injection before using in query
|
|
111
|
+
// BUG: Edge case failure when array is empty - needs investigation
|
|
112
|
+
// REFACTOR: Extract this logic into separate utility function for reusability
|
|
113
|
+
// DEPRECATED: Use newApiFunction() instead - this will be removed in v3.0
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Anti-Patterns
|
|
117
|
+
|
|
118
|
+
- **Dead code comments** — Don't comment out code; delete it (git has history)
|
|
119
|
+
- **Changelog comments** — Don't maintain change history in comments; use git
|
|
120
|
+
- **Divider comments** — Don't use decorative separators; use proper file structure
|
|
121
|
+
|
|
122
|
+
## Quality Checklist
|
|
123
|
+
|
|
124
|
+
Before committing, ensure your comments:
|
|
125
|
+
|
|
126
|
+
- [ ] Explain WHY, not WHAT
|
|
127
|
+
- [ ] Are grammatically correct and clear
|
|
128
|
+
- [ ] Will remain accurate as code evolves
|
|
129
|
+
- [ ] Add genuine value to code understanding
|
|
130
|
+
- [ ] Are placed appropriately (above the code they describe)
|
|
131
|
+
- [ ] Use proper spelling and professional language
|
|
132
|
+
|
|
133
|
+
**The best comment is the one you don't need to write because the code is self-documenting.**
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: contentful-cms
|
|
3
|
+
description: "Contentful CMS development patterns, GraphQL/REST API usage, content modeling, and migration best practices. Use when working with Contentful content types, entries, assets, or the Management API."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Contentful CMS
|
|
7
|
+
|
|
8
|
+
Generic Contentful CMS development methodology. For project-specific configuration, content types, and API keys, see [cms-config.md](../../customizations/stack/cms-config.md).
|
|
9
|
+
|
|
10
|
+
## Critical Development Rules
|
|
11
|
+
|
|
12
|
+
1. **Always use Content Types** — define structured content types before creating entries
|
|
13
|
+
2. **Prefer GraphQL API** — use the GraphQL Content API for typed, efficient queries
|
|
14
|
+
3. **Handle localization** — Contentful fields can be localized; always specify locale in queries
|
|
15
|
+
4. **Use environments** — develop in sandbox environments, promote to master via migrations
|
|
16
|
+
5. **Migration scripts** — use the Contentful CLI migration tool for schema changes, never modify content types manually in production
|
|
17
|
+
6. **Rich Text rendering** — use `@contentful/rich-text-react-renderer` for React apps
|
|
18
|
+
7. **Asset handling** — use Contentful's Image API for responsive images with transformations
|
|
19
|
+
8. **Webhook-driven** — use webhooks for cache invalidation and rebuild triggers
|
|
20
|
+
9. **Rate limiting** — respect API rate limits (Content Delivery: 78 req/s, Management: 10 req/s)
|
|
21
|
+
10. **Keep queries in shared library** — queries belong in a shared queries library, never inline in components
|
|
22
|
+
|
|
23
|
+
## Query Patterns
|
|
24
|
+
|
|
25
|
+
### GraphQL Content API
|
|
26
|
+
- Use typed GraphQL queries with code generation
|
|
27
|
+
- Leverage `sys.publishedAt` for cache invalidation
|
|
28
|
+
- Use `include` parameter to control link resolution depth
|
|
29
|
+
- Filter with `where` clauses for efficient data fetching
|
|
30
|
+
|
|
31
|
+
### REST Content Delivery API
|
|
32
|
+
- Use `content_type` parameter to filter by type
|
|
33
|
+
- Use `select` to limit returned fields
|
|
34
|
+
- Use `links_to_entry` for reverse lookups
|
|
35
|
+
- Handle pagination with `skip` and `limit`
|
|
36
|
+
|
|
37
|
+
## Content Modeling
|
|
38
|
+
|
|
39
|
+
- Use **references** for relationships between content types
|
|
40
|
+
- Prefer **short text** over **long text** for searchable fields
|
|
41
|
+
- Use **JSON fields** sparingly — prefer structured content types
|
|
42
|
+
- Design for **reusability** — create component content types for shared UI patterns
|
|
43
|
+
- Use **validation rules** on fields to enforce data quality
|