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