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