{"id":"6983bbf8a39d033d001f2e4b","title":"2026 02 04 Issue 146","path":"how-to/committee/release-notes/2026-02-04-issue-146","contentMarkdown":"# 04-Feb-2026 — Deploy, Secrets and 4 more areas: 5 features and 1 fix [#146](https://github.com/nbarrett/ngx-ramblers/issues/146)\n\n## [build 462](https://github.com/nbarrett/ngx-ramblers/actions/runs/21689372104) — [commit dff051b](https://github.com/nbarrett/ngx-ramblers/commit/dff051b465a53e2ebad3155ca3c6bf08b9eca8de)\n\n_____\n\n- Add fly.toml to Dockerfile so it's available in deployed environments\n- Simplify fly deployment to read fly.toml directly instead of requiring fallback\n- Fix Environment type usage in env-config and env-core\n- Add FLICKR_SCRAPE_DUMP_DIR to Environment enum\n(ref: #146)\n\n### **secrets**: add database-first secrets loading for deployed servers ([#146](https://github.com/nbarrett/ngx-ramblers/issues/146))\n\nAdd loadSecretsWithFallback and loadSecretsForEnvironmentFromDatabase\nto support reading secrets from the database ENVIRONMENTS config when\nrunning on deployed servers. Falls back to file-based secrets for local\ndevelopment.\nSecrets are built from:\n- Global aws config and secrets from EnvironmentsConfig\n- Per-environment aws, mongo, and secrets from EnvironmentConfig\n- MongoDB URI is constructed from mongo config fields\n\n### **cli**: add GitHub secrets sync command for environment management ([#146](https://github.com/nbarrett/ngx-ramblers/issues/146))\n\nAdd ngx-cli github command with reconcile, sync, and push subcommands\nto manage the CONFIGS_JSON GitHub secret from the database source of truth.\nThis enables regular syncing when environments are created or modified.\n\n### **backup**: global AWS credentials, S3 path improvements, and DRY refactoring ([#146](https://github.com/nbarrett/ngx-ramblers/issues/146))\n\n## User Guide\n### Global Backup Configuration\nYou can now configure global AWS credentials in the Settings tab under 'Global AWS S3 Configuration'.\nThis allows a single set of credentials to manage backups across all environments, with per-environment\nsettings used as fallback.\n**New Settings Fields:**\n- Access Key ID\n- AWS access key with S3 permissions\n- Secret Access Key\n- Corresponding secret key\n### Backup Improvements\n- Backups are now organised by environment and timestamp in S3: `<environment>/<timestamp>/`\n- Upload progress is displayed in the History tab logs\n- Server-side logging reduced to show only meaningful operations\n### Environment Configuration\n- MongoDB URI can now be pasted directly\n- fields auto-populate from the connection string\n- All environment configs support AWS, MongoDB, and Fly.io credentials in one place\n## Technical Changes\n### S3 Path Construction\n- New `backup-paths.ts` with pure utility functions for S3 key construction\n- 22 unit tests covering path building and parsing\n- Simplified path structure: `<env>/<timestamp>` instead of `<env>/<db>/<timestamp>`\n### DRY Refactoring\n- Consolidated `uploadDirectoryToS3` from 3 duplicate implementations into `server/lib/aws/s3-utils.ts`\n- Added factory functions: `createEmptyAwsConfig()`, `createEmptyMongoConfig()`\n- `EnvironmentBackupConfig` and `BackupConfig` now type aliases for `EnvironmentConfig` and `EnvironmentsConfig`\n- Eliminated inline interface definitions in favour of model imports\n### Credential Resolution\n- `preferredCredentials()` method prioritises global AWS credentials over per-environment\n- `preferredBucket()` and `preferredRegion()` follow same pattern\n- `bucketExists()` check prevents AccessDenied errors when credentials lack CreateBucket permission\n### Code Quality\n- Removed verbose debug logging from backup controller and websocket server\n- Method naming follows project conventions (no 'get' prefix)\n- All config model types centralised in `environment-config.model.ts`\n\n### **environment-setup**: comprehensive environment management overhaul with API and MongoDB migration ([#146](https://github.com/nbarrett/ngx-ramblers/issues/146))\n\nIntroduces new environment configuration API, MongoDB cluster-based config, and enhanced UI with vendor branding and dashboard links.\n**New Environment Configuration API:**\n- RESTful endpoints for reading and writing environment configurations\n- `EnvironmentConfigService` for centralised config management\n- Separation of concerns: environment config extracted from backup/restore\n- Config initialisation from files with validation and error handling\n**MongoDB Configuration Migration:**\n- Migrate from `uri` field to `cluster` field in MongoDB configuration\n- Cluster field stores cluster name without .mongodb.net suffix\n- Database migration script (20260201000000) converts existing records\n- Backward compatible: handles both legacy URI and new cluster formats\n- Improved regex parsing for cluster extraction from URIs\n**Enhanced Environment Setup UI:**\n- Vendor logos in all configuration section headings\n- Ramblers logo dynamically loaded from System Settings\n- AWS, MongoDB, and Fly.io static brand logos\n- External link buttons for quick dashboard access:\n- AWS S3 Console (global and per-environment bucket views)\n- MongoDB Atlas dashboard\n- Fly.io app-specific dashboard\n- Deployed application URL\n- Environment list alphabetically sorted by name\n- Improved visual spacing and button styling consistency\n**Backend Architecture Improvements:**\n- New `environments-config.ts` module for config operations\n- Enhanced `config-initializer` with cluster field population\n- Updated backup/restore service to use new config service\n- CLI tools migrated to cluster-based MongoDB configuration\n- Fly.toml path resolution fixed for compiled environments\n**Technical Implementation:**\n- New `EnvironmentConfig` and `EnvironmentsConfig` models\n- Integration with SystemConfigService for dynamic Ramblers logo\n- Custom `.btn-outline-flyio` styling for brand consistency\n- Shared `sortBy()` utility for environment sorting\n- Type-safe API routes with proper error handling\n\n### **paths**: use resolveClientPath for non-vcs file access ([#146](https://github.com/nbarrett/ngx-ramblers/issues/146))\n\nFix path resolution for secrets and configs.json files when running\nin production mode where code executes from ts-gen directory.","contentHtml":"<h1>04-Feb-2026 — Deploy, Secrets and 4 more areas: 5 features and 1 fix <a href=\"https://github.com/nbarrett/ngx-ramblers/issues/146\">#146</a></h1>\n<h2><a href=\"https://github.com/nbarrett/ngx-ramblers/actions/runs/21689372104\">build 462</a> — <a href=\"https://github.com/nbarrett/ngx-ramblers/commit/dff051b465a53e2ebad3155ca3c6bf08b9eca8de\">commit dff051b</a></h2>\n<hr>\n<ul>\n<li>Add fly.toml to Dockerfile so it&#39;s available in deployed environments</li>\n<li>Simplify fly deployment to read fly.toml directly instead of requiring fallback</li>\n<li>Fix Environment type usage in env-config and env-core</li>\n<li>Add FLICKR_SCRAPE_DUMP_DIR to Environment enum\n(ref: #146)</li>\n</ul>\n<h3><strong>secrets</strong>: add database-first secrets loading for deployed servers (<a href=\"https://github.com/nbarrett/ngx-ramblers/issues/146\">#146</a>)</h3>\n<p>Add loadSecretsWithFallback and loadSecretsForEnvironmentFromDatabase\nto support reading secrets from the database ENVIRONMENTS config when\nrunning on deployed servers. Falls back to file-based secrets for local\ndevelopment.\nSecrets are built from:</p>\n<ul>\n<li>Global aws config and secrets from EnvironmentsConfig</li>\n<li>Per-environment aws, mongo, and secrets from EnvironmentConfig</li>\n<li>MongoDB URI is constructed from mongo config fields</li>\n</ul>\n<h3><strong>cli</strong>: add GitHub secrets sync command for environment management (<a href=\"https://github.com/nbarrett/ngx-ramblers/issues/146\">#146</a>)</h3>\n<p>Add ngx-cli github command with reconcile, sync, and push subcommands\nto manage the CONFIGS_JSON GitHub secret from the database source of truth.\nThis enables regular syncing when environments are created or modified.</p>\n<h3><strong>backup</strong>: global AWS credentials, S3 path improvements, and DRY refactoring (<a href=\"https://github.com/nbarrett/ngx-ramblers/issues/146\">#146</a>)</h3>\n<h2>User Guide</h2>\n<h3>Global Backup Configuration</h3>\n<p>You can now configure global AWS credentials in the Settings tab under &#39;Global AWS S3 Configuration&#39;.\nThis allows a single set of credentials to manage backups across all environments, with per-environment\nsettings used as fallback.\n<strong>New Settings Fields:</strong></p>\n<ul>\n<li>Access Key ID</li>\n<li>AWS access key with S3 permissions</li>\n<li>Secret Access Key</li>\n<li>Corresponding secret key</li>\n</ul>\n<h3>Backup Improvements</h3>\n<ul>\n<li>Backups are now organised by environment and timestamp in S3: <code>&lt;environment&gt;/&lt;timestamp&gt;/</code></li>\n<li>Upload progress is displayed in the History tab logs</li>\n<li>Server-side logging reduced to show only meaningful operations</li>\n</ul>\n<h3>Environment Configuration</h3>\n<ul>\n<li>MongoDB URI can now be pasted directly</li>\n<li>fields auto-populate from the connection string</li>\n<li>All environment configs support AWS, MongoDB, and Fly.io credentials in one place</li>\n</ul>\n<h2>Technical Changes</h2>\n<h3>S3 Path Construction</h3>\n<ul>\n<li>New <code>backup-paths.ts</code> with pure utility functions for S3 key construction</li>\n<li>22 unit tests covering path building and parsing</li>\n<li>Simplified path structure: <code>&lt;env&gt;/&lt;timestamp&gt;</code> instead of <code>&lt;env&gt;/&lt;db&gt;/&lt;timestamp&gt;</code></li>\n</ul>\n<h3>DRY Refactoring</h3>\n<ul>\n<li>Consolidated <code>uploadDirectoryToS3</code> from 3 duplicate implementations into <code>server/lib/aws/s3-utils.ts</code></li>\n<li>Added factory functions: <code>createEmptyAwsConfig()</code>, <code>createEmptyMongoConfig()</code></li>\n<li><code>EnvironmentBackupConfig</code> and <code>BackupConfig</code> now type aliases for <code>EnvironmentConfig</code> and <code>EnvironmentsConfig</code></li>\n<li>Eliminated inline interface definitions in favour of model imports</li>\n</ul>\n<h3>Credential Resolution</h3>\n<ul>\n<li><code>preferredCredentials()</code> method prioritises global AWS credentials over per-environment</li>\n<li><code>preferredBucket()</code> and <code>preferredRegion()</code> follow same pattern</li>\n<li><code>bucketExists()</code> check prevents AccessDenied errors when credentials lack CreateBucket permission</li>\n</ul>\n<h3>Code Quality</h3>\n<ul>\n<li>Removed verbose debug logging from backup controller and websocket server</li>\n<li>Method naming follows project conventions (no &#39;get&#39; prefix)</li>\n<li>All config model types centralised in <code>environment-config.model.ts</code></li>\n</ul>\n<h3><strong>environment-setup</strong>: comprehensive environment management overhaul with API and MongoDB migration (<a href=\"https://github.com/nbarrett/ngx-ramblers/issues/146\">#146</a>)</h3>\n<p>Introduces new environment configuration API, MongoDB cluster-based config, and enhanced UI with vendor branding and dashboard links.\n<strong>New Environment Configuration API:</strong></p>\n<ul>\n<li>RESTful endpoints for reading and writing environment configurations</li>\n<li><code>EnvironmentConfigService</code> for centralised config management</li>\n<li>Separation of concerns: environment config extracted from backup/restore</li>\n<li>Config initialisation from files with validation and error handling\n<strong>MongoDB Configuration Migration:</strong></li>\n<li>Migrate from <code>uri</code> field to <code>cluster</code> field in MongoDB configuration</li>\n<li>Cluster field stores cluster name without .mongodb.net suffix</li>\n<li>Database migration script (20260201000000) converts existing records</li>\n<li>Backward compatible: handles both legacy URI and new cluster formats</li>\n<li>Improved regex parsing for cluster extraction from URIs\n<strong>Enhanced Environment Setup UI:</strong></li>\n<li>Vendor logos in all configuration section headings</li>\n<li>Ramblers logo dynamically loaded from System Settings</li>\n<li>AWS, MongoDB, and Fly.io static brand logos</li>\n<li>External link buttons for quick dashboard access:</li>\n<li>AWS S3 Console (global and per-environment bucket views)</li>\n<li>MongoDB Atlas dashboard</li>\n<li>Fly.io app-specific dashboard</li>\n<li>Deployed application URL</li>\n<li>Environment list alphabetically sorted by name</li>\n<li>Improved visual spacing and button styling consistency\n<strong>Backend Architecture Improvements:</strong></li>\n<li>New <code>environments-config.ts</code> module for config operations</li>\n<li>Enhanced <code>config-initializer</code> with cluster field population</li>\n<li>Updated backup/restore service to use new config service</li>\n<li>CLI tools migrated to cluster-based MongoDB configuration</li>\n<li>Fly.toml path resolution fixed for compiled environments\n<strong>Technical Implementation:</strong></li>\n<li>New <code>EnvironmentConfig</code> and <code>EnvironmentsConfig</code> models</li>\n<li>Integration with SystemConfigService for dynamic Ramblers logo</li>\n<li>Custom <code>.btn-outline-flyio</code> styling for brand consistency</li>\n<li>Shared <code>sortBy()</code> utility for environment sorting</li>\n<li>Type-safe API routes with proper error handling</li>\n</ul>\n<h3><strong>paths</strong>: use resolveClientPath for non-vcs file access (<a href=\"https://github.com/nbarrett/ngx-ramblers/issues/146\">#146</a>)</h3>\n<p>Fix path resolution for secrets and configs.json files when running\nin production mode where code executes from ts-gen directory.</p>\n"}