@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,238 +1,284 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vercel-reference-architecture
|
|
3
|
-
description:
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
description: 'Implement a Vercel reference architecture with layered project structure
|
|
4
|
+
and best practices.
|
|
5
|
+
|
|
6
|
+
Use when designing new Vercel projects, reviewing project structure,
|
|
7
|
+
|
|
6
8
|
or establishing architecture standards for Vercel applications.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
Trigger with phrases like "vercel architecture", "vercel project structure",
|
|
11
|
+
|
|
12
|
+
"vercel best practices layout", "how to organize vercel project".
|
|
13
|
+
|
|
14
|
+
'
|
|
15
|
+
allowed-tools: Read, Write, Edit, Grep
|
|
10
16
|
version: 1.0.0
|
|
11
17
|
license: MIT
|
|
12
18
|
author: Jeremy Longshore <jeremy@intentsolutions.io>
|
|
19
|
+
tags:
|
|
20
|
+
- saas
|
|
21
|
+
- vercel
|
|
22
|
+
- architecture
|
|
23
|
+
- best-practices
|
|
24
|
+
compatibility: Designed for Claude Code, also compatible with Codex and OpenClaw
|
|
13
25
|
---
|
|
14
|
-
|
|
15
26
|
# Vercel Reference Architecture
|
|
16
27
|
|
|
17
28
|
## Overview
|
|
18
|
-
|
|
29
|
+
|
|
30
|
+
Implement a production-ready Vercel project architecture with clear separation across edge, server, and client layers. Covers directory structure, middleware patterns, API route organization, shared utilities, and configuration management.
|
|
19
31
|
|
|
20
32
|
## Prerequisites
|
|
21
|
-
|
|
22
|
-
- Vercel
|
|
33
|
+
|
|
34
|
+
- Understanding of Vercel's deployment model (edge, serverless, static)
|
|
23
35
|
- TypeScript project setup
|
|
24
|
-
-
|
|
36
|
+
- Next.js 14+ (recommended) or other Vercel-supported framework
|
|
25
37
|
|
|
26
|
-
##
|
|
38
|
+
## Instructions
|
|
39
|
+
|
|
40
|
+
### Step 1: Directory Structure
|
|
27
41
|
|
|
28
42
|
```
|
|
29
|
-
my-vercel-
|
|
43
|
+
my-vercel-app/
|
|
44
|
+
├── public/ # Static assets (served from CDN)
|
|
45
|
+
│ ├── favicon.ico
|
|
46
|
+
│ └── images/
|
|
30
47
|
├── src/
|
|
31
|
-
│ ├──
|
|
32
|
-
│ │ ├──
|
|
33
|
-
│ │ ├──
|
|
34
|
-
│ │ ├──
|
|
35
|
-
│ │ ├──
|
|
36
|
-
│ │
|
|
37
|
-
│ │
|
|
38
|
-
│ │ └──
|
|
39
|
-
│ ├──
|
|
40
|
-
│ │
|
|
41
|
-
│ │
|
|
42
|
-
│ │
|
|
43
|
-
│ │
|
|
44
|
-
│
|
|
45
|
-
│
|
|
46
|
-
│ │
|
|
47
|
-
│
|
|
48
|
-
│
|
|
49
|
-
│
|
|
50
|
-
├──
|
|
51
|
-
│ ├──
|
|
52
|
-
│ │ └──
|
|
53
|
-
│ └──
|
|
54
|
-
|
|
55
|
-
├── config
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
└── docs/
|
|
60
|
-
└── vercel/
|
|
61
|
-
├── SETUP.md
|
|
62
|
-
└── RUNBOOK.md
|
|
48
|
+
│ ├── app/ # Next.js App Router pages
|
|
49
|
+
│ │ ├── layout.tsx # Root layout
|
|
50
|
+
│ │ ├── page.tsx # Home page
|
|
51
|
+
│ │ ├── api/ # API routes (serverless functions)
|
|
52
|
+
│ │ │ ├── health/route.ts
|
|
53
|
+
│ │ │ ├── users/route.ts
|
|
54
|
+
│ │ │ └── webhooks/
|
|
55
|
+
│ │ │ └── vercel/route.ts
|
|
56
|
+
│ │ ├── dashboard/ # Protected pages
|
|
57
|
+
│ │ │ ├── layout.tsx
|
|
58
|
+
│ │ │ └── page.tsx
|
|
59
|
+
│ │ └── (marketing)/ # Public pages (route group)
|
|
60
|
+
│ │ ├── pricing/page.tsx
|
|
61
|
+
│ │ └── about/page.tsx
|
|
62
|
+
│ ├── lib/ # Shared utilities (server + client)
|
|
63
|
+
│ │ ├── api-client.ts # External API wrapper
|
|
64
|
+
│ │ ├── db.ts # Database client (lazy singleton)
|
|
65
|
+
│ │ ├── env.ts # Typed environment variables
|
|
66
|
+
│ │ └── errors.ts # Error classes
|
|
67
|
+
│ ├── components/ # React components
|
|
68
|
+
│ │ ├── ui/ # Design system primitives
|
|
69
|
+
│ │ └── features/ # Feature-specific components
|
|
70
|
+
│ └── middleware.ts # Edge Middleware (auth, redirects)
|
|
71
|
+
├── vercel.json # Vercel configuration
|
|
72
|
+
├── next.config.js # Next.js configuration
|
|
73
|
+
├── tsconfig.json
|
|
74
|
+
├── package.json
|
|
75
|
+
└── .env.example # Required env vars (no values)
|
|
63
76
|
```
|
|
64
77
|
|
|
65
|
-
|
|
78
|
+
### Step 2: Typed Environment Variables
|
|
66
79
|
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
```typescript
|
|
81
|
+
// src/lib/env.ts — validate env vars at import time
|
|
82
|
+
import { z } from 'zod';
|
|
83
|
+
|
|
84
|
+
const envSchema = z.object({
|
|
85
|
+
DATABASE_URL: z.string().url(),
|
|
86
|
+
API_SECRET: z.string().min(16),
|
|
87
|
+
NEXT_PUBLIC_API_URL: z.string().url(),
|
|
88
|
+
VERCEL_ENV: z.enum(['production', 'preview', 'development']).default('development'),
|
|
89
|
+
VERCEL_URL: z.string().optional(),
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Fails fast at startup if env vars are missing
|
|
93
|
+
export const env = envSchema.parse(process.env);
|
|
94
|
+
|
|
95
|
+
// Type-safe access throughout the app
|
|
96
|
+
// Usage: import { env } from '@/lib/env'; env.DATABASE_URL
|
|
81
97
|
```
|
|
82
98
|
|
|
83
|
-
|
|
99
|
+
### Step 3: Database Client (Lazy Singleton)
|
|
84
100
|
|
|
85
|
-
### Step 1: Client Wrapper
|
|
86
101
|
```typescript
|
|
87
|
-
// src/
|
|
88
|
-
|
|
89
|
-
private client: VercelClient;
|
|
90
|
-
private cache: Cache;
|
|
91
|
-
private monitor: Monitor;
|
|
92
|
-
|
|
93
|
-
constructor(config: VercelConfig) {
|
|
94
|
-
this.client = new VercelClient(config);
|
|
95
|
-
this.cache = new Cache(config.cacheOptions);
|
|
96
|
-
this.monitor = new Monitor('vercel');
|
|
97
|
-
}
|
|
102
|
+
// src/lib/db.ts — lazy init to minimize cold starts
|
|
103
|
+
import { PrismaClient } from '@prisma/client';
|
|
98
104
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
105
|
+
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient | undefined };
|
|
106
|
+
|
|
107
|
+
export const db = globalForPrisma.prisma ?? new PrismaClient({
|
|
108
|
+
log: process.env.VERCEL_ENV === 'development' ? ['query'] : ['error'],
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Prevent multiple instances in development (hot reload)
|
|
112
|
+
if (process.env.VERCEL_ENV !== 'production') {
|
|
113
|
+
globalForPrisma.prisma = db;
|
|
104
114
|
}
|
|
105
115
|
```
|
|
106
116
|
|
|
107
|
-
### Step
|
|
117
|
+
### Step 4: API Route Pattern
|
|
118
|
+
|
|
108
119
|
```typescript
|
|
109
|
-
// src/
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
this.name = 'VercelServiceError';
|
|
119
|
-
}
|
|
120
|
-
}
|
|
120
|
+
// src/app/api/users/route.ts
|
|
121
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
122
|
+
import { db } from '@/lib/db';
|
|
123
|
+
import { env } from '@/lib/env';
|
|
124
|
+
|
|
125
|
+
export async function GET(request: NextRequest) {
|
|
126
|
+
try {
|
|
127
|
+
const searchParams = request.nextUrl.searchParams;
|
|
128
|
+
const limit = Number(searchParams.get('limit') ?? 20);
|
|
121
129
|
|
|
122
|
-
|
|
123
|
-
|
|
130
|
+
const users = await db.user.findMany({ take: limit });
|
|
131
|
+
return NextResponse.json({ users }, {
|
|
132
|
+
headers: { 'Cache-Control': 's-maxage=60, stale-while-revalidate=300' },
|
|
133
|
+
});
|
|
134
|
+
} catch (error) {
|
|
135
|
+
console.error('GET /api/users failed:', error);
|
|
136
|
+
return NextResponse.json(
|
|
137
|
+
{ error: 'Internal server error', requestId: crypto.randomUUID() },
|
|
138
|
+
{ status: 500 }
|
|
139
|
+
);
|
|
140
|
+
}
|
|
124
141
|
}
|
|
125
|
-
```
|
|
126
142
|
|
|
127
|
-
|
|
128
|
-
```typescript
|
|
129
|
-
// src/vercel/health.ts
|
|
130
|
-
export async function checkVercelHealth(): Promise<HealthStatus> {
|
|
143
|
+
export async function POST(request: NextRequest) {
|
|
131
144
|
try {
|
|
132
|
-
const
|
|
133
|
-
await
|
|
134
|
-
return {
|
|
135
|
-
status: 'healthy',
|
|
136
|
-
latencyMs: Date.now() - start,
|
|
137
|
-
};
|
|
145
|
+
const body = await request.json();
|
|
146
|
+
const user = await db.user.create({ data: body });
|
|
147
|
+
return NextResponse.json({ user }, { status: 201 });
|
|
138
148
|
} catch (error) {
|
|
139
|
-
|
|
149
|
+
console.error('POST /api/users failed:', error);
|
|
150
|
+
return NextResponse.json(
|
|
151
|
+
{ error: 'Failed to create user' },
|
|
152
|
+
{ status: 400 }
|
|
153
|
+
);
|
|
140
154
|
}
|
|
141
155
|
}
|
|
142
156
|
```
|
|
143
157
|
|
|
144
|
-
|
|
158
|
+
### Step 5: Edge Middleware for Auth
|
|
145
159
|
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
160
|
+
```typescript
|
|
161
|
+
// src/middleware.ts
|
|
162
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
163
|
+
|
|
164
|
+
export function middleware(request: NextRequest) {
|
|
165
|
+
const { pathname } = request.nextUrl;
|
|
166
|
+
|
|
167
|
+
// Skip auth for public routes
|
|
168
|
+
if (pathname.startsWith('/api/health') || pathname.startsWith('/api/webhooks')) {
|
|
169
|
+
return NextResponse.next();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Check auth for dashboard routes
|
|
173
|
+
if (pathname.startsWith('/dashboard') || pathname.startsWith('/api/')) {
|
|
174
|
+
const token = request.cookies.get('session')?.value;
|
|
175
|
+
if (!token) {
|
|
176
|
+
if (pathname.startsWith('/api/')) {
|
|
177
|
+
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
178
|
+
}
|
|
179
|
+
return NextResponse.redirect(new URL('/login', request.url));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return NextResponse.next();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export const config = {
|
|
187
|
+
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
|
|
188
|
+
};
|
|
172
189
|
```
|
|
173
190
|
|
|
174
|
-
|
|
191
|
+
### Step 6: Health Check Endpoint
|
|
175
192
|
|
|
176
193
|
```typescript
|
|
177
|
-
//
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
timeout: number;
|
|
182
|
-
retries: number;
|
|
183
|
-
cache: {
|
|
184
|
-
enabled: boolean;
|
|
185
|
-
ttlSeconds: number;
|
|
186
|
-
};
|
|
187
|
-
}
|
|
194
|
+
// src/app/api/health/route.ts
|
|
195
|
+
import { db } from '@/lib/db';
|
|
196
|
+
|
|
197
|
+
export const dynamic = 'force-dynamic'; // Never cache health checks
|
|
188
198
|
|
|
189
|
-
export function
|
|
190
|
-
const
|
|
191
|
-
|
|
199
|
+
export async function GET() {
|
|
200
|
+
const checks: Record<string, 'ok' | 'error'> = {};
|
|
201
|
+
|
|
202
|
+
// Database connectivity
|
|
203
|
+
try {
|
|
204
|
+
await db.$queryRaw`SELECT 1`;
|
|
205
|
+
checks.database = 'ok';
|
|
206
|
+
} catch {
|
|
207
|
+
checks.database = 'error';
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const allHealthy = Object.values(checks).every(v => v === 'ok');
|
|
211
|
+
|
|
212
|
+
return Response.json({
|
|
213
|
+
status: allHealthy ? 'healthy' : 'degraded',
|
|
214
|
+
checks,
|
|
215
|
+
version: process.env.VERCEL_GIT_COMMIT_SHA?.slice(0, 7) ?? 'local',
|
|
216
|
+
region: process.env.VERCEL_REGION ?? 'local',
|
|
217
|
+
timestamp: new Date().toISOString(),
|
|
218
|
+
}, {
|
|
219
|
+
status: allHealthy ? 200 : 503,
|
|
220
|
+
});
|
|
192
221
|
}
|
|
193
222
|
```
|
|
194
223
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
### Step 1: Create Directory Structure
|
|
198
|
-
Set up the project layout following the reference structure above.
|
|
224
|
+
### Step 7: Vercel Configuration
|
|
199
225
|
|
|
200
|
-
|
|
201
|
-
|
|
226
|
+
```json
|
|
227
|
+
// vercel.json
|
|
228
|
+
{
|
|
229
|
+
"regions": ["iad1"],
|
|
230
|
+
"headers": [
|
|
231
|
+
{
|
|
232
|
+
"source": "/(.*)",
|
|
233
|
+
"headers": [
|
|
234
|
+
{ "key": "X-Content-Type-Options", "value": "nosniff" },
|
|
235
|
+
{ "key": "X-Frame-Options", "value": "DENY" },
|
|
236
|
+
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" }
|
|
237
|
+
]
|
|
238
|
+
}
|
|
239
|
+
],
|
|
240
|
+
"rewrites": [
|
|
241
|
+
{ "source": "/docs/:path*", "destination": "https://docs.example.com/:path*" }
|
|
242
|
+
],
|
|
243
|
+
"redirects": [
|
|
244
|
+
{ "source": "/old-page", "destination": "/new-page", "permanent": true }
|
|
245
|
+
]
|
|
246
|
+
}
|
|
247
|
+
```
|
|
202
248
|
|
|
203
|
-
|
|
204
|
-
Implement custom error classes for Vercel operations.
|
|
249
|
+
## Layer Responsibilities
|
|
205
250
|
|
|
206
|
-
|
|
207
|
-
|
|
251
|
+
| Layer | Runtime | Responsibilities |
|
|
252
|
+
|-------|---------|-----------------|
|
|
253
|
+
| Edge (middleware.ts) | V8 isolates | Auth, redirects, A/B testing, headers |
|
|
254
|
+
| Server (api routes) | Node.js | Database queries, business logic, webhooks |
|
|
255
|
+
| Static (pages) | CDN | Pre-rendered pages, ISR, images |
|
|
256
|
+
| Client (components) | Browser | Interactivity, client state |
|
|
208
257
|
|
|
209
258
|
## Output
|
|
210
|
-
|
|
211
|
-
-
|
|
212
|
-
-
|
|
213
|
-
-
|
|
259
|
+
|
|
260
|
+
- Layered project structure with clear separation of concerns
|
|
261
|
+
- Typed environment variables validated at startup
|
|
262
|
+
- Lazy-initialized database client minimizing cold starts
|
|
263
|
+
- Edge Middleware handling authentication before server layer
|
|
264
|
+
- Health check endpoint for deployment verification
|
|
214
265
|
|
|
215
266
|
## Error Handling
|
|
216
|
-
|
|
267
|
+
|
|
268
|
+
| Error | Cause | Solution |
|
|
217
269
|
|-------|-------|----------|
|
|
218
|
-
|
|
|
219
|
-
|
|
|
220
|
-
|
|
|
221
|
-
|
|
|
222
|
-
|
|
223
|
-
## Examples
|
|
224
|
-
|
|
225
|
-
### Quick Setup Script
|
|
226
|
-
```bash
|
|
227
|
-
# Create reference structure
|
|
228
|
-
mkdir -p src/vercel/{handlers} src/services/vercel src/api/vercel
|
|
229
|
-
touch src/vercel/{client,config,types,errors}.ts
|
|
230
|
-
touch src/services/vercel/{index,sync,cache}.ts
|
|
231
|
-
```
|
|
270
|
+
| Env validation fails on deploy | Missing required variable | Add to Vercel dashboard for target environment |
|
|
271
|
+
| Middleware runs on static assets | Matcher too broad | Add exclusions for `_next/static`, `_next/image` |
|
|
272
|
+
| Database connection pool exhausted | Too many concurrent functions | Use connection pooler (PgBouncer, Prisma Accelerate) |
|
|
273
|
+
| API route not found | Wrong directory structure | Must be in `src/app/api/` with `route.ts` filename |
|
|
232
274
|
|
|
233
275
|
## Resources
|
|
234
|
-
- [Vercel SDK Documentation](https://vercel.com/docs/sdk)
|
|
235
|
-
- [Vercel Best Practices](https://vercel.com/docs/best-practices)
|
|
236
276
|
|
|
237
|
-
|
|
238
|
-
|
|
277
|
+
- [Next.js Project Structure](https://nextjs.org/docs/getting-started/project-structure)
|
|
278
|
+
- [Vercel Project Configuration](https://vercel.com/docs/project-configuration)
|
|
279
|
+
- [Middleware Documentation](https://vercel.com/docs/functions/edge-middleware)
|
|
280
|
+
- [API Routes (App Router)](https://nextjs.org/docs/app/building-your-application/routing/route-handlers)
|
|
281
|
+
|
|
282
|
+
## Next Steps
|
|
283
|
+
|
|
284
|
+
For multi-environment setup, see `vercel-multi-env-setup`.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Error Handling Reference
|
|
2
|
+
|
|
3
|
+
| Issue | Cause | Solution |
|
|
4
|
+
|-------|-------|----------|
|
|
5
|
+
| Circular dependencies | Wrong layering | Separate concerns by layer |
|
|
6
|
+
| Config not loading | Wrong paths | Verify config file locations |
|
|
7
|
+
| Type errors | Missing types | Add Vercel types |
|
|
8
|
+
| Test isolation | Shared state | Use dependency injection |
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
*[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
## Examples
|
|
2
|
+
|
|
3
|
+
### Quick Setup Script
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
# Create reference structure
|
|
7
|
+
mkdir -p src/vercel/{handlers} src/services/vercel src/api/vercel
|
|
8
|
+
touch src/vercel/{client,config,types,errors}.ts
|
|
9
|
+
touch src/services/vercel/{index,sync,cache}.ts
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
*[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Key Components
|
|
2
|
+
|
|
3
|
+
## Key Components
|
|
4
|
+
|
|
5
|
+
### Step 1: Client Wrapper
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
// src/vercel/client.ts
|
|
9
|
+
export class VercelService {
|
|
10
|
+
private client: VercelClient;
|
|
11
|
+
private cache: Cache;
|
|
12
|
+
private monitor: Monitor;
|
|
13
|
+
|
|
14
|
+
constructor(config: VercelConfig) {
|
|
15
|
+
this.client = new VercelClient(config);
|
|
16
|
+
this.cache = new Cache(config.cacheOptions);
|
|
17
|
+
this.monitor = new Monitor('vercel');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async get(id: string): Promise<Resource> {
|
|
21
|
+
return this.cache.getOrFetch(id, () =>
|
|
22
|
+
this.monitor.track('get', () => this.client.get(id))
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Step 2: Error Boundary
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
// src/vercel/errors.ts
|
|
32
|
+
export class VercelServiceError extends Error {
|
|
33
|
+
constructor(
|
|
34
|
+
message: string,
|
|
35
|
+
public readonly code: string,
|
|
36
|
+
public readonly retryable: boolean,
|
|
37
|
+
public readonly originalError?: Error
|
|
38
|
+
) {
|
|
39
|
+
super(message);
|
|
40
|
+
this.name = 'VercelServiceError';
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function wrapVercelError(error: unknown): VercelServiceError {
|
|
45
|
+
// Transform SDK errors to application errors
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Step 3: Health Check
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// src/vercel/health.ts
|
|
53
|
+
export async function checkVercelHealth(): Promise<HealthStatus> {
|
|
54
|
+
try {
|
|
55
|
+
const start = Date.now();
|
|
56
|
+
await vercelClient.ping();
|
|
57
|
+
return {
|
|
58
|
+
status: 'healthy',
|
|
59
|
+
latencyMs: Date.now() - start,
|
|
60
|
+
};
|
|
61
|
+
} catch (error) {
|
|
62
|
+
return { status: 'unhealthy', error: error.message };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Project Structure
|
|
2
|
+
|
|
3
|
+
## Project Structure
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
my-vercel-project/
|
|
7
|
+
├── src/
|
|
8
|
+
│ ├── vercel/
|
|
9
|
+
│ │ ├── client.ts # Singleton client wrapper
|
|
10
|
+
│ │ ├── config.ts # Environment configuration
|
|
11
|
+
│ │ ├── types.ts # TypeScript types
|
|
12
|
+
│ │ ├── errors.ts # Custom error classes
|
|
13
|
+
│ │ └── handlers/
|
|
14
|
+
│ │ ├── webhooks.ts # Webhook handlers
|
|
15
|
+
│ │ └── events.ts # Event processing
|
|
16
|
+
│ ├── services/
|
|
17
|
+
│ │ └── vercel/
|
|
18
|
+
│ │ ├── index.ts # Service facade
|
|
19
|
+
│ │ ├── sync.ts # Data synchronization
|
|
20
|
+
│ │ └── cache.ts # Caching layer
|
|
21
|
+
│ ├── api/
|
|
22
|
+
│ │ └── vercel/
|
|
23
|
+
│ │ └── webhook.ts # Webhook endpoint
|
|
24
|
+
│ └── jobs/
|
|
25
|
+
│ └── vercel/
|
|
26
|
+
│ └── sync.ts # Background sync job
|
|
27
|
+
├── tests/
|
|
28
|
+
│ ├── unit/
|
|
29
|
+
│ │ └── vercel/
|
|
30
|
+
│ └── integration/
|
|
31
|
+
│ └── vercel/
|
|
32
|
+
├── config/
|
|
33
|
+
│ ├── vercel.development.json
|
|
34
|
+
│ ├── vercel.staging.json
|
|
35
|
+
│ └── vercel.production.json
|
|
36
|
+
└── docs/
|
|
37
|
+
└── vercel/
|
|
38
|
+
├── SETUP.md
|
|
39
|
+
└── RUNBOOK.md
|
|
40
|
+
```
|