@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,646 @@
1
+ # DTT Framework - Environment Variables
2
+
3
+ ## Overview
4
+
5
+ Environment variables are used to configure the DTT Framework. This document provides a complete reference for all available environment variables, their purposes, and how to configure them.
6
+
7
+ ---
8
+
9
+ ## Complete .env.example Reference
10
+
11
+ ```bash
12
+ # ============================================
13
+ # DTT Framework Environment Variables
14
+ # ============================================
15
+ # Copy this file to .env and fill in your values
16
+ # Never commit .env to version control
17
+ # ============================================
18
+
19
+ # ============================================
20
+ # Application
21
+ # ============================================
22
+
23
+ # The URL where your application is deployed
24
+ # Used for redirects, webhooks, and callbacks
25
+ NEXT_PUBLIC_APP_URL=http://localhost:3000
26
+
27
+ # ============================================
28
+ # Clerk Authentication
29
+ # ============================================
30
+
31
+ # Clerk publishable key (starts with pk_)
32
+ # Used for client-side Clerk operations
33
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxx
34
+
35
+ # Clerk secret key (starts with sk_)
36
+ # Used for server-side Clerk operations
37
+ CLERK_SECRET_KEY=sk_test_xxx
38
+
39
+ # Clerk webhook secret (starts with whsec_)
40
+ # Used to verify webhook signatures
41
+ CLERK_WEBHOOK_SECRET=whsec_xxx
42
+
43
+ # URL for sign-in page
44
+ NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
45
+
46
+ # URL for sign-up page
47
+ NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
48
+
49
+ # Redirect URL after successful sign-in
50
+ NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/health
51
+
52
+ # Redirect URL after successful sign-up
53
+ NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/health
54
+
55
+ # ============================================
56
+ # Supabase
57
+ # ============================================
58
+
59
+ # Supabase project URL
60
+ NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
61
+
62
+ # Supabase anonymous/public key
63
+ # Used for client-side Supabase operations
64
+ NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJxxx
65
+
66
+ # Supabase service role key
67
+ # Used for server-side Supabase operations (bypasses RLS)
68
+ SUPABASE_SERVICE_ROLE_KEY=eyJxxx
69
+
70
+ # PostgreSQL connection URL (Transaction mode)
71
+ # Format: postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
72
+ DATABASE_URL=postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
73
+
74
+ # ============================================
75
+ # Snowflake (Optional)
76
+ # ============================================
77
+
78
+ # Snowflake account identifier
79
+ # Format: [account_locator].[region]
80
+ SNOWFLAKE_ACCOUNT=xxx.us-east-1
81
+
82
+ # Snowflake username
83
+ SNOWFLAKE_USERNAME=xxx
84
+
85
+ # Snowflake password
86
+ SNOWFLAKE_PASSWORD=xxx
87
+
88
+ # Snowflake warehouse name
89
+ SNOWFLAKE_WAREHOUSE=COMPUTE_WH
90
+
91
+ # Snowflake database name
92
+ SNOWFLAKE_DATABASE=ANALYTICS
93
+
94
+ # Snowflake schema name
95
+ SNOWFLAKE_SCHEMA=PUBLIC
96
+
97
+ # Snowflake role name
98
+ SNOWFLAKE_ROLE=ANALYST
99
+
100
+ # ============================================
101
+ # NextBank (Placeholder - Optional)
102
+ # ============================================
103
+
104
+ # NextBank API URL
105
+ NEXTBANK_API=https://api.nextbank.com
106
+
107
+ # NextBank API username
108
+ NEXTBANK_API_USERNAME=user
109
+
110
+ # NextBank API password
111
+ NEXTBANK_API_PASSWORD=pass
112
+ ```
113
+
114
+ ---
115
+
116
+ ## How to Configure Each Variable
117
+
118
+ ### Application Variables
119
+
120
+ #### NEXT_PUBLIC_APP_URL
121
+
122
+ **Purpose:** Base URL for your application
123
+
124
+ **Where to find:** This is your application's URL
125
+
126
+ **Examples:**
127
+ ```bash
128
+ # Development
129
+ NEXT_PUBLIC_APP_URL=http://localhost:3000
130
+
131
+ # Production
132
+ NEXT_PUBLIC_APP_URL=https://your-app.com
133
+
134
+ # Staging
135
+ NEXT_PUBLIC_APP_URL=https://staging.your-app.com
136
+ ```
137
+
138
+ **Notes:**
139
+ - Must include protocol (http:// or https://)
140
+ - No trailing slash
141
+ - Used for webhook callbacks and redirects
142
+
143
+ ---
144
+
145
+ ### Clerk Authentication Variables
146
+
147
+ #### NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY
148
+
149
+ **Purpose:** Client-side Clerk operations
150
+
151
+ **Where to find:** Clerk Dashboard → Your App → API Keys → Publishable Key
152
+
153
+ **Format:** Starts with `pk_`
154
+
155
+ **Example:**
156
+ ```bash
157
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxx
158
+ ```
159
+
160
+ **Notes:**
161
+ - Safe to expose to client (starts with NEXT_PUBLIC_)
162
+ - Used for Clerk components on client-side
163
+ - Different keys for test and production environments
164
+
165
+ #### CLERK_SECRET_KEY
166
+
167
+ **Purpose:** Server-side Clerk operations
168
+
169
+ **Where to find:** Clerk Dashboard → Your App → API Keys → Secret Key
170
+
171
+ **Format:** Starts with `sk_`
172
+
173
+ **Example:**
174
+ ```bash
175
+ CLERK_SECRET_KEY=sk_test_xxx
176
+ ```
177
+
178
+ **Notes:**
179
+ - Never expose to client (no NEXT_PUBLIC_ prefix)
180
+ - Used for server-side auth verification
181
+ - Keep secret and never commit to version control
182
+
183
+ #### CLERK_WEBHOOK_SECRET
184
+
185
+ **Purpose:** Verify webhook signatures
186
+
187
+ **Where to find:** Clerk Dashboard → Your App → Webhooks → Add Endpoint → Copy Secret
188
+
189
+ **Format:** Starts with `whsec_`
190
+
191
+ **Example:**
192
+ ```bash
193
+ CLERK_WEBHOOK_SECRET=whsec_xxx
194
+ ```
195
+
196
+ **Notes:**
197
+ - Never expose to client
198
+ - Used to verify incoming webhooks are from Clerk
199
+ - Required for webhook endpoint
200
+
201
+ #### Clerk URL Variables
202
+
203
+ **Purpose:** Configure Clerk authentication flow
204
+
205
+ **Examples:**
206
+ ```bash
207
+ NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
208
+ NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
209
+ NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/health
210
+ NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/health
211
+ ```
212
+
213
+ **Notes:**
214
+ - All start with NEXT_PUBLIC_ (used in client)
215
+ - Can be absolute URLs or relative paths
216
+ - Customize based on your routing structure
217
+
218
+ ---
219
+
220
+ ### Supabase Variables
221
+
222
+ #### NEXT_PUBLIC_SUPABASE_URL
223
+
224
+ **Purpose:** Supabase project URL
225
+
226
+ **Where to find:** Supabase Dashboard → Your Project → Settings → API → Project URL
227
+
228
+ **Format:** Full URL including protocol
229
+
230
+ **Example:**
231
+ ```bash
232
+ NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
233
+ ```
234
+
235
+ **Notes:**
236
+ - Safe to expose to client
237
+ - Used for all Supabase client operations
238
+ - Different URL for each project
239
+
240
+ #### NEXT_PUBLIC_SUPABASE_ANON_KEY
241
+
242
+ **Purpose:** Client-side Supabase operations
243
+
244
+ **Where to find:** Supabase Dashboard → Your Project → Settings → API → anon/public key
245
+
246
+ **Format:** JWT token (starts with `eyJ`)
247
+
248
+ **Example:**
249
+ ```bash
250
+ NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJxxx
251
+ ```
252
+
253
+ **Notes:**
254
+ - Safe to expose to client
255
+ - Respects Row Level Security (RLS) policies
256
+ - Limited permissions by default
257
+
258
+ #### SUPABASE_SERVICE_ROLE_KEY
259
+
260
+ **Purpose:** Server-side Supabase operations with full access
261
+
262
+ **Where to find:** Supabase Dashboard → Your Project → Settings → API → service_role key
263
+
264
+ **Format:** JWT token (starts with `eyJ`)
265
+
266
+ **Example:**
267
+ ```bash
268
+ SUPABASE_SERVICE_ROLE_KEY=eyJxxx
269
+ ```
270
+
271
+ **Notes:**
272
+ - Never expose to client
273
+ - Bypasses Row Level Security (RLS)
274
+ - Full database access
275
+ - Use only on server-side
276
+
277
+ #### DATABASE_URL
278
+
279
+ **Purpose:** PostgreSQL connection string
280
+
281
+ **Where to find:** Supabase Dashboard → Your Project → Settings → Database → Connection String → Transaction mode
282
+
283
+ **Format:** PostgreSQL connection string
284
+
285
+ **Example:**
286
+ ```bash
287
+ DATABASE_URL=postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
288
+ ```
289
+
290
+ **Notes:**
291
+ - Never expose to client
292
+ - Use Transaction mode for serverless (port 6543, .pooler. domain)
293
+ - Required for Drizzle ORM
294
+ - Format: `postgresql://[user]:[password]@[host]:[port]/[database]`
295
+
296
+ **Connection Modes:**
297
+
298
+ | Mode | URL Format | Use Case |
299
+ |-------|-------------|----------|
300
+ | **Session** | `postgres://[user]:[password]@[host]:5432/[database]` | Serverful applications |
301
+ | **Transaction** | `postgres://[user]:[password]@[host]:6543/[database]` | Serverless applications |
302
+
303
+ ---
304
+
305
+ ### Snowflake Variables (Optional)
306
+
307
+ #### SNOWFLAKE_ACCOUNT
308
+
309
+ **Purpose:** Snowflake account identifier
310
+
311
+ **Where to find:** Snowflake URL when logged in
312
+
313
+ **Format:** `[account_locator].[region]`
314
+
315
+ **Example:**
316
+ ```bash
317
+ SNOWFLAKE_ACCOUNT=xy12345.us-east-1
318
+ ```
319
+
320
+ **Notes:**
321
+ - Extract from Snowflake URL: `https://xy12345.us-east-1.snowflakecomputing.com`
322
+ - Different regions: `us-east-1`, `us-west-2`, `eu-west-1`, etc.
323
+
324
+ #### SNOWFLAKE_USERNAME
325
+
326
+ **Purpose:** Snowflake username
327
+
328
+ **Where to find:** Your Snowflake username
329
+
330
+ **Example:**
331
+ ```bash
332
+ SNOWFLAKE_USERNAME=myuser
333
+ ```
334
+
335
+ **Notes:**
336
+ - Case-sensitive
337
+ - Usually email or custom username
338
+
339
+ #### SNOWFLAKE_PASSWORD
340
+
341
+ **Purpose:** Snowflake password
342
+
343
+ **Where to find:** Your Snowflake password
344
+
345
+ **Example:**
346
+ ```bash
347
+ SNOWFLAKE_PASSWORD=mypassword
348
+ ```
349
+
350
+ **Notes:**
351
+ - Never commit to version control
352
+ - May need to be updated if password changes
353
+ - Consider using password rotation policies
354
+
355
+ #### SNOWFLAKE_WAREHOUSE
356
+
357
+ **Purpose:** Compute warehouse to use
358
+
359
+ **Where to find:** Snowflake → Warehouses
360
+
361
+ **Example:**
362
+ ```bash
363
+ SNOWFLAKE_WAREHOUSE=COMPUTE_WH
364
+ ```
365
+
366
+ **Notes:**
367
+ - Warehouse must exist in your Snowflake account
368
+ - Different sizes: X-Small, Small, Medium, Large, etc.
369
+ - Affects query performance and cost
370
+
371
+ #### SNOWFLAKE_DATABASE
372
+
373
+ **Purpose:** Database to connect to
374
+
375
+ **Where to find:** Snowflake → Databases
376
+
377
+ **Example:**
378
+ ```bash
379
+ SNOWFLAKE_DATABASE=ANALYTICS
380
+ ```
381
+
382
+ **Notes:**
383
+ - Database must exist in your Snowflake account
384
+ - User must have access to database
385
+ - Default is often `SNOWFLAKE` or `ANALYTICS`
386
+
387
+ #### SNOWFLAKE_SCHEMA
388
+
389
+ **Purpose:** Schema to use
390
+
391
+ **Where to find:** Snowflake → Databases → Your Database → Schemas
392
+
393
+ **Example:**
394
+ ```bash
395
+ SNOWFLAKE_SCHEMA=PUBLIC
396
+ ```
397
+
398
+ **Notes:**
399
+ - Schema must exist in database
400
+ - Default is usually `PUBLIC`
401
+ - User must have access to schema
402
+
403
+ #### SNOWFLAKE_ROLE
404
+
405
+ **Purpose:** Role to use for queries
406
+
407
+ **Where to find:** Snowflake → Roles
408
+
409
+ **Example:**
410
+ ```bash
411
+ SNOWFLAKE_ROLE=ANALYST
412
+ ```
413
+
414
+ **Notes:**
415
+ - Role must exist in your Snowflake account
416
+ - User must be granted the role
417
+ - Determines permissions and access
418
+
419
+ ---
420
+
421
+ ### NextBank Variables (Placeholder)
422
+
423
+ **Note:** NextBank is a placeholder integration. These variables are optional and not currently used.
424
+
425
+ #### NEXTBANK_API
426
+
427
+ **Purpose:** NextBank API endpoint
428
+
429
+ **Example:**
430
+ ```bash
431
+ NEXTBANK_API=https://api.nextbank.com
432
+ ```
433
+
434
+ #### NEXTBANK_API_USERNAME
435
+
436
+ **Purpose:** API username for NextBank
437
+
438
+ **Example:**
439
+ ```bash
440
+ NEXTBANK_API_USERNAME=user
441
+ ```
442
+
443
+ #### NEXTBANK_API_PASSWORD
444
+
445
+ **Purpose:** API password for NextBank
446
+
447
+ **Example:**
448
+ ```bash
449
+ NEXTBANK_API_PASSWORD=pass
450
+ ```
451
+
452
+ ---
453
+
454
+ ## Security Considerations
455
+
456
+ ### 1. Never Commit .env Files
457
+
458
+ Always add `.env` to `.gitignore`:
459
+
460
+ ```gitignore
461
+ # Environment variables
462
+ .env
463
+ .env.local
464
+ .env.development.local
465
+ .env.test.local
466
+ .env.production.local
467
+ ```
468
+
469
+ ### 2. Use Environment-Specific Files
470
+
471
+ Use different environment files for different stages:
472
+
473
+ ```bash
474
+ # Development
475
+ .env.development
476
+
477
+ # Staging
478
+ .env.staging
479
+
480
+ # Production
481
+ .env.production
482
+ ```
483
+
484
+ Load appropriate file based on environment:
485
+
486
+ ```bash
487
+ # In package.json scripts
488
+ "dev": "cp .env.development .env && next dev",
489
+ "build": "cp .env.production .env && next build"
490
+ ```
491
+
492
+ ### 3. Prefix Client Variables
493
+
494
+ Only prefix variables with `NEXT_PUBLIC_` if they need to be exposed to client:
495
+
496
+ ```bash
497
+ # ✅ Good - Exposed to client
498
+ NEXT_PUBLIC_API_URL=https://api.example.com
499
+
500
+ # ❌ Bad - Not exposed, but might be needed
501
+ API_URL=https://api.example.com
502
+ ```
503
+
504
+ ### 4. Validate Environment Variables
505
+
506
+ The framework uses `@t3-oss/env-nextjs` for validation:
507
+
508
+ ```typescript
509
+ // src/config/env.ts
510
+ export const env = createEnv({
511
+ server: {
512
+ DATABASE_URL: z.string().url(),
513
+ CLERK_SECRET_KEY: z.string().startsWith('sk_'),
514
+ },
515
+ client: {
516
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string().startsWith('pk_'),
517
+ },
518
+ })
519
+ ```
520
+
521
+ This ensures:
522
+ - All required variables are present
523
+ - Variables are correctly formatted
524
+ - Build fails if variables are missing
525
+
526
+ ### 5. Use Secret Management Services
527
+
528
+ For production, consider using secret management:
529
+
530
+ - **Vercel Environment Variables**: For Vercel deployments
531
+ - **AWS Secrets Manager**: For AWS deployments
532
+ - **GitHub Secrets**: For GitHub Actions
533
+ - **Docker Secrets**: For containerized deployments
534
+
535
+ ---
536
+
537
+ ## Environment Variable Validation
538
+
539
+ ### Schema Validation
540
+
541
+ The framework validates environment variables at build time:
542
+
543
+ ```typescript
544
+ // src/config/env.ts
545
+ import { createEnv } from '@t3-oss/env-nextjs'
546
+ import { z } from 'zod'
547
+
548
+ export const env = createEnv({
549
+ server: {
550
+ DATABASE_URL: z.string().url(),
551
+ NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),
552
+ },
553
+ client: {
554
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string().startsWith('pk_'),
555
+ },
556
+ runtimeEnv: {
557
+ DATABASE_URL: process.env.DATABASE_URL,
558
+ NODE_ENV: process.env.NODE_ENV,
559
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,
560
+ },
561
+ })
562
+ ```
563
+
564
+ ### Validation Errors
565
+
566
+ If validation fails, you'll see an error like:
567
+
568
+ ```
569
+ ❌ Invalid environment variables:
570
+ - DATABASE_URL: Required
571
+ - NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: Must start with "pk_"
572
+ ```
573
+
574
+ ### Skipping Validation
575
+
576
+ For Docker builds, you can skip validation:
577
+
578
+ ```bash
579
+ SKIP_ENV_VALIDATION=true pnpm build
580
+ ```
581
+
582
+ ---
583
+
584
+ ## Troubleshooting
585
+
586
+ ### Common Issues
587
+
588
+ **Issue: "Environment variable not found"**
589
+
590
+ **Solution:** Ensure `.env` file exists and is loaded:
591
+
592
+ ```bash
593
+ # Check if .env exists
594
+ ls -la .env
595
+
596
+ # Copy from example if missing
597
+ cp .env.example .env
598
+
599
+ # Restart development server
600
+ pnpm dev
601
+ ```
602
+
603
+ **Issue: "Invalid environment variable format"**
604
+
605
+ **Solution:** Check variable format matches expected pattern:
606
+
607
+ ```bash
608
+ # Clerk keys must start with specific prefixes
609
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxx # ✅ Correct
610
+ CLERK_SECRET_KEY=sk_test_xxx # ✅ Correct
611
+
612
+ # Database URL must be valid URL
613
+ DATABASE_URL=postgresql://user:pass@host:5432/db # ✅ Correct
614
+ ```
615
+
616
+ **Issue: "Database connection failed"**
617
+
618
+ **Solution:** Verify DATABASE_URL is correct:
619
+
620
+ ```bash
621
+ # Test connection
622
+ psql $DATABASE_URL
623
+
624
+ # Check for correct mode (Transaction vs Session)
625
+ # Transaction mode: port 6543, .pooler. domain
626
+ # Session mode: port 5432, direct domain
627
+ ```
628
+
629
+ **Issue: "Clerk webhook verification failed"**
630
+
631
+ **Solution:** Verify webhook secret is correct:
632
+
633
+ ```bash
634
+ # Check webhook secret matches Clerk dashboard
635
+ CLERK_WEBHOOK_SECRET=whsec_xxx # Must match exactly
636
+ ```
637
+
638
+ ---
639
+
640
+ ## Related Documentation
641
+
642
+ - [Overview](./01-overview.md) - Framework introduction
643
+ - [Tech Stack](./02-techstack.md) - Technology breakdown
644
+ - [Clerk Authentication](./clerk-authentication.md) - Auth configuration
645
+ - [Supabase Integration](./supabase-integration.md) - Database configuration
646
+ - [Snowflake Integration](./snowflake-integration.md) - Data warehouse configuration