11import { z } from 'zod' ;
22
3+ // UUID-like pattern (less strict than RFC 4122)
4+ const uuidLike = z . string ( ) . regex ( / ^ [ 0 - 9 a - f A - F ] { 8 } - [ 0 - 9 a - f A - F ] { 4 } - [ 0 - 9 a - f A - F ] { 4 } - [ 0 - 9 a - f A - F ] { 4 } - [ 0 - 9 a - f A - F ] { 12 } $ / , 'Invalid UUID format' ) ;
5+
36// Environment schema
47const EnvironmentSchema = z . enum ( [ 'development' , 'staging' , 'production' , 'test' ] ) ;
58
@@ -11,15 +14,6 @@ const ConfigSchema = z.object({
1114 // Server
1215 port : z . coerce . number ( ) . int ( ) . positive ( ) . default ( 7000 ) ,
1316
14- // Database (Postgres)
15- database : z . object ( {
16- host : z . string ( ) . default ( 'localhost' ) ,
17- port : z . coerce . number ( ) . int ( ) . positive ( ) . default ( 5432 ) ,
18- user : z . string ( ) . default ( 'postgres' ) ,
19- password : z . string ( ) . default ( 'password' ) ,
20- name : z . string ( ) . default ( 'openworkers' )
21- } ) ,
22-
2317 // JWT
2418 jwt : z . object ( {
2519 access : z . object ( {
@@ -36,6 +30,16 @@ const ConfigSchema = z.object({
3630 github : z . object ( {
3731 clientId : z . string ( ) . optional ( ) ,
3832 clientSecret : z . string ( ) . optional ( )
33+ } ) ,
34+
35+ // Postgate (SQL proxy)
36+ postgate : z . object ( {
37+ url : z . string ( ) . url ( ) . default ( 'http://localhost:6080' ) ,
38+ // Admin database (tenant management functions) - mode schema on public
39+ adminDatabaseId : uuidLike . default ( '00000000-0000-0000-0000-000000000000' ) ,
40+ // OpenWorkers database (API data) - mode dedicated
41+ openworkersDatabaseId : uuidLike ,
42+ jwtSecret : z . string ( ) . min ( 32 , 'POSTGATE_JWT_SECRET must be at least 32 characters' )
3943 } )
4044} ) ;
4145
@@ -48,13 +52,6 @@ function loadConfig(): Config {
4852 const rawConfig = {
4953 nodeEnv : process . env . NODE_ENV ,
5054 port : process . env . PORT ,
51- database : {
52- host : process . env . POSTGRES_HOST ,
53- port : process . env . POSTGRES_PORT ,
54- user : process . env . POSTGRES_USER ,
55- password : process . env . POSTGRES_PASSWORD ,
56- name : process . env . POSTGRES_DB
57- } ,
5855 jwt : {
5956 access : {
6057 secret : process . env . JWT_ACCESS_SECRET ,
@@ -68,33 +65,34 @@ function loadConfig(): Config {
6865 github : {
6966 clientId : process . env . GITHUB_CLIENT_ID ,
7067 clientSecret : process . env . GITHUB_CLIENT_SECRET
68+ } ,
69+ postgate : {
70+ url : process . env . POSTGATE_URL ,
71+ adminDatabaseId : process . env . POSTGATE_ADMIN_DATABASE_ID ,
72+ openworkersDatabaseId : process . env . POSTGATE_OPENWORKERS_DATABASE_ID ,
73+ jwtSecret : process . env . POSTGATE_JWT_SECRET
7174 }
7275 } ;
7376
7477 try {
7578 const config = ConfigSchema . parse ( rawConfig ) ;
7679
77- // Sanity check: test database should end with "test"
78- if ( config . nodeEnv === 'test' && ! config . database . name . endsWith ( 'test' ) ) {
79- throw new Error ( `Database name should end with "test" in test mode, got "${ config . database . name } "` ) ;
80- }
81-
8280 // Log configuration status
8381 if ( config . nodeEnv === 'development' ) {
84- console . log ( '🔧 Running in DEVELOPMENT mode' ) ;
82+ console . log ( 'Running in DEVELOPMENT mode' ) ;
8583 } else if ( config . nodeEnv === 'production' ) {
86- console . log ( '🚀 Running in PRODUCTION mode' ) ;
84+ console . log ( 'Running in PRODUCTION mode' ) ;
8785 }
8886
8987 // Warn about missing GitHub OAuth
9088 if ( ! config . github . clientId || ! config . github . clientSecret ) {
91- console . warn ( '⚠️ GitHub OAuth not configured (GITHUB_CLIENT_ID/GITHUB_CLIENT_SECRET missing)' ) ;
89+ console . warn ( 'GitHub OAuth not configured (GITHUB_CLIENT_ID/GITHUB_CLIENT_SECRET missing)' ) ;
9290 }
9391
9492 return config ;
9593 } catch ( error ) {
9694 if ( error instanceof z . ZodError ) {
97- console . error ( '❌ Configuration validation failed:' ) ;
95+ console . error ( 'Configuration validation failed:' ) ;
9896 error . issues . forEach ( ( err ) => {
9997 console . error ( ` - ${ err . path . join ( '.' ) } : ${ err . message } ` ) ;
10098 } ) ;
@@ -104,8 +102,10 @@ function loadConfig(): Config {
104102 }
105103}
106104
105+ console . log ( 'Loading configuration...' , process . env . POSTGATE_OPENWORKERS_DATABASE_ID ) ;
106+
107107// Export singleton config instance
108108export const config = loadConfig ( ) ;
109109
110110// Export individual sections for convenience
111- export const { nodeEnv, port, database , jwt, github } = config ;
111+ export const { nodeEnv, port, jwt, github, postgate } = config ;
0 commit comments