@@ -7,34 +7,17 @@ import { EMBEDDED_TFSTATE } from '../generated/tfstate.js';
77
88const __dirname = dirname ( fileURLToPath ( import . meta. url ) ) ;
99
10- /**
11- * Probes candidate relative paths from __dirname in order and returns the
12- * first that exists on disk. Falls back to the first candidate when none
13- * exist so callers get a deterministic (missing-file) path rather than
14- * undefined behaviour.
15- *
16- * Needed because the depth from __dirname to the repo/workspace root differs
17- * between environments:
18- * - local source tree (src/services or dist/services inside repo): 5 levels up → repo root
19- * - Docker image (dist/services inside /app): 4 levels up → /app
20- */
21- function resolveRuntimePath ( ...relativeCandidates : string [ ] ) : string {
22- for ( const rel of relativeCandidates ) {
23- const resolved = join ( __dirname , rel ) ;
24- if ( existsSync ( resolved ) ) return resolved ;
25- }
26- return join ( __dirname , relativeCandidates [ 0 ] ) ;
27- }
10+ // dist/services/ → 4 hops up = app root (repo: app/, Docker: /workspace/app/)
11+ // 5 hops up = repo/workspace root, where terraform/ lives
12+ const APP_ROOT = join ( __dirname , '..' , '..' , '..' , '..' ) ;
13+
14+ const TF_STATE_PATH =
15+ process . env [ 'TF_STATE_PATH' ] ??
16+ join ( APP_ROOT , '..' , 'terraform' , 'terraform.tfstate' ) ;
2817
29- const TF_STATE_PATH = process . env [ 'TF_STATE_PATH' ] ??
30- resolveRuntimePath (
31- '../../../../../terraform/terraform.tfstate' ,
32- '../../../../terraform/terraform.tfstate' ,
33- ) ;
34- const CONFIG_PATH = resolveRuntimePath (
35- '../../../../../app/server_config.json' ,
36- '../../../../server_config.json' ,
37- ) ;
18+ const SERVER_CONFIG_PATH =
19+ process . env [ 'SERVER_CONFIG_PATH' ] ??
20+ join ( APP_ROOT , 'server_config.json' ) ;
3821
3922/**
4023 * Shape of the subset of Terraform root outputs the management app consumes.
@@ -83,7 +66,8 @@ const DEFAULT_CONFIG: WatchdogConfig = {
8366 * lazily and cached in-memory until {@link ConfigService.invalidateCache}
8467 * is called.
8568 * - `server_config.json` — the user-editable file holding the watchdog
86- * tunables and the optional API bearer token.
69+ * tunables and the optional API bearer token. Path resolved via
70+ * `SERVER_CONFIG_PATH` env var, defaulting to `<app-root>/server_config.json`.
8771 * - A handful of process env vars (`AWS_DEFAULT_REGION`, `API_TOKEN`).
8872 *
8973 * Every other service injects this one instead of touching `process.env` or
@@ -197,9 +181,9 @@ export class ConfigService {
197181 if ( env !== undefined ) {
198182 return env . length > 0 ? env : null ;
199183 }
200- if ( ! existsSync ( CONFIG_PATH ) ) return null ;
184+ if ( ! existsSync ( SERVER_CONFIG_PATH ) ) return null ;
201185 try {
202- const raw = JSON . parse ( readFileSync ( CONFIG_PATH , 'utf-8' ) ) as { api_token ?: unknown } ;
186+ const raw = JSON . parse ( readFileSync ( SERVER_CONFIG_PATH , 'utf-8' ) ) as { api_token ?: unknown } ;
203187 return typeof raw . api_token === 'string' && raw . api_token . length > 0 ? raw . api_token : null ;
204188 } catch ( err ) {
205189 logger . warn ( 'Could not read api_token from config file' , { err } ) ;
@@ -226,9 +210,9 @@ export class ConfigService {
226210 * fresh object on every call — safe for callers to mutate.
227211 */
228212 getConfig ( ) : WatchdogConfig {
229- if ( ! existsSync ( CONFIG_PATH ) ) return { ...DEFAULT_CONFIG } ;
213+ if ( ! existsSync ( SERVER_CONFIG_PATH ) ) return { ...DEFAULT_CONFIG } ;
230214 try {
231- const saved = JSON . parse ( readFileSync ( CONFIG_PATH , 'utf-8' ) ) as Partial < WatchdogConfig > ;
215+ const saved = JSON . parse ( readFileSync ( SERVER_CONFIG_PATH , 'utf-8' ) ) as Partial < WatchdogConfig > ;
232216 return { ...DEFAULT_CONFIG , ...saved } ;
233217 } catch ( err ) {
234218 logger . warn ( 'Could not read config file, using defaults' , { err } ) ;
@@ -242,7 +226,7 @@ export class ConfigService {
242226 * save here is not effective until the next `terraform apply`.
243227 */
244228 saveConfig ( config : WatchdogConfig ) : void {
245- writeFileSync ( CONFIG_PATH , JSON . stringify ( config , null , 2 ) ) ;
229+ writeFileSync ( SERVER_CONFIG_PATH , JSON . stringify ( config , null , 2 ) ) ;
246230 logger . info ( 'Config saved' , config ) ;
247231 }
248232}
0 commit comments