@odvi/create-dtt-framework 0.1.3 → 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 (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 +103 -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 +863 -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 +658 -0
  20. package/template/docs/framework/health-check-system.md +582 -0
  21. package/template/docs/framework/implementation.md +559 -0
  22. package/template/docs/framework/snowflake-integration.md +591 -0
  23. package/template/docs/framework/state-management.md +615 -0
  24. package/template/docs/framework/supabase-integration.md +581 -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 +12 -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 +166 -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 +363 -0
  64. package/template/src/features/health-check/config.ts +72 -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 +37 -0
  74. package/template/src/lib/snowflake/client.ts +53 -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 +117 -0
  86. package/template/src/server/api/routes/health/edge-functions.ts +75 -0
  87. package/template/src/server/api/routes/health/framework.ts +45 -0
  88. package/template/src/server/api/routes/health/index.ts +102 -0
  89. package/template/src/server/api/routes/health/nextbank.ts +67 -0
  90. package/template/src/server/api/routes/health/snowflake.ts +83 -0
  91. package/template/src/server/api/routes/health/storage.ts +163 -0
  92. package/template/src/server/api/routes/users.ts +95 -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 +26 -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,591 @@
1
+ # DTT Framework - Snowflake Integration
2
+
3
+ ## Overview
4
+
5
+ The DTT Framework includes integration with [Snowflake](https://www.snowflake.com/), a cloud-based data warehousing platform. Snowflake is used for analytics, reporting, and business intelligence workloads.
6
+
7
+ ### Why Snowflake?
8
+
9
+ - **Cloud-Native**: Fully managed data warehouse
10
+ - **Separation of Compute and Storage**: Scale independently
11
+ - **Performance**: Fast query execution with automatic optimization
12
+ - **SQL Support**: Standard SQL with extensions
13
+ - **Data Sharing**: Secure data sharing with other Snowflake accounts
14
+ - **Ecosystem**: Rich partner ecosystem and integrations
15
+
16
+ ---
17
+
18
+ ## Snowflake Connection Setup
19
+
20
+ ### 1. Create a Snowflake Account
21
+
22
+ 1. Go to [snowflake.com](https://www.snowflake.com/) and sign up
23
+ 2. Create a new account or use an existing one
24
+ 3. Note down your account identifier (e.g., `xy12345.us-east-1`)
25
+
26
+ ### 2. Install Dependencies
27
+
28
+ ```bash
29
+ pnpm add snowflake-sdk
30
+ pnpm add -D @types/snowflake-sdk
31
+ ```
32
+
33
+ ### 3. Configure Environment Variables
34
+
35
+ Add the following to your [`.env`](./environment-variables.md) file:
36
+
37
+ ```bash
38
+ # Snowflake
39
+ SNOWFLAKE_ACCOUNT=xxx.us-east-1
40
+ SNOWFLAKE_USERNAME=xxx
41
+ SNOWFLAKE_PASSWORD=xxx
42
+ SNOWFLAKE_WAREHOUSE=COMPUTE_WH
43
+ SNOWFLAKE_DATABASE=ANALYTICS
44
+ SNOWFLAKE_SCHEMA=PUBLIC
45
+ SNOWFLAKE_ROLE=ANALYST
46
+ ```
47
+
48
+ **Where to find these values:**
49
+
50
+ - **Account**: Snowflake URL (e.g., `xy12345.us-east-1` from `https://xy12345.us-east-1.snowflakecomputing.com`)
51
+ - **Username**: Your Snowflake username
52
+ - **Password**: Your Snowflake password
53
+ - **Warehouse**: Compute warehouse name (create one if needed)
54
+ - **Database**: Database name (create one if needed)
55
+ - **Schema**: Schema name (usually `PUBLIC`)
56
+ - **Role**: Role with appropriate permissions
57
+
58
+ ### 4. Create Snowflake Client
59
+
60
+ Create [`src/lib/snowflake/client.ts`](../../src/lib/snowflake/client.ts):
61
+
62
+ ```typescript
63
+ import snowflake from 'snowflake-sdk'
64
+ import type { Bind } from 'snowflake-sdk'
65
+ import { env } from '@/config/env'
66
+
67
+ const config = {
68
+ account: env.SNOWFLAKE_ACCOUNT,
69
+ username: env.SNOWFLAKE_USERNAME,
70
+ password: env.SNOWFLAKE_PASSWORD,
71
+ warehouse: env.SNOWFLAKE_WAREHOUSE,
72
+ database: env.SNOWFLAKE_DATABASE,
73
+ schema: env.SNOWFLAKE_SCHEMA,
74
+ role: env.SNOWFLAKE_ROLE,
75
+ }
76
+
77
+ export function createSnowflakeConnection() {
78
+ return snowflake.createConnection(config)
79
+ }
80
+
81
+ export async function connectSnowflake(): Promise<snowflake.Connection> {
82
+ return new Promise((resolve, reject) => {
83
+ const connection = createSnowflakeConnection()
84
+ connection.connect((err, conn) => {
85
+ if (err) reject(err)
86
+ else resolve(conn)
87
+ })
88
+ })
89
+ }
90
+
91
+ export async function executeQuery<T = unknown>(
92
+ connection: snowflake.Connection,
93
+ sqlText: string,
94
+ binds?: Bind[]
95
+ ): Promise<T[]> {
96
+ return new Promise((resolve, reject) => {
97
+ connection.execute({
98
+ sqlText,
99
+ binds: binds as any,
100
+ complete: (err, stmt, rows) => {
101
+ if (err) reject(err)
102
+ else resolve((rows || []) as T[])
103
+ },
104
+ })
105
+ })
106
+ }
107
+
108
+ export async function destroyConnection(connection: snowflake.Connection): Promise<void> {
109
+ return new Promise((resolve, reject) => {
110
+ connection.destroy((err) => {
111
+ if (err) reject(err)
112
+ else resolve()
113
+ })
114
+ })
115
+ }
116
+ ```
117
+
118
+ ---
119
+
120
+ ## Query Execution Patterns
121
+
122
+ ### Basic Query Execution
123
+
124
+ ```typescript
125
+ import { connectSnowflake, executeQuery, destroyConnection } from '@/lib/snowflake/client'
126
+
127
+ async function runQuery() {
128
+ const connection = await connectSnowflake()
129
+
130
+ try {
131
+ const results = await executeQuery<{ NAME: string; VALUE: number }>(
132
+ connection,
133
+ 'SELECT NAME, VALUE FROM MY_TABLE LIMIT 10'
134
+ )
135
+
136
+ console.log(results)
137
+ return results
138
+ } finally {
139
+ await destroyConnection(connection)
140
+ }
141
+ }
142
+ ```
143
+
144
+ ### Parameterized Queries
145
+
146
+ ```typescript
147
+ async function runParameterizedQuery(userId: string) {
148
+ const connection = await connectSnowflake()
149
+
150
+ try {
151
+ const results = await executeQuery<{ ID: string; NAME: string }>(
152
+ connection,
153
+ 'SELECT ID, NAME FROM USERS WHERE ID = ?',
154
+ [userId]
155
+ )
156
+
157
+ return results
158
+ } finally {
159
+ await destroyConnection(connection)
160
+ }
161
+ }
162
+ ```
163
+
164
+ ### Multiple Queries in Sequence
165
+
166
+ ```typescript
167
+ async function runMultipleQueries() {
168
+ const connection = await connectSnowflake()
169
+
170
+ try {
171
+ const users = await executeQuery(connection, 'SELECT * FROM USERS LIMIT 10')
172
+ const products = await executeQuery(connection, 'SELECT * FROM PRODUCTS LIMIT 10')
173
+ const orders = await executeQuery(connection, 'SELECT * FROM ORDERS LIMIT 10')
174
+
175
+ return { users, products, orders }
176
+ } finally {
177
+ await destroyConnection(connection)
178
+ }
179
+ }
180
+ ```
181
+
182
+ ---
183
+
184
+ ## Warehouse Configuration
185
+
186
+ ### Snowflake Warehouse Concepts
187
+
188
+ A warehouse in Snowflake is a compute resource that executes queries:
189
+
190
+ | Warehouse Type | Description | Use Case |
191
+ |----------------|-------------|----------|
192
+ | **X-Small** | 1 credit/hour | Testing, development |
193
+ | **Small** | 2 credits/hour | Light analytics |
194
+ | **Medium** | 4 credits/hour | Standard analytics |
195
+ | **Large** | 8 credits/hour | Heavy analytics |
196
+ | **X-Large** | 16 credits/hour | Large datasets |
197
+ | **2X-Large** | 32 credits/hour | Very large datasets |
198
+ | **3X-Large** | 64 credits/hour | Enterprise workloads |
199
+ | **4X-Large** | 128 credits/hour | Maximum performance |
200
+
201
+ ### Creating a Warehouse
202
+
203
+ ```sql
204
+ CREATE WAREHOUSE COMPUTE_WH
205
+ WAREHOUSE_SIZE = 'X-SMALL'
206
+ AUTO_SUSPEND = 300
207
+ AUTO_RESUME = TRUE
208
+ MIN_CLUSTER_COUNT = 1
209
+ MAX_CLUSTER_COUNT = 1
210
+ SCALING_POLICY = 'STANDARD';
211
+ ```
212
+
213
+ ### Warehouse Best Practices
214
+
215
+ 1. **Auto-Suspend**: Enable auto-suspend to save credits when not in use
216
+ 2. **Auto-Resume**: Enable auto-resume for instant availability
217
+ 3. **Right-Size**: Choose the appropriate size for your workload
218
+ 4. **Multi-Cluster**: Use multi-cluster warehouses for high concurrency
219
+ 5. **Monitor Usage**: Regularly review warehouse usage and optimize
220
+
221
+ ---
222
+
223
+ ## Best Practices
224
+
225
+ ### Connection Management
226
+
227
+ **Always close connections:**
228
+
229
+ ```typescript
230
+ // ✅ Good - Always close connection
231
+ async function goodPattern() {
232
+ const connection = await connectSnowflake()
233
+ try {
234
+ return await executeQuery(connection, 'SELECT * FROM TABLE')
235
+ } finally {
236
+ await destroyConnection(connection)
237
+ }
238
+ }
239
+
240
+ // ❌ Bad - Connection not closed
241
+ async function badPattern() {
242
+ const connection = await connectSnowflake()
243
+ return await executeQuery(connection, 'SELECT * FROM TABLE')
244
+ }
245
+ ```
246
+
247
+ **Use connection pooling for high-frequency queries:**
248
+
249
+ ```typescript
250
+ // For high-frequency queries, consider implementing connection pooling
251
+ // Snowflake SDK doesn't have built-in pooling, but you can implement it
252
+ ```
253
+
254
+ ### Query Optimization
255
+
256
+ **Use LIMIT for large datasets:**
257
+
258
+ ```typescript
259
+ // ✅ Good - Limit results
260
+ const results = await executeQuery(connection, 'SELECT * FROM LARGE_TABLE LIMIT 1000')
261
+
262
+ // ❌ Bad - Could return millions of rows
263
+ const results = await executeQuery(connection, 'SELECT * FROM LARGE_TABLE')
264
+ ```
265
+
266
+ **Select only needed columns:**
267
+
268
+ ```typescript
269
+ // ✅ Good - Select only needed columns
270
+ const results = await executeQuery(
271
+ connection,
272
+ 'SELECT ID, NAME FROM USERS'
273
+ )
274
+
275
+ // ❌ Bad - Select all columns
276
+ const results = await executeQuery(
277
+ connection,
278
+ 'SELECT * FROM USERS'
279
+ )
280
+ ```
281
+
282
+ **Use WHERE clauses to filter data:**
283
+
284
+ ```typescript
285
+ // ✅ Good - Filter data
286
+ const results = await executeQuery(
287
+ connection,
288
+ 'SELECT * FROM ORDERS WHERE CREATED_AT >= DATEADD(day, -30, CURRENT_DATE())'
289
+ )
290
+
291
+ // ❌ Bad - No filtering
292
+ const results = await executeQuery(
293
+ connection,
294
+ 'SELECT * FROM ORDERS'
295
+ )
296
+ ```
297
+
298
+ ### Error Handling
299
+
300
+ **Handle connection errors:**
301
+
302
+ ```typescript
303
+ async function safeQuery() {
304
+ try {
305
+ const connection = await connectSnowflake()
306
+ try {
307
+ return await executeQuery(connection, 'SELECT * FROM TABLE')
308
+ } finally {
309
+ await destroyConnection(connection)
310
+ }
311
+ } catch (error) {
312
+ console.error('Snowflake connection error:', error)
313
+ throw new Error('Failed to execute Snowflake query')
314
+ }
315
+ }
316
+ ```
317
+
318
+ **Handle query errors:**
319
+
320
+ ```typescript
321
+ async function safeQueryWithHandling() {
322
+ const connection = await connectSnowflake()
323
+
324
+ try {
325
+ const results = await executeQuery(connection, 'SELECT * FROM NON_EXISTENT_TABLE')
326
+ return results
327
+ } catch (error: any) {
328
+ if (error.code === '002003') {
329
+ // Table does not exist
330
+ console.error('Table not found:', error.message)
331
+ } else {
332
+ console.error('Query error:', error.message)
333
+ }
334
+ throw error
335
+ } finally {
336
+ await destroyConnection(connection)
337
+ }
338
+ }
339
+ ```
340
+
341
+ ### Security
342
+
343
+ **Never hardcode credentials:**
344
+
345
+ ```typescript
346
+ // ❌ Bad - Hardcoded credentials
347
+ const connection = snowflake.createConnection({
348
+ account: 'xy12345.us-east-1',
349
+ username: 'myuser',
350
+ password: 'mypassword', // Never do this!
351
+ // ...
352
+ })
353
+
354
+ // ✅ Good - Use environment variables
355
+ const connection = snowflake.createConnection({
356
+ account: env.SNOWFLAKE_ACCOUNT,
357
+ username: env.SNOWFLAKE_USERNAME,
358
+ password: env.SNOWFLAKE_PASSWORD,
359
+ // ...
360
+ })
361
+ ```
362
+
363
+ **Use least privilege principle:**
364
+
365
+ - Create roles with minimal required permissions
366
+ - Grant only necessary privileges to roles
367
+ - Regularly audit role permissions
368
+
369
+ **Encrypt sensitive data:**
370
+
371
+ - Use Snowflake's built-in encryption
372
+ - Encrypt data at rest and in transit
373
+ - Use secure key management
374
+
375
+ ---
376
+
377
+ ## Health Check Endpoints
378
+
379
+ The framework includes health check endpoints for verifying Snowflake integration:
380
+
381
+ ### Snowflake Health Checks
382
+
383
+ | Endpoint | Method | Description |
384
+ |----------|--------|-------------|
385
+ | `/api/health/snowflake/connect` | GET | Test Snowflake connection |
386
+ | `/api/health/snowflake/query` | GET | Execute test query |
387
+
388
+ ### Connection Check
389
+
390
+ ```typescript
391
+ // GET /api/health/snowflake/connect
392
+ {
393
+ "status": "healthy",
394
+ "responseTimeMs": 234,
395
+ "message": "Successfully connected to Snowflake"
396
+ }
397
+ ```
398
+
399
+ ### Query Check
400
+
401
+ ```typescript
402
+ // GET /api/health/snowflake/query
403
+ {
404
+ "status": "healthy",
405
+ "responseTimeMs": 312,
406
+ "message": "Query executed successfully",
407
+ "data": {
408
+ "timestamp": "2025-12-29 07:50:00.000"
409
+ }
410
+ }
411
+ ```
412
+
413
+ ---
414
+
415
+ ## Advanced Patterns
416
+
417
+ ### Streaming Large Results
418
+
419
+ ```typescript
420
+ async function streamLargeResults() {
421
+ const connection = await connectSnowflake()
422
+
423
+ try {
424
+ const statement = connection.execute({
425
+ sqlText: 'SELECT * FROM LARGE_TABLE',
426
+ streamResult: true,
427
+ complete: (err, stmt, rows) => {
428
+ if (err) {
429
+ console.error('Error:', err)
430
+ return
431
+ }
432
+
433
+ // Process rows in batches
434
+ rows?.forEach((row) => {
435
+ // Process each row
436
+ console.log(row)
437
+ })
438
+ },
439
+ })
440
+ } finally {
441
+ await destroyConnection(connection)
442
+ }
443
+ }
444
+ ```
445
+
446
+ ### Transaction Management
447
+
448
+ ```typescript
449
+ async function transactionExample() {
450
+ const connection = await connectSnowflake()
451
+
452
+ try {
453
+ // Start transaction
454
+ await executeQuery(connection, 'BEGIN')
455
+
456
+ try {
457
+ // Execute multiple statements
458
+ await executeQuery(connection, 'INSERT INTO TABLE1 VALUES (1, 2, 3)')
459
+ await executeQuery(connection, 'UPDATE TABLE2 SET VALUE = 10 WHERE ID = 1')
460
+
461
+ // Commit transaction
462
+ await executeQuery(connection, 'COMMIT')
463
+ } catch (error) {
464
+ // Rollback on error
465
+ await executeQuery(connection, 'ROLLBACK')
466
+ throw error
467
+ }
468
+ } finally {
469
+ await destroyConnection(connection)
470
+ }
471
+ }
472
+ ```
473
+
474
+ ### Batch Operations
475
+
476
+ ```typescript
477
+ async function batchInsert() {
478
+ const connection = await connectSnowflake()
479
+
480
+ try {
481
+ const values = [
482
+ [1, 'Alice', 25],
483
+ [2, 'Bob', 30],
484
+ [3, 'Charlie', 35],
485
+ ]
486
+
487
+ // Build multi-row INSERT
488
+ const valuesStr = values.map(v => `(${v.join(', ')})`).join(', ')
489
+ const sql = `INSERT INTO USERS (ID, NAME, AGE) VALUES ${valuesStr}`
490
+
491
+ await executeQuery(connection, sql)
492
+ } finally {
493
+ await destroyConnection(connection)
494
+ }
495
+ }
496
+ ```
497
+
498
+ ---
499
+
500
+ ## Snowflake SQL Tips
501
+
502
+ ### Common Snowflake Functions
503
+
504
+ **Date Functions:**
505
+
506
+ ```sql
507
+ -- Current date/time
508
+ SELECT CURRENT_DATE();
509
+ SELECT CURRENT_TIMESTAMP();
510
+
511
+ -- Date arithmetic
512
+ SELECT DATEADD(day, -7, CURRENT_DATE());
513
+ SELECT DATEDIFF(day, '2025-01-01', CURRENT_DATE());
514
+
515
+ -- Date truncation
516
+ SELECT DATE_TRUNC('month', CURRENT_DATE());
517
+ ```
518
+
519
+ **String Functions:**
520
+
521
+ ```sql
522
+ -- String manipulation
523
+ SELECT UPPER('hello');
524
+ SELECT LOWER('HELLO');
525
+ SELECT TRIM(' hello ');
526
+ SELECT CONCAT('Hello', ' ', 'World');
527
+
528
+ -- String matching
529
+ SELECT * FROM TABLE WHERE NAME LIKE '%test%';
530
+ SELECT REGEXP_SUBSTR('hello-world', '[^-]+');
531
+ ```
532
+
533
+ **Aggregate Functions:**
534
+
535
+ ```sql
536
+ -- Basic aggregates
537
+ SELECT COUNT(*), SUM(VALUE), AVG(VALUE), MIN(VALUE), MAX(VALUE) FROM TABLE;
538
+
539
+ -- Group by
540
+ SELECT CATEGORY, COUNT(*), AVG(VALUE) FROM TABLE GROUP BY CATEGORY;
541
+
542
+ -- Window functions
543
+ SELECT
544
+ NAME,
545
+ VALUE,
546
+ AVG(VALUE) OVER (PARTITION BY CATEGORY) AS CATEGORY_AVG
547
+ FROM TABLE;
548
+ ```
549
+
550
+ ---
551
+
552
+ ## Troubleshooting
553
+
554
+ ### Common Issues
555
+
556
+ **Issue: Connection timeout**
557
+
558
+ - Verify account identifier is correct
559
+ - Check network connectivity
560
+ - Verify firewall allows Snowflake traffic
561
+ - Check if warehouse is suspended
562
+
563
+ **Issue: Authentication failed**
564
+
565
+ - Verify username and password are correct
566
+ - Check if account is locked
567
+ - Verify role has necessary permissions
568
+ - Check if password has expired
569
+
570
+ **Issue: Query timeout**
571
+
572
+ - Increase warehouse size
573
+ - Optimize query (add WHERE clause, use LIMIT)
574
+ - Check if warehouse is auto-suspended
575
+ - Verify query is not blocked by a lock
576
+
577
+ **Issue: "Object does not exist"**
578
+
579
+ - Verify database, schema, and table names are correct
580
+ - Check if you're using the correct role
581
+ - Verify you have access to the object
582
+ - Check if object exists in the correct schema
583
+
584
+ ---
585
+
586
+ ## Related Documentation
587
+
588
+ - [Environment Variables](./environment-variables.md) - Snowflake environment variables
589
+ - [API Layer](./api-layer.md) - Snowflake API routes
590
+ - [Health Check System](./health-check-system.md) - Health check endpoints
591
+ - [Supabase Integration](./supabase-integration.md) - Primary database setup