@odvi/create-dtt-framework 0.1.8 → 0.1.10
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.
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +3 -0
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +170 -73
- package/dist/commands/update.js.map +1 -1
- package/package.json +1 -1
- package/template/.env.example +117 -106
- package/template/docs/framework/environment-variables.md +52 -0
- package/template/src/config/env.ts +5 -0
- package/template/src/features/health-check/config.ts +7 -0
- package/template/src/server/api/routes/health/aws-s3.ts +59 -0
- package/template/src/server/api/routes/health/index.ts +7 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,eAAO,MAAM,aAAa,SAgKtB,CAAC"}
|
package/dist/commands/create.js
CHANGED
|
@@ -105,6 +105,9 @@ export const createCommand = new Command('create')
|
|
|
105
105
|
const packageJson = await fs.readJson(packageJsonPath);
|
|
106
106
|
packageJson.name = projectName;
|
|
107
107
|
packageJson.version = '0.1.0';
|
|
108
|
+
packageJson.dtt = {
|
|
109
|
+
version: '0.1.9' // Current framework version
|
|
110
|
+
};
|
|
108
111
|
await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
|
|
109
112
|
spinner.succeed('Project configured');
|
|
110
113
|
// Initialize git if not disabled
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBpC,eAAO,MAAM,aAAa,SAwNtB,CAAC"}
|
package/dist/commands/update.js
CHANGED
|
@@ -3,101 +3,198 @@ import chalk from 'chalk';
|
|
|
3
3
|
import ora from 'ora';
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import fs from 'fs-extra';
|
|
6
|
-
import
|
|
6
|
+
import inquirer from 'inquirer';
|
|
7
|
+
import { getTemplatePath } from '../utils/template.js';
|
|
8
|
+
async function getFiles(dir) {
|
|
9
|
+
const subdirs = await fs.readdir(dir);
|
|
10
|
+
const files = await Promise.all(subdirs.map(async (subdir) => {
|
|
11
|
+
const res = path.resolve(dir, subdir);
|
|
12
|
+
return (await fs.stat(res)).isDirectory() ? getFiles(res) : res;
|
|
13
|
+
}));
|
|
14
|
+
return files.flat();
|
|
15
|
+
}
|
|
7
16
|
export const updateCommand = new Command('update')
|
|
8
|
-
.description('Update DTT Framework to the latest version')
|
|
17
|
+
.description('Update DTT Framework project files to the latest version')
|
|
9
18
|
.option('--check-only', 'Only check for updates without installing')
|
|
10
|
-
.option('--force', 'Force update
|
|
19
|
+
.option('--force', 'Force update and overwrite all files')
|
|
20
|
+
.option('--yes', 'Skip confirmation prompts')
|
|
11
21
|
.action(async (options) => {
|
|
12
22
|
try {
|
|
13
23
|
console.log();
|
|
14
|
-
console.log(chalk.cyan.bold('🔄
|
|
24
|
+
console.log(chalk.cyan.bold('🔄 DTT Framework Updater'));
|
|
15
25
|
console.log();
|
|
16
|
-
const spinner = ora('Checking
|
|
17
|
-
|
|
18
|
-
const packageJsonPath = path.join(
|
|
26
|
+
const spinner = ora('Checking project...').start();
|
|
27
|
+
const projectPath = process.cwd();
|
|
28
|
+
const packageJsonPath = path.join(projectPath, 'package.json');
|
|
19
29
|
if (!(await fs.pathExists(packageJsonPath))) {
|
|
20
|
-
spinner.fail('package.json not found
|
|
21
|
-
console.log(chalk.yellow('Please run this command from
|
|
30
|
+
spinner.fail('package.json not found');
|
|
31
|
+
console.log(chalk.yellow('Please run this command from the root of your DTT Framework project.'));
|
|
22
32
|
process.exit(1);
|
|
23
33
|
}
|
|
24
34
|
const packageJson = await fs.readJson(packageJsonPath);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
35
|
+
// Heuristic check: look for specific framework files if 'dtt' metadata is missing
|
|
36
|
+
const isDttProject = packageJson.dtt ||
|
|
37
|
+
(await fs.pathExists(path.join(projectPath, 'src/features/health-check'))) ||
|
|
38
|
+
(await fs.pathExists(path.join(projectPath, 'src/lib/snowflake')));
|
|
39
|
+
if (!isDttProject) {
|
|
40
|
+
spinner.fail('Not a DTT Framework project');
|
|
41
|
+
console.log(chalk.yellow('This directory does not appear to be a DTT Framework project.'));
|
|
29
42
|
process.exit(1);
|
|
30
43
|
}
|
|
31
|
-
spinner.succeed(
|
|
32
|
-
//
|
|
33
|
-
|
|
44
|
+
spinner.succeed('Project detected');
|
|
45
|
+
// Get template path
|
|
46
|
+
const templatePath = getTemplatePath();
|
|
47
|
+
if (!(await fs.pathExists(templatePath))) {
|
|
48
|
+
spinner.fail('Template files not found');
|
|
49
|
+
console.log(chalk.red('Could not locate framework template files.'));
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
spinner.text = 'Scanning files...';
|
|
34
53
|
spinner.start();
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
54
|
+
// Get all files from template
|
|
55
|
+
const templateFilesAbs = await getFiles(templatePath);
|
|
56
|
+
const templateFiles = templateFilesAbs.map(f => path.relative(templatePath, f));
|
|
57
|
+
// Filter out ignored files
|
|
58
|
+
const ignoredPatterns = [
|
|
59
|
+
'node_modules',
|
|
60
|
+
'.git',
|
|
61
|
+
'.next',
|
|
62
|
+
'dist',
|
|
63
|
+
'package.json', // Handle package.json separately or ignore for now as it's user-specific
|
|
64
|
+
'pnpm-lock.yaml',
|
|
65
|
+
'yarn.lock',
|
|
66
|
+
'package-lock.json',
|
|
67
|
+
'.env',
|
|
68
|
+
'.env.local'
|
|
69
|
+
];
|
|
70
|
+
const relevantFiles = templateFiles.filter(file => {
|
|
71
|
+
const parts = file.split(path.sep);
|
|
72
|
+
return !ignoredPatterns.some(pattern => parts.includes(pattern));
|
|
73
|
+
});
|
|
74
|
+
const newFiles = [];
|
|
75
|
+
const modifiedFiles = [];
|
|
76
|
+
const upToDateFiles = [];
|
|
77
|
+
for (const file of relevantFiles) {
|
|
78
|
+
const targetPath = path.join(projectPath, file);
|
|
79
|
+
const templateFilePath = path.join(templatePath, file);
|
|
80
|
+
if (!(await fs.pathExists(targetPath))) {
|
|
81
|
+
newFiles.push(file);
|
|
43
82
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
83
|
+
else {
|
|
84
|
+
// Compare content
|
|
85
|
+
const targetContent = await fs.readFile(targetPath);
|
|
86
|
+
const templateContent = await fs.readFile(templateFilePath);
|
|
87
|
+
if (!targetContent.equals(templateContent)) {
|
|
88
|
+
modifiedFiles.push(file);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
upToDateFiles.push(file);
|
|
92
|
+
}
|
|
52
93
|
}
|
|
53
|
-
|
|
94
|
+
}
|
|
95
|
+
spinner.stop();
|
|
96
|
+
console.log(chalk.bold('\nAnalysis Results:'));
|
|
97
|
+
console.log(chalk.green(` + ${newFiles.length} new files to add`));
|
|
98
|
+
console.log(chalk.yellow(` ~ ${modifiedFiles.length} files differ from latest template`));
|
|
99
|
+
console.log(chalk.gray(` = ${upToDateFiles.length} files match exactly`));
|
|
100
|
+
console.log();
|
|
101
|
+
if (newFiles.length === 0 && modifiedFiles.length === 0) {
|
|
102
|
+
console.log(chalk.green('✨ Your project is up to date!'));
|
|
103
|
+
process.exit(0);
|
|
104
|
+
}
|
|
105
|
+
if (options?.checkOnly) {
|
|
106
|
+
process.exit(0);
|
|
107
|
+
}
|
|
108
|
+
// Handle New Files
|
|
109
|
+
if (newFiles.length > 0) {
|
|
110
|
+
console.log(chalk.green.bold('New files will be added:'));
|
|
111
|
+
newFiles.slice(0, 5).forEach(f => console.log(chalk.green(` + ${f}`)));
|
|
112
|
+
if (newFiles.length > 5)
|
|
113
|
+
console.log(chalk.gray(` ...and ${newFiles.length - 5} more`));
|
|
114
|
+
console.log();
|
|
115
|
+
}
|
|
116
|
+
// Handle Modified Files
|
|
117
|
+
if (modifiedFiles.length > 0) {
|
|
118
|
+
console.log(chalk.yellow.bold('Modified files (conflicts):'));
|
|
119
|
+
console.log(chalk.yellow(' These files differ from the latest framework version.'));
|
|
120
|
+
console.log(chalk.yellow(' Updating them might overwrite your custom changes.'));
|
|
121
|
+
modifiedFiles.slice(0, 5).forEach(f => console.log(chalk.yellow(` ~ ${f}`)));
|
|
122
|
+
if (modifiedFiles.length > 5)
|
|
123
|
+
console.log(chalk.gray(` ...and ${modifiedFiles.length - 5} more`));
|
|
54
124
|
console.log();
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
125
|
+
}
|
|
126
|
+
let shouldProceed = options?.yes || options?.force;
|
|
127
|
+
if (!shouldProceed) {
|
|
128
|
+
const answers = await inquirer.prompt([
|
|
129
|
+
{
|
|
130
|
+
type: 'confirm',
|
|
131
|
+
name: 'proceed',
|
|
132
|
+
message: 'Do you want to proceed with the update?',
|
|
133
|
+
default: true,
|
|
61
134
|
}
|
|
62
|
-
|
|
63
|
-
|
|
135
|
+
]);
|
|
136
|
+
shouldProceed = answers.proceed;
|
|
137
|
+
}
|
|
138
|
+
if (!shouldProceed) {
|
|
139
|
+
console.log(chalk.yellow('Update cancelled.'));
|
|
140
|
+
process.exit(0);
|
|
141
|
+
}
|
|
142
|
+
const updateSpinner = ora('Updating files...').start();
|
|
143
|
+
// Copy new files
|
|
144
|
+
for (const file of newFiles) {
|
|
145
|
+
const source = path.join(templatePath, file);
|
|
146
|
+
const dest = path.join(projectPath, file);
|
|
147
|
+
await fs.copy(source, dest);
|
|
148
|
+
}
|
|
149
|
+
// Handle modified files
|
|
150
|
+
let updatedCount = 0;
|
|
151
|
+
let skippedCount = 0;
|
|
152
|
+
if (modifiedFiles.length > 0) {
|
|
153
|
+
if (options?.force) {
|
|
154
|
+
// Overwrite everything
|
|
155
|
+
for (const file of modifiedFiles) {
|
|
156
|
+
const source = path.join(templatePath, file);
|
|
157
|
+
const dest = path.join(projectPath, file);
|
|
158
|
+
await fs.copy(source, dest);
|
|
159
|
+
updatedCount++;
|
|
64
160
|
}
|
|
65
|
-
execSync(`${packageManager} update dtt-framework@latest`, { stdio: 'inherit' });
|
|
66
|
-
updateSpinner.succeed('Update completed successfully!');
|
|
67
|
-
console.log();
|
|
68
|
-
console.log(chalk.green.bold('✨ DTT Framework updated successfully!'));
|
|
69
|
-
console.log();
|
|
70
|
-
console.log(chalk.cyan('Changes:'));
|
|
71
|
-
console.log(chalk.white(` Updated from ${currentVersion} to ${latestVersion}`));
|
|
72
|
-
console.log();
|
|
73
|
-
console.log(chalk.yellow('Please review the changelog for breaking changes:'));
|
|
74
|
-
console.log(chalk.cyan(' https://github.com/your-org/dtt-framework/releases'));
|
|
75
|
-
console.log();
|
|
76
|
-
console.log(chalk.cyan('Next steps:'));
|
|
77
|
-
console.log(chalk.white(' Review and update your code if needed'));
|
|
78
|
-
console.log(chalk.white(' Run tests to ensure everything works'));
|
|
79
|
-
console.log();
|
|
80
161
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
162
|
+
else {
|
|
163
|
+
// Ask for strategy if not forced?
|
|
164
|
+
// For now, let's skip modified files by default to be safe, unless user explicitly asks.
|
|
165
|
+
// Or maybe create .new files?
|
|
166
|
+
// The user asked for "check if there is newly changes code... they can also get the latest updated code".
|
|
167
|
+
// If we skip, they don't get the update for modified files.
|
|
168
|
+
// Let's create .update files for manual merge.
|
|
169
|
+
for (const file of modifiedFiles) {
|
|
170
|
+
const source = path.join(templatePath, file);
|
|
171
|
+
const dest = path.join(projectPath, `${file}.update`);
|
|
172
|
+
await fs.copy(source, dest);
|
|
173
|
+
skippedCount++;
|
|
174
|
+
}
|
|
91
175
|
}
|
|
92
176
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
console.log();
|
|
99
|
-
|
|
177
|
+
updateSpinner.succeed('Update complete');
|
|
178
|
+
console.log();
|
|
179
|
+
console.log(chalk.green.bold('✨ Project updated successfully!'));
|
|
180
|
+
console.log();
|
|
181
|
+
if (newFiles.length > 0) {
|
|
182
|
+
console.log(chalk.green(` Added ${newFiles.length} new files.`));
|
|
183
|
+
}
|
|
184
|
+
if (skippedCount > 0) {
|
|
185
|
+
console.log(chalk.yellow(` Created ${skippedCount} .update files for modified files.`));
|
|
186
|
+
console.log(chalk.yellow(' Please review these files and merge changes manually into your code.'));
|
|
100
187
|
}
|
|
188
|
+
else if (updatedCount > 0) {
|
|
189
|
+
console.log(chalk.green(` Updated ${updatedCount} modified files.`));
|
|
190
|
+
}
|
|
191
|
+
// Check package.json dependencies
|
|
192
|
+
console.log();
|
|
193
|
+
console.log(chalk.cyan('Checking dependencies...'));
|
|
194
|
+
// This is harder because we don't have the "template" package.json easily available as a file.
|
|
195
|
+
// But we can remind the user to run install.
|
|
196
|
+
console.log(chalk.gray(' Remember to run `pnpm install` to update dependencies.'));
|
|
197
|
+
console.log();
|
|
101
198
|
}
|
|
102
199
|
catch (error) {
|
|
103
200
|
console.error(chalk.red('Error during update:'), error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/template/.env.example
CHANGED
|
@@ -1,106 +1,117 @@
|
|
|
1
|
-
# Since the ".env" file is gitignored, you can use the ".env.example" file to
|
|
2
|
-
# build a new ".env" file when you clone the repo. Keep this file up-to-date
|
|
3
|
-
# when you add new variables to `.env`.
|
|
4
|
-
|
|
5
|
-
# This file will be committed to version control, so make sure not to have any
|
|
6
|
-
# secrets in it. If you are cloning this repo, create a copy of this file named
|
|
7
|
-
# ".env" and populate it with your secrets.
|
|
8
|
-
|
|
9
|
-
# When adding additional environment variables, the schema in "/src/env.js"
|
|
10
|
-
# should be updated accordingly.
|
|
11
|
-
|
|
12
|
-
# ========================================
|
|
13
|
-
# App Configuration
|
|
14
|
-
# ========================================
|
|
15
|
-
# The base URL of your application. Used for redirects, webhooks, and callbacks.
|
|
16
|
-
# In development: http://localhost:3000
|
|
17
|
-
# In production: https://your-domain.com
|
|
18
|
-
NEXT_PUBLIC_APP_URL=http://localhost:3000
|
|
19
|
-
|
|
20
|
-
# ========================================
|
|
21
|
-
# Clerk Authentication
|
|
22
|
-
# ========================================
|
|
23
|
-
# Clerk publishable key - used on the client side for authentication
|
|
24
|
-
# Get this from your Clerk Dashboard > API Keys > Publishable Key
|
|
25
|
-
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxx
|
|
26
|
-
|
|
27
|
-
# Clerk secret key - used on the server side for authentication
|
|
28
|
-
# Get this from your Clerk Dashboard > API Keys > Secret Key
|
|
29
|
-
CLERK_SECRET_KEY=sk_test_xxx
|
|
30
|
-
|
|
31
|
-
# Clerk webhook secret - used to verify webhook events from Clerk
|
|
32
|
-
# Get this from your Clerk Dashboard > Webhooks > Add Endpoint > Signing Secret
|
|
33
|
-
CLERK_WEBHOOK_SECRET=whsec_xxx
|
|
34
|
-
|
|
35
|
-
# URL path for the sign-in page
|
|
36
|
-
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
|
|
37
|
-
|
|
38
|
-
# URL path for the sign-up page
|
|
39
|
-
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
|
|
40
|
-
|
|
41
|
-
# Where to redirect users after successful sign-in
|
|
42
|
-
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/health
|
|
43
|
-
|
|
44
|
-
# Where to redirect users after successful sign-up
|
|
45
|
-
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/health
|
|
46
|
-
|
|
47
|
-
# ========================================
|
|
48
|
-
# Supabase
|
|
49
|
-
# ========================================
|
|
50
|
-
# Supabase project URL - found in your Supabase project settings
|
|
51
|
-
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
|
|
52
|
-
|
|
53
|
-
# Supabase anonymous/public key - safe to expose on client side
|
|
54
|
-
# Found in your Supabase project settings under API keys
|
|
55
|
-
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJxxx
|
|
56
|
-
|
|
57
|
-
# Supabase service role key - full admin access, keep secret!
|
|
58
|
-
# Found in your Supabase project settings under API keys
|
|
59
|
-
SUPABASE_SERVICE_ROLE_KEY=eyJxxx
|
|
60
|
-
|
|
61
|
-
# PostgreSQL connection string for Drizzle ORM
|
|
62
|
-
# Use Supabase's Transaction mode pooler for better performance
|
|
63
|
-
# Format: postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
|
|
64
|
-
DATABASE_URL=postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
|
|
65
|
-
|
|
66
|
-
# ========================================
|
|
67
|
-
# Snowflake Data Warehouse
|
|
68
|
-
# ========================================
|
|
69
|
-
# Snowflake account identifier (e.g., ef19411.ap-southeast-1)
|
|
70
|
-
SNOWFLAKE_ACCOUNT=ef19411.ap-southeast-1
|
|
71
|
-
|
|
72
|
-
# Snowflake warehouse to use
|
|
73
|
-
SNOWFLAKE_WAREHOUSE=COMPUTE_WH
|
|
74
|
-
|
|
75
|
-
# Snowflake role
|
|
76
|
-
SNOWFLAKE_ROLE=ACCOUNTADMIN
|
|
77
|
-
|
|
78
|
-
# Authentication method (SNOWFLAKE_JWT for Key Pair Auth)
|
|
79
|
-
SNOWFLAKE_AUTHENTICATOR=SNOWFLAKE_JWT
|
|
80
|
-
|
|
81
|
-
# Snowflake username
|
|
82
|
-
SNOWFLAKE_USERNAME=APP_USER_WITH_KEY_AUTH
|
|
83
|
-
|
|
84
|
-
# Private Key for Authentication (PEM format)
|
|
85
|
-
SNOWFLAKE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
|
|
86
|
-
...
|
|
87
|
-
-----END PRIVATE KEY-----"
|
|
88
|
-
|
|
89
|
-
# Passphrase for the Private Key (if encrypted)
|
|
90
|
-
SNOWFLAKE_PRIVATE_KEY_PASSPHRASE="<password>"
|
|
91
|
-
|
|
92
|
-
# Enable logging (optional)
|
|
93
|
-
SNOWFLAKE_LOGGING=true
|
|
94
|
-
|
|
95
|
-
# ========================================
|
|
96
|
-
#
|
|
97
|
-
# ========================================
|
|
98
|
-
#
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
#
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
#
|
|
105
|
-
|
|
106
|
-
|
|
1
|
+
# Since the ".env" file is gitignored, you can use the ".env.example" file to
|
|
2
|
+
# build a new ".env" file when you clone the repo. Keep this file up-to-date
|
|
3
|
+
# when you add new variables to `.env`.
|
|
4
|
+
|
|
5
|
+
# This file will be committed to version control, so make sure not to have any
|
|
6
|
+
# secrets in it. If you are cloning this repo, create a copy of this file named
|
|
7
|
+
# ".env" and populate it with your secrets.
|
|
8
|
+
|
|
9
|
+
# When adding additional environment variables, the schema in "/src/env.js"
|
|
10
|
+
# should be updated accordingly.
|
|
11
|
+
|
|
12
|
+
# ========================================
|
|
13
|
+
# App Configuration
|
|
14
|
+
# ========================================
|
|
15
|
+
# The base URL of your application. Used for redirects, webhooks, and callbacks.
|
|
16
|
+
# In development: http://localhost:3000
|
|
17
|
+
# In production: https://your-domain.com
|
|
18
|
+
NEXT_PUBLIC_APP_URL=http://localhost:3000
|
|
19
|
+
|
|
20
|
+
# ========================================
|
|
21
|
+
# Clerk Authentication
|
|
22
|
+
# ========================================
|
|
23
|
+
# Clerk publishable key - used on the client side for authentication
|
|
24
|
+
# Get this from your Clerk Dashboard > API Keys > Publishable Key
|
|
25
|
+
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxx
|
|
26
|
+
|
|
27
|
+
# Clerk secret key - used on the server side for authentication
|
|
28
|
+
# Get this from your Clerk Dashboard > API Keys > Secret Key
|
|
29
|
+
CLERK_SECRET_KEY=sk_test_xxx
|
|
30
|
+
|
|
31
|
+
# Clerk webhook secret - used to verify webhook events from Clerk
|
|
32
|
+
# Get this from your Clerk Dashboard > Webhooks > Add Endpoint > Signing Secret
|
|
33
|
+
CLERK_WEBHOOK_SECRET=whsec_xxx
|
|
34
|
+
|
|
35
|
+
# URL path for the sign-in page
|
|
36
|
+
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
|
|
37
|
+
|
|
38
|
+
# URL path for the sign-up page
|
|
39
|
+
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
|
|
40
|
+
|
|
41
|
+
# Where to redirect users after successful sign-in
|
|
42
|
+
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/health
|
|
43
|
+
|
|
44
|
+
# Where to redirect users after successful sign-up
|
|
45
|
+
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/health
|
|
46
|
+
|
|
47
|
+
# ========================================
|
|
48
|
+
# Supabase
|
|
49
|
+
# ========================================
|
|
50
|
+
# Supabase project URL - found in your Supabase project settings
|
|
51
|
+
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
|
|
52
|
+
|
|
53
|
+
# Supabase anonymous/public key - safe to expose on client side
|
|
54
|
+
# Found in your Supabase project settings under API keys
|
|
55
|
+
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJxxx
|
|
56
|
+
|
|
57
|
+
# Supabase service role key - full admin access, keep secret!
|
|
58
|
+
# Found in your Supabase project settings under API keys
|
|
59
|
+
SUPABASE_SERVICE_ROLE_KEY=eyJxxx
|
|
60
|
+
|
|
61
|
+
# PostgreSQL connection string for Drizzle ORM
|
|
62
|
+
# Use Supabase's Transaction mode pooler for better performance
|
|
63
|
+
# Format: postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
|
|
64
|
+
DATABASE_URL=postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
|
|
65
|
+
|
|
66
|
+
# ========================================
|
|
67
|
+
# Snowflake Data Warehouse
|
|
68
|
+
# ========================================
|
|
69
|
+
# Snowflake account identifier (e.g., ef19411.ap-southeast-1)
|
|
70
|
+
SNOWFLAKE_ACCOUNT=ef19411.ap-southeast-1
|
|
71
|
+
|
|
72
|
+
# Snowflake warehouse to use
|
|
73
|
+
SNOWFLAKE_WAREHOUSE=COMPUTE_WH
|
|
74
|
+
|
|
75
|
+
# Snowflake role
|
|
76
|
+
SNOWFLAKE_ROLE=ACCOUNTADMIN
|
|
77
|
+
|
|
78
|
+
# Authentication method (SNOWFLAKE_JWT for Key Pair Auth)
|
|
79
|
+
SNOWFLAKE_AUTHENTICATOR=SNOWFLAKE_JWT
|
|
80
|
+
|
|
81
|
+
# Snowflake username
|
|
82
|
+
SNOWFLAKE_USERNAME=APP_USER_WITH_KEY_AUTH
|
|
83
|
+
|
|
84
|
+
# Private Key for Authentication (PEM format)
|
|
85
|
+
SNOWFLAKE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
|
|
86
|
+
...
|
|
87
|
+
-----END PRIVATE KEY-----"
|
|
88
|
+
|
|
89
|
+
# Passphrase for the Private Key (if encrypted)
|
|
90
|
+
SNOWFLAKE_PRIVATE_KEY_PASSPHRASE="<password>"
|
|
91
|
+
|
|
92
|
+
# Enable logging (optional)
|
|
93
|
+
SNOWFLAKE_LOGGING=true
|
|
94
|
+
|
|
95
|
+
# ========================================
|
|
96
|
+
# AWS S3 (Optional)
|
|
97
|
+
# ========================================
|
|
98
|
+
# AWS Access Key ID for S3 access
|
|
99
|
+
AWS_ACCESS_KEY_ID=AKIA...
|
|
100
|
+
|
|
101
|
+
# AWS Secret Access Key for S3 access
|
|
102
|
+
AWS_ACCESS_SECRET_KEY=wJalr...
|
|
103
|
+
|
|
104
|
+
# AWS Region where your S3 buckets are located (e.g., us-east-1)
|
|
105
|
+
AWS_REGION=us-east-1
|
|
106
|
+
|
|
107
|
+
# ========================================
|
|
108
|
+
# NextBank API (Placeholder)
|
|
109
|
+
# ========================================
|
|
110
|
+
# Base URL for the NextBank API endpoint
|
|
111
|
+
NEXTBANK_API=https://api.nextbank.com
|
|
112
|
+
|
|
113
|
+
# Username for NextBank Basic Authentication
|
|
114
|
+
NEXTBANK_API_USERNAME=user
|
|
115
|
+
|
|
116
|
+
# Password for NextBank Basic Authentication
|
|
117
|
+
NEXTBANK_API_PASSWORD=pass
|
|
@@ -97,6 +97,19 @@ SNOWFLAKE_SCHEMA=PUBLIC
|
|
|
97
97
|
# Snowflake role name
|
|
98
98
|
SNOWFLAKE_ROLE=ANALYST
|
|
99
99
|
|
|
100
|
+
# ============================================
|
|
101
|
+
# AWS S3 (Optional)
|
|
102
|
+
# ============================================
|
|
103
|
+
|
|
104
|
+
# AWS Access Key ID
|
|
105
|
+
AWS_ACCESS_KEY_ID=AKIA...
|
|
106
|
+
|
|
107
|
+
# AWS Secret Access Key
|
|
108
|
+
AWS_ACCESS_SECRET_KEY=wJalr...
|
|
109
|
+
|
|
110
|
+
# AWS Region (e.g., us-east-1, ap-southeast-1)
|
|
111
|
+
AWS_REGION=us-east-1
|
|
112
|
+
|
|
100
113
|
# ============================================
|
|
101
114
|
# NextBank (Placeholder - Optional)
|
|
102
115
|
# ============================================
|
|
@@ -418,6 +431,45 @@ SNOWFLAKE_ROLE=ANALYST
|
|
|
418
431
|
|
|
419
432
|
---
|
|
420
433
|
|
|
434
|
+
### AWS S3 Variables (Optional)
|
|
435
|
+
|
|
436
|
+
#### AWS_ACCESS_KEY_ID
|
|
437
|
+
|
|
438
|
+
**Purpose:** AWS Access Key ID for S3 access
|
|
439
|
+
|
|
440
|
+
**Where to find:** AWS IAM Console → Users → Security credentials
|
|
441
|
+
|
|
442
|
+
**Example:**
|
|
443
|
+
```bash
|
|
444
|
+
AWS_ACCESS_KEY_ID=AKIA...
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
#### AWS_ACCESS_SECRET_KEY
|
|
448
|
+
|
|
449
|
+
**Purpose:** AWS Secret Access Key for S3 access
|
|
450
|
+
|
|
451
|
+
**Where to find:** AWS IAM Console → Users → Security credentials (only visible when created)
|
|
452
|
+
|
|
453
|
+
**Example:**
|
|
454
|
+
```bash
|
|
455
|
+
AWS_ACCESS_SECRET_KEY=wJalr...
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
**Notes:**
|
|
459
|
+
- Never commit to version control
|
|
460
|
+
- Ensure the user has appropriate S3 permissions (e.g., `AmazonS3ReadOnlyAccess` or custom policy)
|
|
461
|
+
|
|
462
|
+
#### AWS_REGION
|
|
463
|
+
|
|
464
|
+
**Purpose:** AWS Region where your S3 buckets are located
|
|
465
|
+
|
|
466
|
+
**Example:**
|
|
467
|
+
```bash
|
|
468
|
+
AWS_REGION=us-east-1
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
---
|
|
472
|
+
|
|
421
473
|
### NextBank Variables (Placeholder)
|
|
422
474
|
|
|
423
475
|
**Note:** NextBank is a placeholder integration. These variables are optional and not currently used.
|
|
@@ -30,6 +30,11 @@ const envSchema = z.object({
|
|
|
30
30
|
NEXTBANK_API: z.string().url().optional(),
|
|
31
31
|
NEXTBANK_API_USERNAME: z.string().optional(),
|
|
32
32
|
NEXTBANK_API_PASSWORD: z.string().optional(),
|
|
33
|
+
|
|
34
|
+
// AWS S3 (optional)
|
|
35
|
+
AWS_ACCESS_KEY_ID: z.string().optional(),
|
|
36
|
+
AWS_ACCESS_SECRET_KEY: z.string().optional(),
|
|
37
|
+
AWS_REGION: z.string().optional(),
|
|
33
38
|
})
|
|
34
39
|
|
|
35
40
|
export const env = envSchema.parse(process.env)
|
|
@@ -52,6 +52,13 @@ export const SERVICES = [
|
|
|
52
52
|
{ name: 'Ping API', endpoint: '/nextbank/ping' },
|
|
53
53
|
],
|
|
54
54
|
},
|
|
55
|
+
{
|
|
56
|
+
name: 'AWS S3',
|
|
57
|
+
icon: 'cloud',
|
|
58
|
+
checks: [
|
|
59
|
+
{ name: 'Connect', endpoint: '/aws-s3/connect' },
|
|
60
|
+
],
|
|
61
|
+
},
|
|
55
62
|
{
|
|
56
63
|
name: 'Framework',
|
|
57
64
|
icon: 'code',
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Hono } from 'hono'
|
|
2
|
+
import { S3Client, ListBucketsCommand } from '@aws-sdk/client-s3'
|
|
3
|
+
import { env } from '@/config/env'
|
|
4
|
+
|
|
5
|
+
export const awsS3HealthRoutes = new Hono()
|
|
6
|
+
|
|
7
|
+
awsS3HealthRoutes.get('/connect', async (c) => {
|
|
8
|
+
const start = performance.now()
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
// Check if credentials are configured
|
|
12
|
+
if (!env.AWS_ACCESS_KEY_ID || !env.AWS_ACCESS_SECRET_KEY || !env.AWS_REGION) {
|
|
13
|
+
return c.json({
|
|
14
|
+
status: 'warning',
|
|
15
|
+
responseTimeMs: Math.round(performance.now() - start),
|
|
16
|
+
message: 'AWS S3 credentials not configured - skipping connection check',
|
|
17
|
+
data: {
|
|
18
|
+
skipped: true,
|
|
19
|
+
reason: 'Missing AWS_ACCESS_KEY_ID, AWS_ACCESS_SECRET_KEY, or AWS_REGION',
|
|
20
|
+
},
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const s3Client = new S3Client({
|
|
25
|
+
region: env.AWS_REGION,
|
|
26
|
+
credentials: {
|
|
27
|
+
accessKeyId: env.AWS_ACCESS_KEY_ID,
|
|
28
|
+
secretAccessKey: env.AWS_ACCESS_SECRET_KEY,
|
|
29
|
+
},
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
// Try to list buckets to verify connectivity and credentials
|
|
33
|
+
const command = new ListBucketsCommand({})
|
|
34
|
+
const response = await s3Client.send(command)
|
|
35
|
+
|
|
36
|
+
return c.json({
|
|
37
|
+
status: 'healthy',
|
|
38
|
+
responseTimeMs: Math.round(performance.now() - start),
|
|
39
|
+
message: 'Successfully connected to AWS S3',
|
|
40
|
+
data: {
|
|
41
|
+
region: env.AWS_REGION,
|
|
42
|
+
bucketCount: response.Buckets?.length ?? 0,
|
|
43
|
+
},
|
|
44
|
+
})
|
|
45
|
+
} catch (error) {
|
|
46
|
+
return c.json(
|
|
47
|
+
{
|
|
48
|
+
status: 'error',
|
|
49
|
+
responseTimeMs: Math.round(performance.now() - start),
|
|
50
|
+
error: error instanceof Error ? error.message : 'Failed to connect to AWS S3',
|
|
51
|
+
data: {
|
|
52
|
+
details: error instanceof Error ? error.stack : undefined,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
500
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
|
|
@@ -6,6 +6,7 @@ import { edgeFunctionsHealthRoutes } from './edge-functions'
|
|
|
6
6
|
import { snowflakeHealthRoutes } from './snowflake'
|
|
7
7
|
import { nextbankHealthRoutes } from './nextbank'
|
|
8
8
|
import { frameworkHealthRoutes } from './framework'
|
|
9
|
+
import { awsS3HealthRoutes } from './aws-s3'
|
|
9
10
|
|
|
10
11
|
export const healthRoutes = new Hono()
|
|
11
12
|
|
|
@@ -16,6 +17,7 @@ healthRoutes.route('/edge', edgeFunctionsHealthRoutes)
|
|
|
16
17
|
healthRoutes.route('/snowflake', snowflakeHealthRoutes)
|
|
17
18
|
healthRoutes.route('/nextbank', nextbankHealthRoutes)
|
|
18
19
|
healthRoutes.route('/framework', frameworkHealthRoutes)
|
|
20
|
+
healthRoutes.route('/aws-s3', awsS3HealthRoutes)
|
|
19
21
|
|
|
20
22
|
healthRoutes.get('/all', async (c) => {
|
|
21
23
|
const start = performance.now()
|
|
@@ -38,6 +40,7 @@ healthRoutes.get('/all', async (c) => {
|
|
|
38
40
|
{ name: 'Snowflake Query', url: `${baseUrl}/api/health/snowflake/query` },
|
|
39
41
|
{ name: 'NextBank Ping', url: `${baseUrl}/api/health/nextbank/ping` },
|
|
40
42
|
{ name: 'NextBank Auth', url: `${baseUrl}/api/health/nextbank/auth` },
|
|
43
|
+
{ name: 'AWS S3 Connect', url: `${baseUrl}/api/health/aws-s3/connect` },
|
|
41
44
|
]
|
|
42
45
|
|
|
43
46
|
// Run all checks in parallel
|
|
@@ -46,7 +49,7 @@ healthRoutes.get('/all', async (c) => {
|
|
|
46
49
|
const checkStart = performance.now()
|
|
47
50
|
try {
|
|
48
51
|
const response = await fetch(check.url, {
|
|
49
|
-
method: check.method
|
|
52
|
+
method: check.method ?? 'GET',
|
|
50
53
|
headers: {
|
|
51
54
|
'Content-Type': 'application/json',
|
|
52
55
|
// Forward auth header if present
|
|
@@ -60,7 +63,7 @@ healthRoutes.get('/all', async (c) => {
|
|
|
60
63
|
|
|
61
64
|
return {
|
|
62
65
|
name: check.name,
|
|
63
|
-
status: response.ok ? data.status
|
|
66
|
+
status: response.ok ? data.status ?? 'healthy' : 'error',
|
|
64
67
|
responseTimeMs: Math.round(performance.now() - checkStart),
|
|
65
68
|
httpStatus: response.status,
|
|
66
69
|
data,
|
|
@@ -85,12 +88,13 @@ healthRoutes.get('/all', async (c) => {
|
|
|
85
88
|
edge: results.filter((r) => r.status === 'fulfilled' && r.value.name.includes('Edge')),
|
|
86
89
|
snowflake: results.filter((r) => r.status === 'fulfilled' && r.value.name.includes('Snowflake')),
|
|
87
90
|
nextbank: results.filter((r) => r.status === 'fulfilled' && r.value.name.includes('NextBank')),
|
|
91
|
+
awsS3: results.filter((r) => r.status === 'fulfilled' && r.value.name.includes('AWS S3')),
|
|
88
92
|
}
|
|
89
93
|
|
|
90
94
|
// Determine overall status
|
|
91
95
|
const allResults = results.map((r) => (r.status === 'fulfilled' ? r.value : null))
|
|
92
96
|
const hasErrors = allResults.some((r) => r && (r.status === 'error' || r.httpStatus >= 400))
|
|
93
|
-
const allHealthy = allResults.every((r) => r
|
|
97
|
+
const allHealthy = allResults.every((r) => r?.status === 'healthy')
|
|
94
98
|
|
|
95
99
|
return c.json({
|
|
96
100
|
status: hasErrors ? 'unhealthy' : allHealthy ? 'healthy' : 'partial',
|