@odvi/create-dtt-framework 0.1.2 → 0.1.5

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