@intentsolutionsio/vercel-pack 1.0.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/.claude-plugin/plugin.json +17 -0
- package/000-docs/001-BL-LICN-license.txt +3 -0
- package/LICENSE +21 -0
- package/README.md +69 -0
- package/package.json +43 -0
- package/skills/vercel-advanced-troubleshooting/SKILL.md +261 -0
- package/skills/vercel-architecture-variants/SKILL.md +284 -0
- package/skills/vercel-ci-integration/SKILL.md +124 -0
- package/skills/vercel-common-errors/SKILL.md +109 -0
- package/skills/vercel-cost-tuning/SKILL.md +201 -0
- package/skills/vercel-data-handling/SKILL.md +220 -0
- package/skills/vercel-debug-bundle/SKILL.md +111 -0
- package/skills/vercel-deploy-integration/SKILL.md +209 -0
- package/skills/vercel-deploy-preview/SKILL.md +71 -0
- package/skills/vercel-edge-functions/SKILL.md +73 -0
- package/skills/vercel-enterprise-rbac/SKILL.md +222 -0
- package/skills/vercel-hello-world/SKILL.md +96 -0
- package/skills/vercel-incident-runbook/SKILL.md +203 -0
- package/skills/vercel-install-auth/SKILL.md +90 -0
- package/skills/vercel-known-pitfalls/SKILL.md +334 -0
- package/skills/vercel-load-scale/SKILL.md +274 -0
- package/skills/vercel-local-dev-loop/SKILL.md +117 -0
- package/skills/vercel-migration-deep-dive/SKILL.md +244 -0
- package/skills/vercel-multi-env-setup/SKILL.md +222 -0
- package/skills/vercel-observability/SKILL.md +250 -0
- package/skills/vercel-performance-tuning/SKILL.md +214 -0
- package/skills/vercel-policy-guardrails/SKILL.md +257 -0
- package/skills/vercel-prod-checklist/SKILL.md +119 -0
- package/skills/vercel-rate-limits/SKILL.md +149 -0
- package/skills/vercel-reference-architecture/SKILL.md +238 -0
- package/skills/vercel-reliability-patterns/SKILL.md +290 -0
- package/skills/vercel-sdk-patterns/SKILL.md +147 -0
- package/skills/vercel-security-basics/SKILL.md +140 -0
- package/skills/vercel-upgrade-migration/SKILL.md +112 -0
- package/skills/vercel-webhooks-events/SKILL.md +199 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vercel-hello-world
|
|
3
|
+
description: |
|
|
4
|
+
Create a minimal working Vercel example.
|
|
5
|
+
Use when starting a new Vercel integration, testing your setup,
|
|
6
|
+
or learning basic Vercel API patterns.
|
|
7
|
+
Trigger with phrases like "vercel hello world", "vercel example",
|
|
8
|
+
"vercel quick start", "simple vercel code".
|
|
9
|
+
allowed-tools: Read, Write, Edit
|
|
10
|
+
version: 1.0.0
|
|
11
|
+
license: MIT
|
|
12
|
+
author: Jeremy Longshore <jeremy@intentsolutions.io>
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Vercel Hello World
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
Minimal working example demonstrating core Vercel functionality.
|
|
19
|
+
|
|
20
|
+
## Prerequisites
|
|
21
|
+
- Completed `vercel-install-auth` setup
|
|
22
|
+
- Valid API credentials configured
|
|
23
|
+
- Development environment ready
|
|
24
|
+
|
|
25
|
+
## Instructions
|
|
26
|
+
|
|
27
|
+
### Step 1: Create Entry File
|
|
28
|
+
Create a new file for your hello world example.
|
|
29
|
+
|
|
30
|
+
### Step 2: Import and Initialize Client
|
|
31
|
+
```typescript
|
|
32
|
+
import { VercelClient } from 'vercel';
|
|
33
|
+
|
|
34
|
+
const client = new VercelClient({
|
|
35
|
+
apiKey: process.env.VERCEL_API_KEY,
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Step 3: Make Your First API Call
|
|
40
|
+
```typescript
|
|
41
|
+
async function main() {
|
|
42
|
+
const projects = await vercel.projects.list(); console.log('Projects:', projects.map(p => p.name));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
main().catch(console.error);
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Output
|
|
49
|
+
- Working code file with Vercel client initialization
|
|
50
|
+
- Successful API response confirming connection
|
|
51
|
+
- Console output showing:
|
|
52
|
+
```
|
|
53
|
+
Success! Your Vercel connection is working.
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Error Handling
|
|
57
|
+
| Error | Cause | Solution |
|
|
58
|
+
|-------|-------|----------|
|
|
59
|
+
| Import Error | SDK not installed | Verify with `npm list` or `pip show` |
|
|
60
|
+
| Auth Error | Invalid credentials | Check environment variable is set |
|
|
61
|
+
| Timeout | Network issues | Increase timeout or check connectivity |
|
|
62
|
+
| Rate Limit | Too many requests | Wait and retry with exponential backoff |
|
|
63
|
+
|
|
64
|
+
## Examples
|
|
65
|
+
|
|
66
|
+
### TypeScript Example
|
|
67
|
+
```typescript
|
|
68
|
+
import { VercelClient } from 'vercel';
|
|
69
|
+
|
|
70
|
+
const client = new VercelClient({
|
|
71
|
+
apiKey: process.env.VERCEL_API_KEY,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
async function main() {
|
|
75
|
+
const projects = await vercel.projects.list(); console.log('Projects:', projects.map(p => p.name));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
main().catch(console.error);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Python Example
|
|
82
|
+
```python
|
|
83
|
+
from None import VercelClient
|
|
84
|
+
|
|
85
|
+
client = VercelClient()
|
|
86
|
+
|
|
87
|
+
None
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Resources
|
|
91
|
+
- [Vercel Getting Started](https://vercel.com/docs/getting-started)
|
|
92
|
+
- [Vercel API Reference](https://vercel.com/docs/api)
|
|
93
|
+
- [Vercel Examples](https://vercel.com/docs/examples)
|
|
94
|
+
|
|
95
|
+
## Next Steps
|
|
96
|
+
Proceed to `vercel-local-dev-loop` for development workflow setup.
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vercel-incident-runbook
|
|
3
|
+
description: |
|
|
4
|
+
Execute Vercel incident response procedures with triage, mitigation, and postmortem.
|
|
5
|
+
Use when responding to Vercel-related outages, investigating errors,
|
|
6
|
+
or running post-incident reviews for Vercel integration failures.
|
|
7
|
+
Trigger with phrases like "vercel incident", "vercel outage",
|
|
8
|
+
"vercel down", "vercel on-call", "vercel emergency", "vercel broken".
|
|
9
|
+
allowed-tools: Read, Grep, Bash(kubectl:*), Bash(curl:*)
|
|
10
|
+
version: 1.0.0
|
|
11
|
+
license: MIT
|
|
12
|
+
author: Jeremy Longshore <jeremy@intentsolutions.io>
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Vercel Incident Runbook
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
Rapid incident response procedures for Vercel-related outages.
|
|
19
|
+
|
|
20
|
+
## Prerequisites
|
|
21
|
+
- Access to Vercel dashboard and status page
|
|
22
|
+
- kubectl access to production cluster
|
|
23
|
+
- Prometheus/Grafana access
|
|
24
|
+
- Communication channels (Slack, PagerDuty)
|
|
25
|
+
|
|
26
|
+
## Severity Levels
|
|
27
|
+
|
|
28
|
+
| Level | Definition | Response Time | Examples |
|
|
29
|
+
|-------|------------|---------------|----------|
|
|
30
|
+
| P1 | Complete outage | < 15 min | Vercel API unreachable |
|
|
31
|
+
| P2 | Degraded service | < 1 hour | High latency, partial failures |
|
|
32
|
+
| P3 | Minor impact | < 4 hours | Webhook delays, non-critical errors |
|
|
33
|
+
| P4 | No user impact | Next business day | Monitoring gaps |
|
|
34
|
+
|
|
35
|
+
## Quick Triage
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# 1. Check Vercel status
|
|
39
|
+
curl -s https://www.vercel-status.com | jq
|
|
40
|
+
|
|
41
|
+
# 2. Check our integration health
|
|
42
|
+
curl -s https://api.yourapp.com/health | jq '.services.vercel'
|
|
43
|
+
|
|
44
|
+
# 3. Check error rate (last 5 min)
|
|
45
|
+
curl -s localhost:9090/api/v1/query?query=rate(vercel_errors_total[5m])
|
|
46
|
+
|
|
47
|
+
# 4. Recent error logs
|
|
48
|
+
kubectl logs -l app=vercel-integration --since=5m | grep -i error | tail -20
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Decision Tree
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
Vercel API returning errors?
|
|
55
|
+
├─ YES: Is status.vercel.com showing incident?
|
|
56
|
+
│ ├─ YES → Wait for Vercel to resolve. Enable fallback.
|
|
57
|
+
│ └─ NO → Our integration issue. Check credentials, config.
|
|
58
|
+
└─ NO: Is our service healthy?
|
|
59
|
+
├─ YES → Likely resolved or intermittent. Monitor.
|
|
60
|
+
└─ NO → Our infrastructure issue. Check pods, memory, network.
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Immediate Actions by Error Type
|
|
64
|
+
|
|
65
|
+
### 401/403 - Authentication
|
|
66
|
+
```bash
|
|
67
|
+
# Verify API key is set
|
|
68
|
+
kubectl get secret vercel-secrets -o jsonpath='{.data.api-key}' | base64 -d
|
|
69
|
+
|
|
70
|
+
# Check if key was rotated
|
|
71
|
+
# → Verify in Vercel dashboard
|
|
72
|
+
|
|
73
|
+
# Remediation: Update secret and restart pods
|
|
74
|
+
kubectl create secret generic vercel-secrets --from-literal=api-key=NEW_KEY --dry-run=client -o yaml | kubectl apply -f -
|
|
75
|
+
kubectl rollout restart deployment/vercel-integration
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 429 - Rate Limited
|
|
79
|
+
```bash
|
|
80
|
+
# Check rate limit headers
|
|
81
|
+
curl -v https://api.vercel.com 2>&1 | grep -i rate
|
|
82
|
+
|
|
83
|
+
# Enable request queuing
|
|
84
|
+
kubectl set env deployment/vercel-integration RATE_LIMIT_MODE=queue
|
|
85
|
+
|
|
86
|
+
# Long-term: Contact Vercel for limit increase
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 500/503 - Vercel Errors
|
|
90
|
+
```bash
|
|
91
|
+
# Enable graceful degradation
|
|
92
|
+
kubectl set env deployment/vercel-integration VERCEL_FALLBACK=true
|
|
93
|
+
|
|
94
|
+
# Notify users of degraded service
|
|
95
|
+
# Update status page
|
|
96
|
+
|
|
97
|
+
# Monitor Vercel status for resolution
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Communication Templates
|
|
101
|
+
|
|
102
|
+
### Internal (Slack)
|
|
103
|
+
```
|
|
104
|
+
🔴 P1 INCIDENT: Vercel Integration
|
|
105
|
+
Status: INVESTIGATING
|
|
106
|
+
Impact: [Describe user impact]
|
|
107
|
+
Current action: [What you're doing]
|
|
108
|
+
Next update: [Time]
|
|
109
|
+
Incident commander: @[name]
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### External (Status Page)
|
|
113
|
+
```
|
|
114
|
+
Vercel Integration Issue
|
|
115
|
+
|
|
116
|
+
We're experiencing issues with our Vercel integration.
|
|
117
|
+
Some users may experience [specific impact].
|
|
118
|
+
|
|
119
|
+
We're actively investigating and will provide updates.
|
|
120
|
+
|
|
121
|
+
Last updated: [timestamp]
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Post-Incident
|
|
125
|
+
|
|
126
|
+
### Evidence Collection
|
|
127
|
+
```bash
|
|
128
|
+
# Generate debug bundle
|
|
129
|
+
./scripts/vercel-debug-bundle.sh
|
|
130
|
+
|
|
131
|
+
# Export relevant logs
|
|
132
|
+
kubectl logs -l app=vercel-integration --since=1h > incident-logs.txt
|
|
133
|
+
|
|
134
|
+
# Capture metrics
|
|
135
|
+
curl "localhost:9090/api/v1/query_range?query=vercel_errors_total&start=2h" > metrics.json
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Postmortem Template
|
|
139
|
+
```markdown
|
|
140
|
+
## Incident: Vercel [Error Type]
|
|
141
|
+
**Date:** YYYY-MM-DD
|
|
142
|
+
**Duration:** X hours Y minutes
|
|
143
|
+
**Severity:** P[1-4]
|
|
144
|
+
|
|
145
|
+
### Summary
|
|
146
|
+
[1-2 sentence description]
|
|
147
|
+
|
|
148
|
+
### Timeline
|
|
149
|
+
- HH:MM - [Event]
|
|
150
|
+
- HH:MM - [Event]
|
|
151
|
+
|
|
152
|
+
### Root Cause
|
|
153
|
+
[Technical explanation]
|
|
154
|
+
|
|
155
|
+
### Impact
|
|
156
|
+
- Users affected: N
|
|
157
|
+
- Revenue impact: $X
|
|
158
|
+
|
|
159
|
+
### Action Items
|
|
160
|
+
- [ ] [Preventive measure] - Owner - Due date
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Instructions
|
|
164
|
+
|
|
165
|
+
### Step 1: Quick Triage
|
|
166
|
+
Run the triage commands to identify the issue source.
|
|
167
|
+
|
|
168
|
+
### Step 2: Follow Decision Tree
|
|
169
|
+
Determine if the issue is Vercel-side or internal.
|
|
170
|
+
|
|
171
|
+
### Step 3: Execute Immediate Actions
|
|
172
|
+
Apply the appropriate remediation for the error type.
|
|
173
|
+
|
|
174
|
+
### Step 4: Communicate Status
|
|
175
|
+
Update internal and external stakeholders.
|
|
176
|
+
|
|
177
|
+
## Output
|
|
178
|
+
- Issue identified and categorized
|
|
179
|
+
- Remediation applied
|
|
180
|
+
- Stakeholders notified
|
|
181
|
+
- Evidence collected for postmortem
|
|
182
|
+
|
|
183
|
+
## Error Handling
|
|
184
|
+
| Issue | Cause | Solution |
|
|
185
|
+
|-------|-------|----------|
|
|
186
|
+
| Can't reach status page | Network issue | Use mobile or VPN |
|
|
187
|
+
| kubectl fails | Auth expired | Re-authenticate |
|
|
188
|
+
| Metrics unavailable | Prometheus down | Check backup metrics |
|
|
189
|
+
| Secret rotation fails | Permission denied | Escalate to admin |
|
|
190
|
+
|
|
191
|
+
## Examples
|
|
192
|
+
|
|
193
|
+
### One-Line Health Check
|
|
194
|
+
```bash
|
|
195
|
+
curl -sf https://api.yourapp.com/health | jq '.services.vercel.status' || echo "UNHEALTHY"
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Resources
|
|
199
|
+
- [Vercel Status Page](https://www.vercel-status.com)
|
|
200
|
+
- [Vercel Support](https://support.vercel.com)
|
|
201
|
+
|
|
202
|
+
## Next Steps
|
|
203
|
+
For data handling, see `vercel-data-handling`.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vercel-install-auth
|
|
3
|
+
description: |
|
|
4
|
+
Install and configure Vercel SDK/CLI authentication.
|
|
5
|
+
Use when setting up a new Vercel integration, configuring API keys,
|
|
6
|
+
or initializing Vercel in your project.
|
|
7
|
+
Trigger with phrases like "install vercel", "setup vercel",
|
|
8
|
+
"vercel auth", "configure vercel API key".
|
|
9
|
+
allowed-tools: Read, Write, Edit, Bash(npm:*), Bash(pip:*), Grep
|
|
10
|
+
version: 1.0.0
|
|
11
|
+
license: MIT
|
|
12
|
+
author: Jeremy Longshore <jeremy@intentsolutions.io>
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Vercel Install & Auth
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
Set up Vercel SDK/CLI and configure authentication credentials.
|
|
19
|
+
|
|
20
|
+
## Prerequisites
|
|
21
|
+
- Node.js 18+ or Python 3.10+
|
|
22
|
+
- Package manager (npm, pnpm, or pip)
|
|
23
|
+
- Vercel account with API access
|
|
24
|
+
- API key from Vercel dashboard
|
|
25
|
+
|
|
26
|
+
## Instructions
|
|
27
|
+
|
|
28
|
+
### Step 1: Install SDK
|
|
29
|
+
```bash
|
|
30
|
+
# Node.js
|
|
31
|
+
npm install vercel
|
|
32
|
+
|
|
33
|
+
# Python
|
|
34
|
+
pip install None
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Step 2: Configure Authentication
|
|
38
|
+
```bash
|
|
39
|
+
# Set environment variable
|
|
40
|
+
export VERCEL_API_KEY="your-api-key"
|
|
41
|
+
|
|
42
|
+
# Or create .env file
|
|
43
|
+
echo 'VERCEL_API_KEY=your-api-key' >> .env
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Step 3: Verify Connection
|
|
47
|
+
```typescript
|
|
48
|
+
const teams = await vercel.teams.list(); console.log(teams.length > 0 ? 'OK' : 'No teams');
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Output
|
|
52
|
+
- Installed SDK package in node_modules or site-packages
|
|
53
|
+
- Environment variable or .env file with API key
|
|
54
|
+
- Successful connection verification output
|
|
55
|
+
|
|
56
|
+
## Error Handling
|
|
57
|
+
| Error | Cause | Solution |
|
|
58
|
+
|-------|-------|----------|
|
|
59
|
+
| Invalid API Key | Incorrect or expired key | Verify key in Vercel dashboard |
|
|
60
|
+
| Rate Limited | Exceeded quota | Check quota at https://vercel.com/docs |
|
|
61
|
+
| Network Error | Firewall blocking | Ensure outbound HTTPS allowed |
|
|
62
|
+
| Module Not Found | Installation failed | Run `npm install` or `pip install` again |
|
|
63
|
+
|
|
64
|
+
## Examples
|
|
65
|
+
|
|
66
|
+
### TypeScript Setup
|
|
67
|
+
```typescript
|
|
68
|
+
import { VercelClient } from 'vercel';
|
|
69
|
+
|
|
70
|
+
const client = new VercelClient({
|
|
71
|
+
apiKey: process.env.VERCEL_API_KEY,
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Python Setup
|
|
76
|
+
```python
|
|
77
|
+
from None import VercelClient
|
|
78
|
+
|
|
79
|
+
client = VercelClient(
|
|
80
|
+
api_key=os.environ.get('VERCEL_API_KEY')
|
|
81
|
+
)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Resources
|
|
85
|
+
- [Vercel Documentation](https://vercel.com/docs)
|
|
86
|
+
- [Vercel Dashboard](https://api.vercel.com)
|
|
87
|
+
- [Vercel Status](https://www.vercel-status.com)
|
|
88
|
+
|
|
89
|
+
## Next Steps
|
|
90
|
+
After successful auth, proceed to `vercel-hello-world` for your first API call.
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vercel-known-pitfalls
|
|
3
|
+
description: |
|
|
4
|
+
Identify and avoid Vercel anti-patterns and common integration mistakes.
|
|
5
|
+
Use when reviewing Vercel code for issues, onboarding new developers,
|
|
6
|
+
or auditing existing Vercel integrations for best practices violations.
|
|
7
|
+
Trigger with phrases like "vercel mistakes", "vercel anti-patterns",
|
|
8
|
+
"vercel pitfalls", "vercel what not to do", "vercel code review".
|
|
9
|
+
allowed-tools: Read, Grep
|
|
10
|
+
version: 1.0.0
|
|
11
|
+
license: MIT
|
|
12
|
+
author: Jeremy Longshore <jeremy@intentsolutions.io>
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Vercel Known Pitfalls
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
Common mistakes and anti-patterns when integrating with Vercel.
|
|
19
|
+
|
|
20
|
+
## Prerequisites
|
|
21
|
+
- Access to Vercel codebase for review
|
|
22
|
+
- Understanding of async/await patterns
|
|
23
|
+
- Knowledge of security best practices
|
|
24
|
+
- Familiarity with rate limiting concepts
|
|
25
|
+
|
|
26
|
+
## Pitfall #1: Synchronous API Calls in Request Path
|
|
27
|
+
|
|
28
|
+
### ❌ Anti-Pattern
|
|
29
|
+
```typescript
|
|
30
|
+
// User waits for Vercel API call
|
|
31
|
+
app.post('/checkout', async (req, res) => {
|
|
32
|
+
const payment = await vercelClient.processPayment(req.body); // 2-5s latency
|
|
33
|
+
const notification = await vercelClient.sendEmail(payment); // Another 1-2s
|
|
34
|
+
res.json({ success: true }); // User waited 3-7s
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### ✅ Better Approach
|
|
39
|
+
```typescript
|
|
40
|
+
// Return immediately, process async
|
|
41
|
+
app.post('/checkout', async (req, res) => {
|
|
42
|
+
const jobId = await queue.enqueue('process-checkout', req.body);
|
|
43
|
+
res.json({ jobId, status: 'processing' }); // 50ms response
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Background job
|
|
47
|
+
async function processCheckout(data) {
|
|
48
|
+
const payment = await vercelClient.processPayment(data);
|
|
49
|
+
await vercelClient.sendEmail(payment);
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Pitfall #2: Not Handling Rate Limits
|
|
56
|
+
|
|
57
|
+
### ❌ Anti-Pattern
|
|
58
|
+
```typescript
|
|
59
|
+
// Blast requests, crash on 429
|
|
60
|
+
for (const item of items) {
|
|
61
|
+
await vercelClient.process(item); // Will hit rate limit
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### ✅ Better Approach
|
|
66
|
+
```typescript
|
|
67
|
+
import pLimit from 'p-limit';
|
|
68
|
+
|
|
69
|
+
const limit = pLimit(5); // Max 5 concurrent
|
|
70
|
+
const rateLimiter = new RateLimiter({ tokensPerSecond: 10 });
|
|
71
|
+
|
|
72
|
+
for (const item of items) {
|
|
73
|
+
await rateLimiter.acquire();
|
|
74
|
+
await limit(() => vercelClient.process(item));
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Pitfall #3: Leaking API Keys
|
|
81
|
+
|
|
82
|
+
### ❌ Anti-Pattern
|
|
83
|
+
```typescript
|
|
84
|
+
// In frontend code (visible to users!)
|
|
85
|
+
const client = new VercelClient({
|
|
86
|
+
apiKey: 'sk_live_ACTUAL_KEY_HERE', // Anyone can see this
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// In git history
|
|
90
|
+
git commit -m "add API key" // Exposed forever
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### ✅ Better Approach
|
|
94
|
+
```typescript
|
|
95
|
+
// Backend only, environment variable
|
|
96
|
+
const client = new VercelClient({
|
|
97
|
+
apiKey: process.env.VERCEL_API_KEY,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Use .gitignore
|
|
101
|
+
.env
|
|
102
|
+
.env.local
|
|
103
|
+
.env.*.local
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Pitfall #4: Ignoring Idempotency
|
|
109
|
+
|
|
110
|
+
### ❌ Anti-Pattern
|
|
111
|
+
```typescript
|
|
112
|
+
// Network error on response = duplicate charge!
|
|
113
|
+
try {
|
|
114
|
+
await vercelClient.charge(order);
|
|
115
|
+
} catch (error) {
|
|
116
|
+
if (error.code === 'NETWORK_ERROR') {
|
|
117
|
+
await vercelClient.charge(order); // Charged twice!
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### ✅ Better Approach
|
|
123
|
+
```typescript
|
|
124
|
+
const idempotencyKey = `order-${order.id}-${Date.now()}`;
|
|
125
|
+
|
|
126
|
+
await vercelClient.charge(order, {
|
|
127
|
+
idempotencyKey, // Safe to retry
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Pitfall #5: Not Validating Webhooks
|
|
134
|
+
|
|
135
|
+
### ❌ Anti-Pattern
|
|
136
|
+
```typescript
|
|
137
|
+
// Trust any incoming request
|
|
138
|
+
app.post('/webhook', (req, res) => {
|
|
139
|
+
processWebhook(req.body); // Attacker can send fake events
|
|
140
|
+
res.sendStatus(200);
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### ✅ Better Approach
|
|
145
|
+
```typescript
|
|
146
|
+
app.post('/webhook',
|
|
147
|
+
express.raw({ type: 'application/json' }),
|
|
148
|
+
(req, res) => {
|
|
149
|
+
const signature = req.headers['x-vercel-signature'];
|
|
150
|
+
if (!verifyVercelSignature(req.body, signature)) {
|
|
151
|
+
return res.sendStatus(401);
|
|
152
|
+
}
|
|
153
|
+
processWebhook(JSON.parse(req.body));
|
|
154
|
+
res.sendStatus(200);
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Pitfall #6: Missing Error Handling
|
|
162
|
+
|
|
163
|
+
### ❌ Anti-Pattern
|
|
164
|
+
```typescript
|
|
165
|
+
// Crashes on any error
|
|
166
|
+
const result = await vercelClient.get(id);
|
|
167
|
+
console.log(result.data.nested.value); // TypeError if missing
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### ✅ Better Approach
|
|
171
|
+
```typescript
|
|
172
|
+
try {
|
|
173
|
+
const result = await vercelClient.get(id);
|
|
174
|
+
console.log(result?.data?.nested?.value ?? 'default');
|
|
175
|
+
} catch (error) {
|
|
176
|
+
if (error instanceof VercelNotFoundError) {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
if (error instanceof VercelRateLimitError) {
|
|
180
|
+
await sleep(error.retryAfter);
|
|
181
|
+
return this.get(id); // Retry
|
|
182
|
+
}
|
|
183
|
+
throw error; // Rethrow unknown errors
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Pitfall #7: Hardcoding Configuration
|
|
190
|
+
|
|
191
|
+
### ❌ Anti-Pattern
|
|
192
|
+
```typescript
|
|
193
|
+
const client = new VercelClient({
|
|
194
|
+
timeout: 5000, // Too short for some operations
|
|
195
|
+
baseUrl: 'https://api.vercel.com', // Can't change for staging
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### ✅ Better Approach
|
|
200
|
+
```typescript
|
|
201
|
+
const client = new VercelClient({
|
|
202
|
+
timeout: parseInt(process.env.VERCEL_TIMEOUT || '30000'),
|
|
203
|
+
baseUrl: process.env.VERCEL_BASE_URL || 'https://api.vercel.com',
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Pitfall #8: Not Implementing Circuit Breaker
|
|
210
|
+
|
|
211
|
+
### ❌ Anti-Pattern
|
|
212
|
+
```typescript
|
|
213
|
+
// When Vercel is down, every request hangs
|
|
214
|
+
for (const user of users) {
|
|
215
|
+
await vercelClient.sync(user); // All timeout sequentially
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### ✅ Better Approach
|
|
220
|
+
```typescript
|
|
221
|
+
import CircuitBreaker from 'opossum';
|
|
222
|
+
|
|
223
|
+
const breaker = new CircuitBreaker(vercelClient.sync, {
|
|
224
|
+
timeout: 10000,
|
|
225
|
+
errorThresholdPercentage: 50,
|
|
226
|
+
resetTimeout: 30000,
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Fails fast when circuit is open
|
|
230
|
+
for (const user of users) {
|
|
231
|
+
await breaker.fire(user).catch(handleFailure);
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Pitfall #9: Logging Sensitive Data
|
|
238
|
+
|
|
239
|
+
### ❌ Anti-Pattern
|
|
240
|
+
```typescript
|
|
241
|
+
console.log('Request:', JSON.stringify(request)); // Logs API key, PII
|
|
242
|
+
console.log('User:', user); // Logs email, phone
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### ✅ Better Approach
|
|
246
|
+
```typescript
|
|
247
|
+
const redacted = {
|
|
248
|
+
...request,
|
|
249
|
+
apiKey: '[REDACTED]',
|
|
250
|
+
user: { id: user.id }, // Only non-sensitive fields
|
|
251
|
+
};
|
|
252
|
+
console.log('Request:', JSON.stringify(redacted));
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Pitfall #10: No Graceful Degradation
|
|
258
|
+
|
|
259
|
+
### ❌ Anti-Pattern
|
|
260
|
+
```typescript
|
|
261
|
+
// Entire feature broken if Vercel is down
|
|
262
|
+
const recommendations = await vercelClient.getRecommendations(userId);
|
|
263
|
+
return renderPage({ recommendations }); // Page crashes
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### ✅ Better Approach
|
|
267
|
+
```typescript
|
|
268
|
+
let recommendations;
|
|
269
|
+
try {
|
|
270
|
+
recommendations = await vercelClient.getRecommendations(userId);
|
|
271
|
+
} catch (error) {
|
|
272
|
+
recommendations = await getFallbackRecommendations(userId);
|
|
273
|
+
reportDegradedService('vercel', error);
|
|
274
|
+
}
|
|
275
|
+
return renderPage({ recommendations, degraded: !recommendations });
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Instructions
|
|
281
|
+
|
|
282
|
+
### Step 1: Review for Anti-Patterns
|
|
283
|
+
Scan codebase for each pitfall pattern.
|
|
284
|
+
|
|
285
|
+
### Step 2: Prioritize Fixes
|
|
286
|
+
Address security issues first, then performance.
|
|
287
|
+
|
|
288
|
+
### Step 3: Implement Better Approach
|
|
289
|
+
Replace anti-patterns with recommended patterns.
|
|
290
|
+
|
|
291
|
+
### Step 4: Add Prevention
|
|
292
|
+
Set up linting and CI checks to prevent recurrence.
|
|
293
|
+
|
|
294
|
+
## Output
|
|
295
|
+
- Anti-patterns identified
|
|
296
|
+
- Fixes prioritized and implemented
|
|
297
|
+
- Prevention measures in place
|
|
298
|
+
- Code quality improved
|
|
299
|
+
|
|
300
|
+
## Error Handling
|
|
301
|
+
| Issue | Cause | Solution |
|
|
302
|
+
|-------|-------|----------|
|
|
303
|
+
| Too many findings | Legacy codebase | Prioritize security first |
|
|
304
|
+
| Pattern not detected | Complex code | Manual review |
|
|
305
|
+
| False positive | Similar code | Whitelist exceptions |
|
|
306
|
+
| Fix breaks tests | Behavior change | Update tests |
|
|
307
|
+
|
|
308
|
+
## Examples
|
|
309
|
+
|
|
310
|
+
### Quick Pitfall Scan
|
|
311
|
+
```bash
|
|
312
|
+
# Check for common pitfalls
|
|
313
|
+
grep -r "sk_live_" --include="*.ts" src/ # Key leakage
|
|
314
|
+
grep -r "console.log" --include="*.ts" src/ # Potential PII logging
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## Resources
|
|
318
|
+
- [Vercel Security Guide](https://vercel.com/docs/security)
|
|
319
|
+
- [Vercel Best Practices](https://vercel.com/docs/best-practices)
|
|
320
|
+
|
|
321
|
+
## Quick Reference Card
|
|
322
|
+
|
|
323
|
+
| Pitfall | Detection | Prevention |
|
|
324
|
+
|---------|-----------|------------|
|
|
325
|
+
| Sync in request | High latency | Use queues |
|
|
326
|
+
| Rate limit ignore | 429 errors | Implement backoff |
|
|
327
|
+
| Key leakage | Git history scan | Env vars, .gitignore |
|
|
328
|
+
| No idempotency | Duplicate records | Idempotency keys |
|
|
329
|
+
| Unverified webhooks | Security audit | Signature verification |
|
|
330
|
+
| Missing error handling | Crashes | Try-catch, types |
|
|
331
|
+
| Hardcoded config | Code review | Environment variables |
|
|
332
|
+
| No circuit breaker | Cascading failures | opossum, resilience4j |
|
|
333
|
+
| Logging PII | Log audit | Redaction middleware |
|
|
334
|
+
| No degradation | Total outages | Fallback systems |
|