@odvi/create-dtt-framework 0.1.3 → 0.1.6

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.
Files changed (111) hide show
  1. package/dist/commands/create.d.ts.map +1 -1
  2. package/dist/commands/create.js +16 -13
  3. package/dist/commands/create.js.map +1 -1
  4. package/package.json +3 -2
  5. package/template/.env.example +106 -0
  6. package/template/components.json +22 -0
  7. package/template/docs/framework/01-overview.md +289 -0
  8. package/template/docs/framework/02-techstack.md +503 -0
  9. package/template/docs/framework/api-layer.md +681 -0
  10. package/template/docs/framework/clerk-authentication.md +649 -0
  11. package/template/docs/framework/cli-installation.md +564 -0
  12. package/template/docs/framework/deployment/ci-cd.md +907 -0
  13. package/template/docs/framework/deployment/digitalocean.md +991 -0
  14. package/template/docs/framework/deployment/domain-setup.md +972 -0
  15. package/template/docs/framework/deployment/environment-variables.md +862 -0
  16. package/template/docs/framework/deployment/monitoring.md +927 -0
  17. package/template/docs/framework/deployment/production-checklist.md +649 -0
  18. package/template/docs/framework/deployment/vercel.md +791 -0
  19. package/template/docs/framework/environment-variables.md +646 -0
  20. package/template/docs/framework/health-check-system.md +583 -0
  21. package/template/docs/framework/implementation.md +559 -0
  22. package/template/docs/framework/snowflake-integration.md +594 -0
  23. package/template/docs/framework/state-management.md +615 -0
  24. package/template/docs/framework/supabase-integration.md +582 -0
  25. package/template/docs/framework/testing-guide.md +544 -0
  26. package/template/docs/framework/what-did-i-miss.md +526 -0
  27. package/template/drizzle.config.ts +11 -0
  28. package/template/next.config.js +21 -0
  29. package/template/postcss.config.js +5 -0
  30. package/template/prettier.config.js +4 -0
  31. package/template/public/favicon.ico +0 -0
  32. package/template/src/app/(auth)/layout.tsx +4 -0
  33. package/template/src/app/(auth)/sign-in/[[...sign-in]]/page.tsx +10 -0
  34. package/template/src/app/(auth)/sign-up/[[...sign-up]]/page.tsx +10 -0
  35. package/template/src/app/(dashboard)/dashboard/page.tsx +8 -0
  36. package/template/src/app/(dashboard)/health/page.tsx +16 -0
  37. package/template/src/app/(dashboard)/layout.tsx +17 -0
  38. package/template/src/app/api/[[...route]]/route.ts +11 -0
  39. package/template/src/app/api/debug-files/route.ts +33 -0
  40. package/template/src/app/api/webhooks/clerk/route.ts +112 -0
  41. package/template/src/app/layout.tsx +28 -0
  42. package/template/src/app/page.tsx +12 -0
  43. package/template/src/app/providers.tsx +20 -0
  44. package/template/src/components/layouts/navbar.tsx +14 -0
  45. package/template/src/components/shared/loading-spinner.tsx +6 -0
  46. package/template/src/components/ui/badge.tsx +46 -0
  47. package/template/src/components/ui/button.tsx +62 -0
  48. package/template/src/components/ui/card.tsx +92 -0
  49. package/template/src/components/ui/collapsible.tsx +33 -0
  50. package/template/src/components/ui/scroll-area.tsx +58 -0
  51. package/template/src/components/ui/sheet.tsx +139 -0
  52. package/template/src/config/__tests__/env.test.ts +164 -0
  53. package/template/src/config/__tests__/site.test.ts +46 -0
  54. package/template/src/config/env.ts +36 -0
  55. package/template/src/config/site.ts +10 -0
  56. package/template/src/env.js +44 -0
  57. package/template/src/features/__tests__/health-check-config.test.ts +142 -0
  58. package/template/src/features/__tests__/health-check-types.test.ts +201 -0
  59. package/template/src/features/documentation/components/doc-sidebar.tsx +109 -0
  60. package/template/src/features/documentation/components/doc-viewer.tsx +70 -0
  61. package/template/src/features/documentation/index.tsx +92 -0
  62. package/template/src/features/documentation/utils/doc-loader.ts +177 -0
  63. package/template/src/features/health-check/components/health-dashboard.tsx +374 -0
  64. package/template/src/features/health-check/config.ts +71 -0
  65. package/template/src/features/health-check/index.ts +4 -0
  66. package/template/src/features/health-check/stores/health-store.ts +14 -0
  67. package/template/src/features/health-check/types.ts +18 -0
  68. package/template/src/hooks/__tests__/use-debounce.test.tsx +28 -0
  69. package/template/src/hooks/queries/use-health-checks.ts +16 -0
  70. package/template/src/hooks/utils/use-debounce.ts +20 -0
  71. package/template/src/lib/__tests__/utils.test.ts +52 -0
  72. package/template/src/lib/__tests__/validators.test.ts +114 -0
  73. package/template/src/lib/nextbank/client.ts +67 -0
  74. package/template/src/lib/snowflake/client.ts +102 -0
  75. package/template/src/lib/supabase/admin.ts +7 -0
  76. package/template/src/lib/supabase/client.ts +7 -0
  77. package/template/src/lib/supabase/server.ts +23 -0
  78. package/template/src/lib/utils.ts +6 -0
  79. package/template/src/lib/validators.ts +9 -0
  80. package/template/src/middleware.ts +22 -0
  81. package/template/src/server/api/index.ts +22 -0
  82. package/template/src/server/api/middleware/auth.ts +19 -0
  83. package/template/src/server/api/middleware/logger.ts +4 -0
  84. package/template/src/server/api/routes/health/clerk.ts +214 -0
  85. package/template/src/server/api/routes/health/database.ts +141 -0
  86. package/template/src/server/api/routes/health/edge-functions.ts +107 -0
  87. package/template/src/server/api/routes/health/framework.ts +48 -0
  88. package/template/src/server/api/routes/health/index.ts +102 -0
  89. package/template/src/server/api/routes/health/nextbank.ts +46 -0
  90. package/template/src/server/api/routes/health/snowflake.ts +83 -0
  91. package/template/src/server/api/routes/health/storage.ts +177 -0
  92. package/template/src/server/api/routes/users.ts +79 -0
  93. package/template/src/server/db/index.ts +17 -0
  94. package/template/src/server/db/queries/users.ts +8 -0
  95. package/template/src/server/db/schema/__tests__/health-checks.test.ts +31 -0
  96. package/template/src/server/db/schema/__tests__/users.test.ts +46 -0
  97. package/template/src/server/db/schema/health-checks.ts +11 -0
  98. package/template/src/server/db/schema/index.ts +2 -0
  99. package/template/src/server/db/schema/users.ts +16 -0
  100. package/template/src/server/db/schema.ts +1 -0
  101. package/template/src/stores/__tests__/ui-store.test.ts +87 -0
  102. package/template/src/stores/ui-store.ts +14 -0
  103. package/template/src/styles/globals.css +129 -0
  104. package/template/src/test/mocks/clerk.ts +35 -0
  105. package/template/src/test/mocks/snowflake.ts +28 -0
  106. package/template/src/test/mocks/supabase.ts +37 -0
  107. package/template/src/test/setup.ts +69 -0
  108. package/template/src/test/utils/test-helpers.ts +158 -0
  109. package/template/src/types/index.ts +14 -0
  110. package/template/tsconfig.json +43 -0
  111. package/template/vitest.config.ts +44 -0
@@ -0,0 +1,862 @@
1
+ # DTT Framework - Deployment Environment Variables
2
+
3
+ ## Overview
4
+
5
+ This document provides a comprehensive guide to managing environment variables for deploying the DTT Framework. It covers the complete list of required variables, platform-specific configurations, security best practices, and credential management.
6
+
7
+ ---
8
+
9
+ ## Table of Contents
10
+
11
+ 1. [Complete List of Required Environment Variables](#complete-list-of-required-environment-variables)
12
+ 2. [Platform-Specific Configuration](#platform-specific-configuration)
13
+ 3. [Security Best Practices](#security-best-practices)
14
+ 4. [Managing Secrets](#managing-secrets)
15
+ 5. [Rotating Credentials](#rotating-credentials)
16
+ 6. [Environment Variable Templates](#environment-variable-templates)
17
+
18
+ ---
19
+
20
+ ## Complete List of Required Environment Variables
21
+
22
+ ### Application Variables
23
+
24
+ | Variable Name | Type | Required | Description | Example |
25
+ |---------------|------|----------|-------------|---------|
26
+ | `NEXT_PUBLIC_APP_URL` | Public | Yes | Base URL of your application | `https://your-app.com` |
27
+ | `NODE_ENV` | Server | Yes | Node environment | `production` |
28
+
29
+ ### Clerk Authentication Variables
30
+
31
+ | Variable Name | Type | Required | Description | Example |
32
+ |---------------|------|----------|-------------|---------|
33
+ | `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` | Public | Yes | Clerk publishable key (client-side) | `pk_live_xxx` |
34
+ | `CLERK_SECRET_KEY` | Server | Yes | Clerk secret key (server-side) | `sk_live_xxx` |
35
+ | `CLERK_WEBHOOK_SECRET` | Server | Yes | Clerk webhook signing secret | `whsec_xxx` |
36
+ | `NEXT_PUBLIC_CLERK_SIGN_IN_URL` | Public | Yes | Sign-in page URL | `/sign-in` |
37
+ | `NEXT_PUBLIC_CLERK_SIGN_UP_URL` | Public | Yes | Sign-up page URL | `/sign-up` |
38
+ | `NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL` | Public | Yes | Redirect URL after sign-in | `/health` |
39
+ | `NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL` | Public | Yes | Redirect URL after sign-up | `/health` |
40
+
41
+ ### Supabase Variables
42
+
43
+ | Variable Name | Type | Required | Description | Example |
44
+ |---------------|------|----------|-------------|---------|
45
+ | `NEXT_PUBLIC_SUPABASE_URL` | Public | Yes | Supabase project URL | `https://xxx.supabase.co` |
46
+ | `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Public | Yes | Supabase anonymous key | `eyJxxx` |
47
+ | `SUPABASE_SERVICE_ROLE_KEY` | Server | Yes | Supabase service role key | `eyJxxx` |
48
+ | `DATABASE_URL` | Server | Yes | PostgreSQL connection string | `postgresql://user:pass@host:6543/db` |
49
+
50
+ ### Snowflake Variables (Optional)
51
+
52
+ | Variable Name | Type | Required | Description | Example |
53
+ |---------------|------|----------|-------------|---------|
54
+ | `SNOWFLAKE_ACCOUNT` | Server | No | Snowflake account identifier | `xxx.us-east-1` |
55
+ | `SNOWFLAKE_USERNAME` | Server | No | Snowflake username | `myuser` |
56
+ | `SNOWFLAKE_PASSWORD` | Server | No | Snowflake password | `mypassword` |
57
+ | `SNOWFLAKE_WAREHOUSE` | Server | No | Snowflake warehouse name | `COMPUTE_WH` |
58
+ | `SNOWFLAKE_DATABASE` | Server | No | Snowflake database name | `ANALYTICS` |
59
+ | `SNOWFLAKE_SCHEMA` | Server | No | Snowflake schema name | `PUBLIC` |
60
+ | `SNOWFLAKE_ROLE` | Server | No | Snowflake role name | `ANALYST` |
61
+
62
+ ### NextBank Variables (Placeholder, Optional)
63
+
64
+ | Variable Name | Type | Required | Description | Example |
65
+ |---------------|------|----------|-------------|---------|
66
+ | `NEXTBANK_API` | Server | No | NextBank API endpoint | `https://api.nextbank.com` |
67
+ | `NEXTBANK_API_USERNAME` | Server | No | NextBank API username | `user` |
68
+ | `NEXTBANK_API_PASSWORD` | Server | No | NextBank API password | `pass` |
69
+
70
+ ---
71
+
72
+ ## Platform-Specific Configuration
73
+
74
+ ### Vercel Configuration
75
+
76
+ #### Setting Variables via Dashboard
77
+
78
+ 1. Go to **Settings** → **Environment Variables**
79
+ 2. Click **"Add New"**
80
+ 3. Enter variable name and value
81
+ 4. Select environments (Production, Preview, Development)
82
+ 5. Click **"Save"**
83
+
84
+ #### Setting Variables via CLI
85
+
86
+ ```bash
87
+ # Add variable to production
88
+ vercel env add DATABASE_URL production
89
+
90
+ # Add variable to all environments
91
+ vercel env add NEXT_PUBLIC_APP_URL
92
+
93
+ # List all variables
94
+ vercel env ls
95
+
96
+ # Pull variables locally
97
+ vercel env pull .env.production
98
+ ```
99
+
100
+ #### Environment-Specific Variables
101
+
102
+ Vercel supports three environments:
103
+
104
+ | Environment | Use Case | Branch |
105
+ |-------------|----------|--------|
106
+ | **Production** | Live application | `main` or `master` |
107
+ | **Preview** | Pull request deployments | Pull request branches |
108
+ | **Development** | Testing environment | `dev` branch |
109
+
110
+ #### Vercel .env.example
111
+
112
+ ```bash
113
+ # ============================================
114
+ # DTT Framework - Vercel Environment Variables
115
+ # ============================================
116
+
117
+ # Application
118
+ NEXT_PUBLIC_APP_URL=https://your-app.vercel.app
119
+ NODE_ENV=production
120
+
121
+ # Clerk Authentication
122
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_xxx
123
+ CLERK_SECRET_KEY=sk_live_xxx
124
+ CLERK_WEBHOOK_SECRET=whsec_xxx
125
+ NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
126
+ NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
127
+ NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/health
128
+ NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/health
129
+
130
+ # Supabase
131
+ NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
132
+ NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJxxx
133
+ SUPABASE_SERVICE_ROLE_KEY=eyJxxx
134
+ DATABASE_URL=postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
135
+
136
+ # Snowflake (Optional)
137
+ SNOWFLAKE_ACCOUNT=xxx.us-east-1
138
+ SNOWFLAKE_USERNAME=xxx
139
+ SNOWFLAKE_PASSWORD=xxx
140
+ SNOWFLAKE_WAREHOUSE=COMPUTE_WH
141
+ SNOWFLAKE_DATABASE=ANALYTICS
142
+ SNOWFLAKE_SCHEMA=PUBLIC
143
+ SNOWFLAKE_ROLE=ANALYST
144
+ ```
145
+
146
+ ### DigitalOcean App Platform Configuration
147
+
148
+ #### Setting Variables via Dashboard
149
+
150
+ 1. Go to **App Platform** → **Your App** → **Settings**
151
+ 2. Scroll to **Environment Variables**
152
+ 3. Click **"Add Variable"**
153
+ 4. Enter variable name and value
154
+ 5. Click **"Save"**
155
+
156
+ #### Setting Variables via doctl CLI
157
+
158
+ ```bash
159
+ # Install doctl
160
+ snap install doctl
161
+
162
+ # Authenticate
163
+ doctl auth init
164
+
165
+ # Add variable to app
166
+ doctl apps create-deployment <app-id> --env DATABASE_URL="postgresql://..."
167
+
168
+ # List variables
169
+ doctl apps spec <app-id>
170
+ ```
171
+
172
+ #### DigitalOcean App Platform .env.example
173
+
174
+ ```bash
175
+ # ============================================
176
+ # DTT Framework - DigitalOcean App Platform
177
+ # ============================================
178
+
179
+ # Application
180
+ NEXT_PUBLIC_APP_URL=https://your-app.ondigitalocean.app
181
+ NODE_ENV=production
182
+
183
+ # Clerk Authentication
184
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_xxx
185
+ CLERK_SECRET_KEY=sk_live_xxx
186
+ CLERK_WEBHOOK_SECRET=whsec_xxx
187
+ NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
188
+ NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
189
+ NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/health
190
+ NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/health
191
+
192
+ # Supabase
193
+ NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
194
+ NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJxxx
195
+ SUPABASE_SERVICE_ROLE_KEY=eyJxxx
196
+ DATABASE_URL=postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
197
+
198
+ # Snowflake (Optional)
199
+ SNOWFLAKE_ACCOUNT=xxx.us-east-1
200
+ SNOWFLAKE_USERNAME=xxx
201
+ SNOWFLAKE_PASSWORD=xxx
202
+ SNOWFLAKE_WAREHOUSE=COMPUTE_WH
203
+ SNOWFLAKE_DATABASE=ANALYTICS
204
+ SNOWFLAKE_SCHEMA=PUBLIC
205
+ SNOWFLAKE_ROLE=ANALYST
206
+ ```
207
+
208
+ ### DigitalOcean Droplet Configuration
209
+
210
+ #### Setting Variables via File
211
+
212
+ ```bash
213
+ # Create .env file
214
+ nano /var/www/dtt-framework/.env
215
+ ```
216
+
217
+ Add environment variables:
218
+
219
+ ```bash
220
+ # ============================================
221
+ # DTT Framework - DigitalOcean Droplet
222
+ # ============================================
223
+
224
+ # Application
225
+ NEXT_PUBLIC_APP_URL=https://your-app.com
226
+ NODE_ENV=production
227
+
228
+ # Clerk Authentication
229
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_xxx
230
+ CLERK_SECRET_KEY=sk_live_xxx
231
+ CLERK_WEBHOOK_SECRET=whsec_xxx
232
+ NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
233
+ NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
234
+ NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/health
235
+ NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/health
236
+
237
+ # Supabase
238
+ NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
239
+ NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJxxx
240
+ SUPABASE_SERVICE_ROLE_KEY=eyJxxx
241
+ DATABASE_URL=postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
242
+
243
+ # Snowflake (Optional)
244
+ SNOWFLAKE_ACCOUNT=xxx.us-east-1
245
+ SNOWFLAKE_USERNAME=xxx
246
+ SNOWFLAKE_PASSWORD=xxx
247
+ SNOWFLAKE_WAREHOUSE=COMPUTE_WH
248
+ SNOWFLAKE_DATABASE=ANALYTICS
249
+ SNOWFLAKE_SCHEMA=PUBLIC
250
+ SNOWFLAKE_ROLE=ANALYST
251
+ ```
252
+
253
+ #### Secure the .env File
254
+
255
+ ```bash
256
+ # Set correct permissions
257
+ chmod 600 /var/www/dtt-framework/.env
258
+
259
+ # Verify permissions
260
+ ls -la /var/www/dtt-framework/.env
261
+ ```
262
+
263
+ #### Restart Application After Changes
264
+
265
+ ```bash
266
+ # Restart PM2 application
267
+ pm2 restart dtt-framework
268
+
269
+ # Or reload without downtime
270
+ pm2 reload dtt-framework
271
+ ```
272
+
273
+ ### GitHub Actions Configuration
274
+
275
+ #### Setting Variables via GitHub Secrets
276
+
277
+ 1. Go to **Repository** → **Settings** → **Secrets and variables** → **Actions**
278
+ 2. Click **"New repository secret"**
279
+ 3. Enter secret name and value
280
+ 4. Click **"Add secret"**
281
+
282
+ #### Using Secrets in Workflow
283
+
284
+ ```yaml
285
+ # .github/workflows/deploy.yml
286
+ name: Deploy
287
+
288
+ on:
289
+ push:
290
+ branches: [main]
291
+
292
+ jobs:
293
+ deploy:
294
+ runs-on: ubuntu-latest
295
+ steps:
296
+ - uses: actions/checkout@v4
297
+
298
+ - name: Setup Node.js
299
+ uses: actions/setup-node@v4
300
+ with:
301
+ node-version: '20'
302
+
303
+ - name: Install pnpm
304
+ uses: pnpm/action-setup@v2
305
+ with:
306
+ version: 10
307
+
308
+ - name: Install dependencies
309
+ run: pnpm install
310
+
311
+ - name: Build application
312
+ env:
313
+ NEXT_PUBLIC_APP_URL: ${{ secrets.NEXT_PUBLIC_APP_URL }}
314
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: ${{ secrets.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY }}
315
+ DATABASE_URL: ${{ secrets.DATABASE_URL }}
316
+ run: pnpm build
317
+
318
+ - name: Deploy to Vercel
319
+ uses: amondnet/vercel-action@v25
320
+ with:
321
+ vercel-token: ${{ secrets.VERCEL_TOKEN }}
322
+ vercel-org-id: ${{ secrets.ORG_ID }}
323
+ vercel-project-id: ${{ secrets.PROJECT_ID }}
324
+ vercel-args: '--prod'
325
+ ```
326
+
327
+ ---
328
+
329
+ ## Security Best Practices
330
+
331
+ ### 1. Never Commit .env Files
332
+
333
+ Always add `.env` to `.gitignore`:
334
+
335
+ ```gitignore
336
+ # Environment variables
337
+ .env
338
+ .env.local
339
+ .env.development.local
340
+ .env.test.local
341
+ .env.production.local
342
+
343
+ # Also ignore secrets files
344
+ *.key
345
+ *.pem
346
+ secrets/
347
+ ```
348
+
349
+ ### 2. Use Environment-Specific Files
350
+
351
+ Use different environment files for different stages:
352
+
353
+ ```bash
354
+ # Development
355
+ .env.development
356
+
357
+ # Staging
358
+ .env.staging
359
+
360
+ # Production
361
+ .env.production
362
+ ```
363
+
364
+ Load appropriate file based on environment:
365
+
366
+ ```bash
367
+ # In package.json scripts
368
+ "dev": "cp .env.development .env && next dev",
369
+ "build:staging": "cp .env.staging .env && next build",
370
+ "build:production": "cp .env.production .env && next build"
371
+ ```
372
+
373
+ ### 3. Prefix Client Variables
374
+
375
+ Only prefix variables with `NEXT_PUBLIC_` if they need to be exposed to client:
376
+
377
+ ```bash
378
+ # ✅ Good - Exposed to client (safe)
379
+ NEXT_PUBLIC_APP_URL=https://your-app.com
380
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_xxx
381
+
382
+ # ❌ Bad - Not exposed, but might be needed
383
+ APP_URL=https://your-app.com
384
+ CLERK_PUBLISHABLE_KEY=pk_live_xxx
385
+
386
+ # ✅ Good - Server-side only (secure)
387
+ DATABASE_URL=postgresql://user:pass@host:6543/db
388
+ CLERK_SECRET_KEY=sk_live_xxx
389
+ ```
390
+
391
+ ### 4. Validate Environment Variables
392
+
393
+ The framework uses `@t3-oss/env-nextjs` for validation:
394
+
395
+ ```typescript
396
+ // src/config/env.ts
397
+ import { createEnv } from '@t3-oss/env-nextjs'
398
+ import { z } from 'zod'
399
+
400
+ export const env = createEnv({
401
+ server: {
402
+ DATABASE_URL: z.string().url(),
403
+ CLERK_SECRET_KEY: z.string().startsWith('sk_'),
404
+ CLERK_WEBHOOK_SECRET: z.string().startsWith('whsec_'),
405
+ SUPABASE_SERVICE_ROLE_KEY: z.string(),
406
+ NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),
407
+ },
408
+ client: {
409
+ NEXT_PUBLIC_APP_URL: z.string().url(),
410
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string().startsWith('pk_'),
411
+ NEXT_PUBLIC_SUPABASE_URL: z.string().url(),
412
+ NEXT_PUBLIC_SUPABASE_ANON_KEY: z.string(),
413
+ },
414
+ runtimeEnv: {
415
+ DATABASE_URL: process.env.DATABASE_URL,
416
+ CLERK_SECRET_KEY: process.env.CLERK_SECRET_KEY,
417
+ CLERK_WEBHOOK_SECRET: process.env.CLERK_WEBHOOK_SECRET,
418
+ SUPABASE_SERVICE_ROLE_KEY: process.env.SUPABASE_SERVICE_ROLE_KEY,
419
+ NODE_ENV: process.env.NODE_ENV,
420
+ NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
421
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,
422
+ NEXT_PUBLIC_SUPABASE_URL: process.env.NEXT_PUBLIC_SUPABASE_URL,
423
+ NEXT_PUBLIC_SUPABASE_ANON_KEY: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
424
+ },
425
+ })
426
+ ```
427
+
428
+ This ensures:
429
+ - All required variables are present
430
+ - Variables are correctly formatted
431
+ - Build fails if variables are missing
432
+
433
+ ### 5. Use Secret Management Services
434
+
435
+ For production, consider using secret management:
436
+
437
+ | Service | Platform | Description |
438
+ |---------|----------|-------------|
439
+ | **Vercel Environment Variables** | Vercel | Built-in secret management |
440
+ | **DigitalOcean App Platform** | DigitalOcean | Built-in secret management |
441
+ | **GitHub Secrets** | GitHub Actions | CI/CD secrets |
442
+ | **AWS Secrets Manager** | AWS | Enterprise secret management |
443
+ | **HashiCorp Vault** | Multi-cloud | Advanced secret management |
444
+ | **1Password Secrets Automation** | Multi-cloud | Password manager integration |
445
+
446
+ ### 6. Implement Least Privilege
447
+
448
+ Use the minimum required permissions for each key:
449
+
450
+ | Key Type | Permissions | Use Case |
451
+ |----------|-------------|----------|
452
+ | `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Limited (RLS) | Client-side operations |
453
+ | `SUPABASE_SERVICE_ROLE_KEY` | Full access | Server-side operations |
454
+ | `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` | Read-only | Client-side auth |
455
+ | `CLERK_SECRET_KEY` | Full access | Server-side auth |
456
+
457
+ ### 7. Rotate Secrets Regularly
458
+
459
+ Establish a secret rotation schedule:
460
+
461
+ | Secret Type | Rotation Frequency |
462
+ |-------------|-------------------|
463
+ | API Keys | Every 90 days |
464
+ | Database Passwords | Every 180 days |
465
+ | Webhook Secrets | When compromised |
466
+ | Service Role Keys | Every 180 days |
467
+
468
+ ### 8. Audit Access to Secrets
469
+
470
+ Track who has access to secrets:
471
+
472
+ ```bash
473
+ # Vercel: Check team member access
474
+ # Dashboard → Team → Members
475
+
476
+ # GitHub: Check secret access
477
+ # Settings → Secrets and variables → Actions
478
+
479
+ # DigitalOcean: Check team access
480
+ # Dashboard → Team → Members
481
+ ```
482
+
483
+ ---
484
+
485
+ ## Managing Secrets
486
+
487
+ ### Secret Management Strategies
488
+
489
+ #### 1. Environment Variable Files
490
+
491
+ Use `.env` files for local development:
492
+
493
+ ```bash
494
+ # .env.local (not committed)
495
+ DATABASE_URL=postgresql://user:pass@localhost:5432/db
496
+ CLERK_SECRET_KEY=sk_test_xxx
497
+ ```
498
+
499
+ #### 2. Secret Management Tools
500
+
501
+ Use tools like:
502
+
503
+ - **direnv**: Load environment variables automatically
504
+ - **dotenv**: Load variables from `.env` files
505
+ - **envsubst**: Substitute variables in files
506
+
507
+ #### 3. Encrypted Secrets
508
+
509
+ Use encryption for sensitive secrets:
510
+
511
+ ```bash
512
+ # Using OpenSSL
513
+ openssl enc -aes-256-cbc -salt -in secret.txt -out secret.enc
514
+
515
+ # Decrypt
516
+ openssl enc -aes-256-cbc -d -in secret.enc -out secret.txt
517
+ ```
518
+
519
+ ### Secret Storage Options
520
+
521
+ #### Option 1: Platform-Native Storage
522
+
523
+ | Platform | Storage Method | Security |
524
+ |----------|---------------|----------|
525
+ | **Vercel** | Environment Variables | Encrypted at rest |
526
+ | **DigitalOcean App Platform** | Environment Variables | Encrypted at rest |
527
+ | **DigitalOcean Droplet** | File system | Manual encryption needed |
528
+
529
+ #### Option 2: Third-Party Secret Managers
530
+
531
+ | Tool | Features | Cost |
532
+ |------|----------|------|
533
+ | **AWS Secrets Manager** | Auto-rotation, audit logs | Paid |
534
+ | **HashiCorp Vault** | Advanced features | Open source + Paid |
535
+ | **1Password** | UI-based, team sharing | Paid |
536
+ | **Infisical** | Open source, syncs to platforms | Free tier available |
537
+
538
+ ### Secret Access Control
539
+
540
+ #### Grant Access by Role
541
+
542
+ ```yaml
543
+ # Example: Role-based access
544
+ roles:
545
+ - developer:
546
+ secrets: [DATABASE_URL, API_KEY]
547
+ - devops:
548
+ secrets: [DATABASE_URL, API_KEY, CLERK_SECRET_KEY]
549
+ - admin:
550
+ secrets: [ALL_SECRETS]
551
+ ```
552
+
553
+ #### Use Temporary Credentials
554
+
555
+ For CI/CD, use temporary credentials:
556
+
557
+ ```yaml
558
+ # GitHub Actions example
559
+ jobs:
560
+ deploy:
561
+ steps:
562
+ - name: Get temporary credentials
563
+ id: creds
564
+ run: |
565
+ TOKEN=$(curl -X POST https://api.example.com/creds)
566
+ echo "::add-mask::$TOKEN"
567
+ echo "::set-output name=token::$TOKEN"
568
+ ```
569
+
570
+ ---
571
+
572
+ ## Rotating Credentials
573
+
574
+ ### Rotation Strategy
575
+
576
+ #### 1. Plan Rotation
577
+
578
+ Create a rotation plan:
579
+
580
+ | Step | Description | Timeline |
581
+ |------|-------------|----------|
582
+ | **Preparation** | Generate new credentials | Day 1 |
583
+ | **Testing** | Test new credentials in staging | Day 2 |
584
+ | **Deployment** | Deploy new credentials to production | Day 3 |
585
+ | **Verification** | Verify application works | Day 3 |
586
+ | **Cleanup** | Revoke old credentials | Day 7 |
587
+
588
+ #### 2. Rotate Clerk Keys
589
+
590
+ ```bash
591
+ # 1. Generate new keys in Clerk Dashboard
592
+ # Dashboard → Your App → API Keys → Rotate
593
+
594
+ # 2. Update environment variables
595
+ vercel env add CLERK_SECRET_KEY production
596
+
597
+ # 3. Redeploy application
598
+ vercel --prod
599
+
600
+ # 4. Verify authentication works
601
+ # Test sign-in/sign-up flows
602
+
603
+ # 5. Revoke old keys (after 7 days)
604
+ # Clerk Dashboard → API Keys → Revoke
605
+ ```
606
+
607
+ #### 3. Rotate Supabase Keys
608
+
609
+ ```bash
610
+ # 1. Generate new keys in Supabase Dashboard
611
+ # Dashboard → Settings → API → Rotate
612
+
613
+ # 2. Update environment variables
614
+ vercel env add SUPABASE_SERVICE_ROLE_KEY production
615
+
616
+ # 3. Redeploy application
617
+ vercel --prod
618
+
619
+ # 4. Verify database operations work
620
+ # Test database queries
621
+
622
+ # 5. Revoke old keys (after 7 days)
623
+ # Supabase Dashboard → Settings → API → Revoke
624
+ ```
625
+
626
+ #### 4. Rotate Database Password
627
+
628
+ ```bash
629
+ # 1. Generate new password
630
+ # Use a password manager
631
+
632
+ # 2. Update database password
633
+ # Supabase Dashboard → Settings → Database → Password
634
+
635
+ # 3. Update DATABASE_URL
636
+ vercel env add DATABASE_URL production
637
+
638
+ # 4. Redeploy application
639
+ vercel --prod
640
+
641
+ # 5. Verify database connection
642
+ # Test database operations
643
+ ```
644
+
645
+ ### Automated Rotation
646
+
647
+ #### Using Cron Jobs
648
+
649
+ ```bash
650
+ # Set up automated rotation check
651
+ # Add to crontab:
652
+ 0 0 1 * * /usr/local/bin/check-rotation.sh
653
+ ```
654
+
655
+ #### Using CI/CD
656
+
657
+ ```yaml
658
+ # .github/workflows/rotate-secrets.yml
659
+ name: Rotate Secrets
660
+
661
+ on:
662
+ schedule:
663
+ - cron: '0 0 1 * *' # Monthly
664
+
665
+ jobs:
666
+ rotate:
667
+ runs-on: ubuntu-latest
668
+ steps:
669
+ - name: Check secret age
670
+ run: |
671
+ # Check if secrets need rotation
672
+ # Trigger rotation if needed
673
+ ```
674
+
675
+ ---
676
+
677
+ ## Environment Variable Templates
678
+
679
+ ### Development Template (.env.development)
680
+
681
+ ```bash
682
+ # ============================================
683
+ # DTT Framework - Development Environment
684
+ # ============================================
685
+
686
+ # Application
687
+ NEXT_PUBLIC_APP_URL=http://localhost:3000
688
+ NODE_ENV=development
689
+
690
+ # Clerk Authentication (Test Mode)
691
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxx
692
+ CLERK_SECRET_KEY=sk_test_xxx
693
+ CLERK_WEBHOOK_SECRET=whsec_test_xxx
694
+ NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
695
+ NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
696
+ NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/health
697
+ NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/health
698
+
699
+ # Supabase (Development Project)
700
+ NEXT_PUBLIC_SUPABASE_URL=https://xxx-dev.supabase.co
701
+ NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJxxx
702
+ SUPABASE_SERVICE_ROLE_KEY=eyJxxx
703
+ DATABASE_URL=postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
704
+
705
+ # Snowflake (Optional - Test Account)
706
+ SNOWFLAKE_ACCOUNT=xxx.us-east-1
707
+ SNOWFLAKE_USERNAME=xxx
708
+ SNOWFLAKE_PASSWORD=xxx
709
+ SNOWFLAKE_WAREHOUSE=COMPUTE_WH
710
+ SNOWFLAKE_DATABASE=ANALYTICS
711
+ SNOWFLAKE_SCHEMA=PUBLIC
712
+ SNOWFLAKE_ROLE=ANALYST
713
+ ```
714
+
715
+ ### Staging Template (.env.staging)
716
+
717
+ ```bash
718
+ # ============================================
719
+ # DTT Framework - Staging Environment
720
+ # ============================================
721
+
722
+ # Application
723
+ NEXT_PUBLIC_APP_URL=https://staging.your-app.com
724
+ NODE_ENV=production
725
+
726
+ # Clerk Authentication (Test Mode)
727
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxx
728
+ CLERK_SECRET_KEY=sk_test_xxx
729
+ CLERK_WEBHOOK_SECRET=whsec_test_xxx
730
+ NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
731
+ NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
732
+ NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/health
733
+ NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/health
734
+
735
+ # Supabase (Staging Project)
736
+ NEXT_PUBLIC_SUPABASE_URL=https://xxx-staging.supabase.co
737
+ NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJxxx
738
+ SUPABASE_SERVICE_ROLE_KEY=eyJxxx
739
+ DATABASE_URL=postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
740
+
741
+ # Snowflake (Optional - Test Account)
742
+ SNOWFLAKE_ACCOUNT=xxx.us-east-1
743
+ SNOWFLAKE_USERNAME=xxx
744
+ SNOWFLAKE_PASSWORD=xxx
745
+ SNOWFLAKE_WAREHOUSE=COMPUTE_WH
746
+ SNOWFLAKE_DATABASE=ANALYTICS
747
+ SNOWFLAKE_SCHEMA=PUBLIC
748
+ SNOWFLAKE_ROLE=ANALYST
749
+ ```
750
+
751
+ ### Production Template (.env.production)
752
+
753
+ ```bash
754
+ # ============================================
755
+ # DTT Framework - Production Environment
756
+ # ============================================
757
+
758
+ # Application
759
+ NEXT_PUBLIC_APP_URL=https://your-app.com
760
+ NODE_ENV=production
761
+
762
+ # Clerk Authentication (Live Mode)
763
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_xxx
764
+ CLERK_SECRET_KEY=sk_live_xxx
765
+ CLERK_WEBHOOK_SECRET=whsec_xxx
766
+ NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
767
+ NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
768
+ NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/health
769
+ NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/health
770
+
771
+ # Supabase (Production Project)
772
+ NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
773
+ NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJxxx
774
+ SUPABASE_SERVICE_ROLE_KEY=eyJxxx
775
+ DATABASE_URL=postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
776
+
777
+ # Snowflake (Optional - Production Account)
778
+ SNOWFLAKE_ACCOUNT=xxx.us-east-1
779
+ SNOWFLAKE_USERNAME=xxx
780
+ SNOWFLAKE_PASSWORD=xxx
781
+ SNOWFLAKE_WAREHOUSE=COMPUTE_WH
782
+ SNOWFLAKE_DATABASE=ANALYTICS
783
+ SNOWFLAKE_SCHEMA=PUBLIC
784
+ SNOWFLAKE_ROLE=ANALYST
785
+ ```
786
+
787
+ ---
788
+
789
+ ## Troubleshooting
790
+
791
+ ### Issue: Environment Variables Not Loading
792
+
793
+ **Symptoms:**
794
+ - Application can't access environment variables
795
+ - `undefined` values for environment variables
796
+
797
+ **Solutions:**
798
+
799
+ ```bash
800
+ # Verify .env file exists
801
+ ls -la .env
802
+
803
+ # Check file permissions
804
+ chmod 600 .env
805
+
806
+ # Restart application
807
+ pm2 restart dtt-framework
808
+
809
+ # Check for typos in variable names
810
+ # Environment variables are case-sensitive
811
+ ```
812
+
813
+ ### Issue: Build Fails Due to Missing Variables
814
+
815
+ **Symptoms:**
816
+ - Build process fails
817
+ - Error about missing environment variables
818
+
819
+ **Solutions:**
820
+
821
+ ```bash
822
+ # Verify all required variables are set
823
+ vercel env ls
824
+
825
+ # Check variable names match exactly
826
+ # NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY (correct)
827
+ # next_public_clerk_publishable_key (incorrect)
828
+
829
+ # For local builds, verify .env file
830
+ cat .env
831
+ ```
832
+
833
+ ### Issue: Variables Not Available in Production
834
+
835
+ **Symptoms:**
836
+ - Variables work in development but not production
837
+ - Application fails in production
838
+
839
+ **Solutions:**
840
+
841
+ ```bash
842
+ # Verify variables are set for production environment
843
+ vercel env ls --environment=production
844
+
845
+ # Redeploy to apply changes
846
+ vercel --prod
847
+
848
+ # Check deployment logs
849
+ vercel logs
850
+ ```
851
+
852
+ ---
853
+
854
+ ## Related Documentation
855
+
856
+ - [Vercel Deployment](./vercel.md) - Vercel deployment guide
857
+ - [DigitalOcean Deployment](./digitalocean.md) - DigitalOcean deployment guide
858
+ - [Domain Setup](./domain-setup.md) - Custom domain configuration
859
+ - [CI/CD Setup](./ci-cd.md) - Automated deployments
860
+ - [Production Checklist](./production-checklist.md) - Pre-deployment checklist
861
+ - [Monitoring](./monitoring.md) - Monitoring and alerting setup
862
+ - [Framework Environment Variables](../environment-variables.md) - Complete variable reference