@intentsolutionsio/vercel-pack 1.0.0 → 1.0.3
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 +1 -1
- package/README.md +67 -44
- package/package.json +4 -4
- package/skills/vercel-advanced-troubleshooting/SKILL.md +185 -195
- package/skills/vercel-advanced-troubleshooting/references/errors.md +11 -0
- package/skills/vercel-advanced-troubleshooting/references/evidence-collection-framework.md +34 -0
- package/skills/vercel-advanced-troubleshooting/references/examples.md +11 -0
- package/skills/vercel-advanced-troubleshooting/references/systematic-isolation.md +56 -0
- package/skills/vercel-advanced-troubleshooting/references/timing-analysis.md +35 -0
- package/skills/vercel-architecture-variants/SKILL.md +227 -216
- package/skills/vercel-architecture-variants/references/errors.md +11 -0
- package/skills/vercel-architecture-variants/references/examples.md +12 -0
- package/skills/vercel-architecture-variants/references/variant-a-monolith-(simple).md +44 -0
- package/skills/vercel-architecture-variants/references/variant-b-service-layer-(moderate).md +72 -0
- package/skills/vercel-architecture-variants/references/variant-c-microservice-(complex).md +81 -0
- package/skills/vercel-ci-integration/SKILL.md +183 -73
- package/skills/vercel-ci-integration/references/errors.md +10 -0
- package/skills/vercel-ci-integration/references/examples.md +36 -0
- package/skills/vercel-ci-integration/references/implementation.md +54 -0
- package/skills/vercel-common-errors/SKILL.md +164 -60
- package/skills/vercel-common-errors/references/errors.md +53 -0
- package/skills/vercel-common-errors/references/examples.md +23 -0
- package/skills/vercel-cost-tuning/SKILL.md +158 -145
- package/skills/vercel-cost-tuning/references/cost-estimation.md +34 -0
- package/skills/vercel-cost-tuning/references/cost-reduction-strategies.md +40 -0
- package/skills/vercel-cost-tuning/references/errors.md +11 -0
- package/skills/vercel-cost-tuning/references/examples.md +15 -0
- package/skills/vercel-data-handling/SKILL.md +202 -155
- package/skills/vercel-data-handling/references/errors.md +11 -0
- package/skills/vercel-data-handling/references/examples.md +27 -0
- package/skills/vercel-data-handling/references/implementation.md +223 -0
- package/skills/vercel-debug-bundle/SKILL.md +163 -67
- package/skills/vercel-debug-bundle/references/errors.md +12 -0
- package/skills/vercel-debug-bundle/references/examples.md +24 -0
- package/skills/vercel-debug-bundle/references/implementation.md +54 -0
- package/skills/vercel-deploy-integration/SKILL.md +163 -156
- package/skills/vercel-deploy-integration/references/errors.md +11 -0
- package/skills/vercel-deploy-integration/references/examples.md +21 -0
- package/skills/vercel-deploy-integration/references/google-cloud-run.md +36 -0
- package/skills/vercel-deploy-integration/references/vercel-deployment.md +35 -0
- package/skills/vercel-deploy-preview/SKILL.md +164 -39
- package/skills/vercel-edge-functions/SKILL.md +185 -37
- package/skills/vercel-enterprise-rbac/SKILL.md +185 -170
- package/skills/vercel-enterprise-rbac/references/errors.md +11 -0
- package/skills/vercel-enterprise-rbac/references/examples.md +12 -0
- package/skills/vercel-enterprise-rbac/references/role-implementation.md +33 -0
- package/skills/vercel-enterprise-rbac/references/sso-integration.md +35 -0
- package/skills/vercel-hello-world/SKILL.md +141 -55
- package/skills/vercel-incident-runbook/SKILL.md +186 -138
- package/skills/vercel-incident-runbook/references/errors.md +11 -0
- package/skills/vercel-incident-runbook/references/examples.md +10 -0
- package/skills/vercel-incident-runbook/references/immediate-actions-by-error-type.md +41 -0
- package/skills/vercel-install-auth/SKILL.md +130 -53
- package/skills/vercel-known-pitfalls/SKILL.md +235 -233
- package/skills/vercel-known-pitfalls/references/errors.md +11 -0
- package/skills/vercel-known-pitfalls/references/examples.md +12 -0
- package/skills/vercel-load-scale/SKILL.md +197 -204
- package/skills/vercel-load-scale/references/capacity-planning.md +47 -0
- package/skills/vercel-load-scale/references/errors.md +11 -0
- package/skills/vercel-load-scale/references/examples.md +26 -0
- package/skills/vercel-load-scale/references/load-testing-with-k6.md +59 -0
- package/skills/vercel-load-scale/references/scaling-patterns.md +65 -0
- package/skills/vercel-local-dev-loop/SKILL.md +159 -71
- package/skills/vercel-local-dev-loop/references/errors.md +11 -0
- package/skills/vercel-local-dev-loop/references/examples.md +21 -0
- package/skills/vercel-local-dev-loop/references/implementation.md +60 -0
- package/skills/vercel-migration-deep-dive/SKILL.md +202 -187
- package/skills/vercel-migration-deep-dive/references/errors.md +11 -0
- package/skills/vercel-migration-deep-dive/references/examples.md +12 -0
- package/skills/vercel-migration-deep-dive/references/implementation-plan.md +80 -0
- package/skills/vercel-migration-deep-dive/references/pre-migration-assessment.md +39 -0
- package/skills/vercel-multi-env-setup/SKILL.md +167 -164
- package/skills/vercel-multi-env-setup/references/configuration-structure.md +59 -0
- package/skills/vercel-multi-env-setup/references/errors.md +11 -0
- package/skills/vercel-multi-env-setup/references/examples.md +11 -0
- package/skills/vercel-observability/SKILL.md +205 -195
- package/skills/vercel-observability/references/alert-configuration.md +40 -0
- package/skills/vercel-observability/references/errors.md +11 -0
- package/skills/vercel-observability/references/examples.md +13 -0
- package/skills/vercel-observability/references/metrics-collection.md +65 -0
- package/skills/vercel-performance-tuning/SKILL.md +212 -156
- package/skills/vercel-performance-tuning/references/caching-strategy.md +49 -0
- package/skills/vercel-performance-tuning/references/errors.md +11 -0
- package/skills/vercel-performance-tuning/references/examples.md +13 -0
- package/skills/vercel-policy-guardrails/SKILL.md +276 -193
- package/skills/vercel-policy-guardrails/references/errors.md +11 -0
- package/skills/vercel-policy-guardrails/references/eslint-rules.md +46 -0
- package/skills/vercel-policy-guardrails/references/examples.md +10 -0
- package/skills/vercel-prod-checklist/SKILL.md +219 -94
- package/skills/vercel-prod-checklist/references/errors.md +11 -0
- package/skills/vercel-prod-checklist/references/examples.md +25 -0
- package/skills/vercel-prod-checklist/references/implementation.md +60 -0
- package/skills/vercel-rate-limits/SKILL.md +187 -100
- package/skills/vercel-rate-limits/references/errors.md +11 -0
- package/skills/vercel-rate-limits/references/examples.md +46 -0
- package/skills/vercel-rate-limits/references/implementation.md +66 -0
- package/skills/vercel-reference-architecture/SKILL.md +226 -180
- package/skills/vercel-reference-architecture/references/errors.md +11 -0
- package/skills/vercel-reference-architecture/references/examples.md +13 -0
- package/skills/vercel-reference-architecture/references/key-components.md +65 -0
- package/skills/vercel-reference-architecture/references/project-structure.md +40 -0
- package/skills/vercel-reliability-patterns/SKILL.md +272 -211
- package/skills/vercel-reliability-patterns/references/circuit-breaker.md +36 -0
- package/skills/vercel-reliability-patterns/references/dead-letter-queue.md +48 -0
- package/skills/vercel-reliability-patterns/references/errors.md +11 -0
- package/skills/vercel-reliability-patterns/references/examples.md +11 -0
- package/skills/vercel-reliability-patterns/references/idempotency-keys.md +36 -0
- package/skills/vercel-sdk-patterns/SKILL.md +264 -92
- package/skills/vercel-sdk-patterns/references/errors.md +11 -0
- package/skills/vercel-sdk-patterns/references/examples.md +45 -0
- package/skills/vercel-sdk-patterns/references/implementation.md +67 -0
- package/skills/vercel-security-basics/SKILL.md +186 -96
- package/skills/vercel-security-basics/references/errors.md +10 -0
- package/skills/vercel-security-basics/references/examples.md +70 -0
- package/skills/vercel-security-basics/references/implementation.md +39 -0
- package/skills/vercel-upgrade-migration/SKILL.md +167 -67
- package/skills/vercel-upgrade-migration/references/errors.md +10 -0
- package/skills/vercel-upgrade-migration/references/examples.md +51 -0
- package/skills/vercel-upgrade-migration/references/implementation.md +29 -0
- package/skills/vercel-webhooks-events/SKILL.md +208 -132
- package/skills/vercel-webhooks-events/references/errors.md +11 -0
- package/skills/vercel-webhooks-events/references/event-handler-pattern.md +37 -0
- package/skills/vercel-webhooks-events/references/examples.md +16 -0
- package/skills/vercel-webhooks-events/references/signature-verification.md +33 -0
|
@@ -1,334 +1,336 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vercel-known-pitfalls
|
|
3
|
-
description:
|
|
4
|
-
|
|
3
|
+
description: 'Identify and avoid Vercel anti-patterns and common integration mistakes.
|
|
4
|
+
|
|
5
5
|
Use when reviewing Vercel code for issues, onboarding new developers,
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
or auditing existing Vercel deployments for best practice violations.
|
|
8
|
+
|
|
7
9
|
Trigger with phrases like "vercel mistakes", "vercel anti-patterns",
|
|
10
|
+
|
|
8
11
|
"vercel pitfalls", "vercel what not to do", "vercel code review".
|
|
12
|
+
|
|
13
|
+
'
|
|
9
14
|
allowed-tools: Read, Grep
|
|
10
15
|
version: 1.0.0
|
|
11
16
|
license: MIT
|
|
12
17
|
author: Jeremy Longshore <jeremy@intentsolutions.io>
|
|
18
|
+
tags:
|
|
19
|
+
- saas
|
|
20
|
+
- vercel
|
|
21
|
+
- audit
|
|
22
|
+
- anti-patterns
|
|
23
|
+
- best-practices
|
|
24
|
+
compatibility: Designed for Claude Code, also compatible with Codex and OpenClaw
|
|
13
25
|
---
|
|
14
|
-
|
|
15
26
|
# Vercel Known Pitfalls
|
|
16
27
|
|
|
17
28
|
## Overview
|
|
18
|
-
|
|
29
|
+
|
|
30
|
+
Catalog of the most common Vercel anti-patterns with severity ratings, detection methods, and fixes. Organized by category: secret exposure, serverless function mistakes, edge runtime violations, configuration errors, and cost traps.
|
|
19
31
|
|
|
20
32
|
## Prerequisites
|
|
33
|
+
|
|
21
34
|
- Access to Vercel codebase for review
|
|
22
|
-
- Understanding of
|
|
23
|
-
-
|
|
24
|
-
- Familiarity with rate limiting concepts
|
|
35
|
+
- Understanding of Vercel's deployment model
|
|
36
|
+
- Familiarity with `vercel-common-errors` for error codes
|
|
25
37
|
|
|
26
|
-
##
|
|
38
|
+
## Instructions
|
|
27
39
|
|
|
28
|
-
###
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
```
|
|
40
|
+
### Category 1: Secret Exposure (Critical)
|
|
41
|
+
|
|
42
|
+
**P1: Secrets in NEXT_PUBLIC_ variables**
|
|
37
43
|
|
|
38
|
-
### ✅ Better Approach
|
|
39
44
|
```typescript
|
|
40
|
-
//
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
//
|
|
47
|
-
async function processCheckout(data) {
|
|
48
|
-
const payment = await vercelClient.processPayment(data);
|
|
49
|
-
await vercelClient.sendEmail(payment);
|
|
50
|
-
}
|
|
45
|
+
// BAD — exposed in client JavaScript bundle, visible to anyone
|
|
46
|
+
const apiKey = process.env.NEXT_PUBLIC_API_SECRET;
|
|
47
|
+
// This value is inlined at build time into the browser bundle
|
|
48
|
+
|
|
49
|
+
// GOOD — server-only access
|
|
50
|
+
const apiKey = process.env.API_SECRET;
|
|
51
|
+
// Only accessible in serverless functions and server components
|
|
51
52
|
```
|
|
52
53
|
|
|
53
|
-
|
|
54
|
+
- **Detection:** `grep -r 'NEXT_PUBLIC_.*SECRET\|NEXT_PUBLIC_.*KEY\|NEXT_PUBLIC_.*TOKEN' src/`
|
|
55
|
+
- **Fix:** Remove `NEXT_PUBLIC_` prefix, rotate the exposed secret immediately
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
**P2: Hardcoded credentials in source**
|
|
56
58
|
|
|
57
|
-
### ❌ Anti-Pattern
|
|
58
59
|
```typescript
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
// BAD
|
|
61
|
+
const client = new Client({ apiKey: 'sk_live_abc123' });
|
|
62
|
+
|
|
63
|
+
// GOOD
|
|
64
|
+
const client = new Client({ apiKey: process.env.API_KEY });
|
|
63
65
|
```
|
|
64
66
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
import pLimit from 'p-limit';
|
|
67
|
+
- **Detection:** `grep -rE 'sk_live|sk_test|Bearer [a-zA-Z0-9]{20,}' src/ api/`
|
|
68
|
+
- **Fix:** Move to environment variables, add pre-commit hook
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
const rateLimiter = new RateLimiter({ tokensPerSecond: 10 });
|
|
70
|
+
**P3: Secrets in vercel.json**
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
```json
|
|
73
|
+
// BAD — vercel.json is committed to git
|
|
74
|
+
{
|
|
75
|
+
"env": { "API_KEY": "sk_live_abc123" }
|
|
75
76
|
}
|
|
77
|
+
|
|
78
|
+
// GOOD — use Vercel dashboard or CLI
|
|
79
|
+
// vercel env add API_KEY production
|
|
76
80
|
```
|
|
77
81
|
|
|
78
|
-
|
|
82
|
+
### Category 2: Serverless Function Mistakes (High)
|
|
79
83
|
|
|
80
|
-
|
|
84
|
+
**P4: Heavy initialization at module level**
|
|
81
85
|
|
|
82
|
-
### ❌ Anti-Pattern
|
|
83
86
|
```typescript
|
|
84
|
-
//
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
//
|
|
90
|
-
|
|
91
|
-
|
|
87
|
+
// BAD — runs on every cold start, adds 500ms+
|
|
88
|
+
import { PrismaClient } from '@prisma/client';
|
|
89
|
+
const prisma = new PrismaClient(); // Connects on import
|
|
90
|
+
const cache = await loadLargeDataset(); // Blocks cold start
|
|
91
|
+
|
|
92
|
+
// GOOD — lazy initialization
|
|
93
|
+
let prisma: PrismaClient | null = null;
|
|
94
|
+
function getDb() {
|
|
95
|
+
if (!prisma) prisma = new PrismaClient();
|
|
96
|
+
return prisma;
|
|
97
|
+
}
|
|
92
98
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
//
|
|
96
|
-
|
|
97
|
-
apiKey: process.env.VERCEL_API_KEY,
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
// Use .gitignore
|
|
101
|
-
.env
|
|
102
|
-
.env.local
|
|
103
|
-
.env.*.local
|
|
99
|
+
export default async function handler(req, res) {
|
|
100
|
+
const db = getDb(); // Only connects on first request
|
|
101
|
+
// ...
|
|
102
|
+
}
|
|
104
103
|
```
|
|
105
104
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
## Pitfall #4: Ignoring Idempotency
|
|
105
|
+
**P5: Not returning responses from all code paths**
|
|
109
106
|
|
|
110
|
-
### ❌ Anti-Pattern
|
|
111
107
|
```typescript
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if (error.code === 'NETWORK_ERROR') {
|
|
117
|
-
await vercelClient.charge(order); // Charged twice!
|
|
108
|
+
// BAD — some paths don't return, causing NO_RESPONSE_FROM_FUNCTION
|
|
109
|
+
export default function handler(req, res) {
|
|
110
|
+
if (req.method === 'GET') {
|
|
111
|
+
res.json({ data: 'ok' });
|
|
118
112
|
}
|
|
113
|
+
// POST, PUT, DELETE — no response returned!
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// GOOD
|
|
117
|
+
export default function handler(req, res) {
|
|
118
|
+
if (req.method === 'GET') {
|
|
119
|
+
return res.json({ data: 'ok' });
|
|
120
|
+
}
|
|
121
|
+
return res.status(405).json({ error: 'Method not allowed' });
|
|
119
122
|
}
|
|
120
123
|
```
|
|
121
124
|
|
|
122
|
-
|
|
125
|
+
**P6: Ignoring function timeout limits**
|
|
126
|
+
|
|
123
127
|
```typescript
|
|
124
|
-
|
|
128
|
+
// BAD — no timeout awareness, function silently killed
|
|
129
|
+
export default async function handler(req, res) {
|
|
130
|
+
const results = await processMillionRecords(); // Takes 5 minutes
|
|
131
|
+
res.json(results);
|
|
132
|
+
}
|
|
125
133
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
134
|
+
// GOOD — chunk work, respect timeout
|
|
135
|
+
export default async function handler(req, res) {
|
|
136
|
+
const batch = req.query.batch ?? 0;
|
|
137
|
+
const results = await processBatch(batch, 100); // Process 100 at a time
|
|
138
|
+
res.json({
|
|
139
|
+
results,
|
|
140
|
+
nextBatch: batch + 1,
|
|
141
|
+
done: results.length < 100,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
129
144
|
```
|
|
130
145
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
## Pitfall #5: Not Validating Webhooks
|
|
146
|
+
**P7: Connection pool exhaustion**
|
|
134
147
|
|
|
135
|
-
### ❌ Anti-Pattern
|
|
136
148
|
```typescript
|
|
137
|
-
//
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
149
|
+
// BAD — each function instance creates its own connection pool
|
|
150
|
+
// With 100 concurrent functions × 10 pool connections = 1000 DB connections
|
|
151
|
+
const pool = new Pool({ max: 10 });
|
|
152
|
+
|
|
153
|
+
// GOOD — use a connection pooler
|
|
154
|
+
// Use Prisma Accelerate, PgBouncer, or Supabase connection pooler
|
|
155
|
+
// Configure pool size to 1-2 per function instance
|
|
156
|
+
const pool = new Pool({ max: 2 });
|
|
142
157
|
```
|
|
143
158
|
|
|
144
|
-
###
|
|
159
|
+
### Category 3: Edge Runtime Violations (High)
|
|
160
|
+
|
|
161
|
+
**P8: Node.js APIs in edge functions**
|
|
162
|
+
|
|
145
163
|
```typescript
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
);
|
|
164
|
+
// BAD — these crash silently in Edge Runtime
|
|
165
|
+
export const config = { runtime: 'edge' };
|
|
166
|
+
|
|
167
|
+
import fs from 'fs'; // Not available
|
|
168
|
+
import path from 'path'; // Not available
|
|
169
|
+
import crypto from 'crypto'; // Use crypto.subtle instead
|
|
170
|
+
import { Buffer } from 'buffer'; // Use Uint8Array instead
|
|
171
|
+
|
|
172
|
+
// GOOD — Web Standard APIs
|
|
173
|
+
const hash = await crypto.subtle.digest('SHA-256', data);
|
|
174
|
+
const encoded = btoa(String.fromCharCode(...new Uint8Array(hash)));
|
|
157
175
|
```
|
|
158
176
|
|
|
159
|
-
|
|
177
|
+
- **Detection:** `grep -rn "from 'fs'\|from 'path'\|from 'crypto'\|from 'child_process'" --include="*edge*" --include="*middleware*"`
|
|
160
178
|
|
|
161
|
-
|
|
179
|
+
**P9: Dynamic code evaluation in edge**
|
|
162
180
|
|
|
163
|
-
### ❌ Anti-Pattern
|
|
164
181
|
```typescript
|
|
165
|
-
//
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
182
|
+
// BAD — throws "Dynamic Code Evaluation not allowed"
|
|
183
|
+
export const config = { runtime: 'edge' };
|
|
184
|
+
const fn = new Function('return 42'); // Not allowed
|
|
185
|
+
eval('console.log("hi")'); // Not allowed
|
|
169
186
|
|
|
170
|
-
|
|
171
|
-
|
|
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
|
-
}
|
|
187
|
+
// GOOD — use static code only
|
|
188
|
+
const fn = () => 42;
|
|
185
189
|
```
|
|
186
190
|
|
|
187
|
-
|
|
191
|
+
### Category 4: Configuration Errors (Medium)
|
|
188
192
|
|
|
189
|
-
|
|
193
|
+
**P10: Missing environment variable scoping**
|
|
190
194
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
timeout: 5000, // Too short for some operations
|
|
195
|
-
baseUrl: 'https://api.vercel.com', // Can't change for staging
|
|
196
|
-
});
|
|
197
|
-
```
|
|
195
|
+
```bash
|
|
196
|
+
# BAD — variable only in Production, preview deployments break
|
|
197
|
+
vercel env add DATABASE_URL production
|
|
198
198
|
|
|
199
|
-
|
|
200
|
-
|
|
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
|
-
});
|
|
199
|
+
# GOOD — add to all environments that need it
|
|
200
|
+
vercel env add DATABASE_URL production preview development
|
|
205
201
|
```
|
|
206
202
|
|
|
207
|
-
|
|
203
|
+
**P11: Using deprecated builds property**
|
|
208
204
|
|
|
209
|
-
|
|
205
|
+
```json
|
|
206
|
+
// BAD (deprecated)
|
|
207
|
+
{
|
|
208
|
+
"builds": [
|
|
209
|
+
{ "src": "api/**/*.ts", "use": "@vercel/node" }
|
|
210
|
+
]
|
|
211
|
+
}
|
|
210
212
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
213
|
+
// GOOD (current)
|
|
214
|
+
{
|
|
215
|
+
"functions": {
|
|
216
|
+
"api/**/*.ts": {
|
|
217
|
+
"runtime": "nodejs20.x",
|
|
218
|
+
"maxDuration": 30
|
|
219
|
+
}
|
|
220
|
+
}
|
|
216
221
|
}
|
|
217
222
|
```
|
|
218
223
|
|
|
219
|
-
|
|
220
|
-
```typescript
|
|
221
|
-
import CircuitBreaker from 'opossum';
|
|
224
|
+
**P12: Middleware running on static assets**
|
|
222
225
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
resetTimeout: 30000,
|
|
227
|
-
});
|
|
226
|
+
```typescript
|
|
227
|
+
// BAD — middleware runs on every request including static files
|
|
228
|
+
export function middleware(request) { /* auth check */ }
|
|
228
229
|
|
|
229
|
-
//
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}
|
|
230
|
+
// GOOD — exclude static assets
|
|
231
|
+
export const config = {
|
|
232
|
+
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
|
|
233
|
+
};
|
|
233
234
|
```
|
|
234
235
|
|
|
235
|
-
|
|
236
|
+
### Category 5: Cost Traps (Medium)
|
|
236
237
|
|
|
237
|
-
|
|
238
|
+
**P13: Uncached high-traffic endpoints**
|
|
238
239
|
|
|
239
|
-
### ❌ Anti-Pattern
|
|
240
240
|
```typescript
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
241
|
+
// BAD — every request invokes a function
|
|
242
|
+
export default function handler(req, res) {
|
|
243
|
+
res.json({ config: getConfig() }); // No cache headers
|
|
244
|
+
}
|
|
244
245
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
user: { id: user.id }, // Only non-sensitive fields
|
|
251
|
-
};
|
|
252
|
-
console.log('Request:', JSON.stringify(redacted));
|
|
246
|
+
// GOOD — cache at the edge, save function invocations
|
|
247
|
+
export default function handler(req, res) {
|
|
248
|
+
res.setHeader('Cache-Control', 's-maxage=3600, stale-while-revalidate=86400');
|
|
249
|
+
res.json({ config: getConfig() });
|
|
250
|
+
}
|
|
253
251
|
```
|
|
254
252
|
|
|
255
|
-
|
|
253
|
+
**P14: Over-allocated function memory**
|
|
256
254
|
|
|
257
|
-
|
|
255
|
+
```json
|
|
256
|
+
// BAD — 3GB for a simple JSON response
|
|
257
|
+
{
|
|
258
|
+
"functions": { "api/config.ts": { "memory": 3008 } }
|
|
259
|
+
}
|
|
258
260
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
261
|
+
// GOOD — right-size per endpoint
|
|
262
|
+
{
|
|
263
|
+
"functions": {
|
|
264
|
+
"api/config.ts": { "memory": 128 },
|
|
265
|
+
"api/image-process.ts": { "memory": 1024 }
|
|
266
|
+
}
|
|
267
|
+
}
|
|
264
268
|
```
|
|
265
269
|
|
|
266
|
-
|
|
270
|
+
**P15: Middleware doing heavy work**
|
|
271
|
+
|
|
267
272
|
```typescript
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
273
|
+
// BAD — database query on every request
|
|
274
|
+
export async function middleware(request) {
|
|
275
|
+
const user = await db.user.findUnique({ where: { id: token.sub } });
|
|
276
|
+
// Runs on EVERY matched request, expensive at scale
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// GOOD — validate JWT locally, no DB call
|
|
280
|
+
export function middleware(request) {
|
|
281
|
+
const token = request.cookies.get('session')?.value;
|
|
282
|
+
// Verify JWT signature locally (cheap, no external call)
|
|
274
283
|
}
|
|
275
|
-
return renderPage({ recommendations, degraded: !recommendations });
|
|
276
284
|
```
|
|
277
285
|
|
|
278
|
-
|
|
286
|
+
## Quick Audit Script
|
|
279
287
|
|
|
280
|
-
|
|
288
|
+
```bash
|
|
289
|
+
#!/usr/bin/env bash
|
|
290
|
+
echo "=== Vercel Pitfall Audit ==="
|
|
291
|
+
|
|
292
|
+
echo "P1: Secrets in NEXT_PUBLIC_:"
|
|
293
|
+
grep -rn 'NEXT_PUBLIC_.*SECRET\|NEXT_PUBLIC_.*KEY\|NEXT_PUBLIC_.*TOKEN' src/ api/ 2>/dev/null || echo " PASS"
|
|
281
294
|
|
|
282
|
-
|
|
283
|
-
|
|
295
|
+
echo "P2: Hardcoded credentials:"
|
|
296
|
+
grep -rnE 'sk_live|sk_test|Bearer [a-zA-Z0-9]{20,}' src/ api/ 2>/dev/null || echo " PASS"
|
|
284
297
|
|
|
285
|
-
|
|
286
|
-
|
|
298
|
+
echo "P8: Node.js APIs in edge files:"
|
|
299
|
+
grep -rn "from 'fs'\|from 'path'\|from 'child_process'" src/middleware.ts api/*edge* 2>/dev/null || echo " PASS"
|
|
287
300
|
|
|
288
|
-
|
|
289
|
-
|
|
301
|
+
echo "P11: Deprecated builds:"
|
|
302
|
+
jq -e '.builds' vercel.json 2>/dev/null && echo " FAIL: deprecated builds" || echo " PASS"
|
|
290
303
|
|
|
291
|
-
|
|
292
|
-
|
|
304
|
+
echo "P12: Middleware without matcher:"
|
|
305
|
+
grep -L 'matcher' src/middleware.ts 2>/dev/null && echo " WARN: no matcher configured" || echo " PASS"
|
|
306
|
+
```
|
|
293
307
|
|
|
294
308
|
## Output
|
|
295
|
-
- Anti-patterns identified
|
|
296
|
-
- Fixes prioritized and implemented
|
|
297
|
-
- Prevention measures in place
|
|
298
|
-
- Code quality improved
|
|
299
309
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
| Pattern not detected | Complex code | Manual review |
|
|
305
|
-
| False positive | Similar code | Whitelist exceptions |
|
|
306
|
-
| Fix breaks tests | Behavior change | Update tests |
|
|
310
|
+
- Anti-patterns identified and classified by severity (Critical/High/Medium)
|
|
311
|
+
- Security issues fixed and exposed secrets rotated
|
|
312
|
+
- Performance improvements from lazy initialization and caching
|
|
313
|
+
- ESLint and CI prevention measures blocking future regressions
|
|
307
314
|
|
|
308
|
-
##
|
|
315
|
+
## Error Handling
|
|
309
316
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
317
|
+
| Pitfall | Severity | Detection | Fix |
|
|
318
|
+
|---------|----------|-----------|-----|
|
|
319
|
+
| P1: NEXT_PUBLIC_ secrets | Critical | grep scan | Remove prefix, rotate secret |
|
|
320
|
+
| P4: Heavy cold starts | High | Cold start timing | Lazy initialization |
|
|
321
|
+
| P5: Missing response | High | 502 errors in logs | Return from all paths |
|
|
322
|
+
| P7: Connection exhaustion | High | DB connection errors | Use connection pooler |
|
|
323
|
+
| P8: Node.js in edge | High | EDGE_FUNCTION_INVOCATION_FAILED | Use Web APIs |
|
|
324
|
+
| P13: No cache headers | Medium | High function invocations bill | Add s-maxage |
|
|
316
325
|
|
|
317
326
|
## Resources
|
|
318
|
-
|
|
319
|
-
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
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 |
|
|
327
|
+
|
|
328
|
+
- Vercel Best Practices
|
|
329
|
+
- [Edge Runtime Limitations](https://vercel.com/docs/functions/runtimes/edge)
|
|
330
|
+
- [Function Configuration](https://vercel.com/docs/functions/configuring-functions)
|
|
331
|
+
- [Vercel Security](https://vercel.com/docs/security)
|
|
332
|
+
- [Vercel Limits](https://vercel.com/docs/limits)
|
|
333
|
+
|
|
334
|
+
## Next Steps
|
|
335
|
+
|
|
336
|
+
Return to `vercel-install-auth` for setup or `vercel-reference-architecture` for project structure.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Error Handling Reference
|
|
2
|
+
|
|
3
|
+
| Issue | Cause | Solution |
|
|
4
|
+
|-------|-------|----------|
|
|
5
|
+
| Too many findings | Legacy codebase | Prioritize security first |
|
|
6
|
+
| Pattern not detected | Complex code | Manual review |
|
|
7
|
+
| False positive | Similar code | Whitelist exceptions |
|
|
8
|
+
| Fix breaks tests | Behavior change | Update tests |
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
*[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
## Examples
|
|
2
|
+
|
|
3
|
+
### Quick Pitfall Scan
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
# Check for common pitfalls
|
|
7
|
+
grep -r "sk_live_" --include="*.ts" src/ # Key leakage
|
|
8
|
+
grep -r "console.log" --include="*.ts" src/ # Potential PII logging
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
*[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
|