Version Info Dialog & Environment Indicator¶
This document describes the architecture and implementation of the version information dialog and environment indicator features in the SyRF web application.
Overview¶
The SyRF web application provides two related features for environment awareness:
- Environment Indicator Banner - A dismissible banner showing non-production environment warnings
- Version Info Dialog - A dialog showing version and health status of all services
These features help users and developers:
- Identify which environment they're working in (Production, Staging, Preview, Development)
- See real-time health status of backend services
- Access version information for debugging and support requests
Architecture¶
Data Flow¶
┌─────────────────────────────────────────────────────────────────────┐
│ Web Application │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────┐ ┌──────────────────────────────────┐ │
│ │ Environment Indicator │ │ Version Info Dialog │ │
│ │ (Banner) │ │ │ │
│ └──────────┬───────────┘ └────────────────┬─────────────────┘ │
│ │ │ │
│ │ On app init │ On dialog open │
│ ▼ ▼ │
│ ┌──────────────────────┐ ┌──────────────────────────────────┐ │
│ │EnvironmentInfoService│ │ Parallel HTTP calls to: │ │
│ │ │ │ - API /health/live │ │
│ │ Calls API once to │ │ - PM /health/live │ │
│ │ get environment info │ │ - Quartz /health/live │ │
│ └──────────┬───────────┘ └────────────────┬─────────────────┘ │
│ │ │ │
└─────────────┼───────────────────────────────────┼────────────────────┘
│ │
▼ ▼
┌─────────────────────────┐ ┌──────────────────────────────────────┐
│ API Service │ │ All Backend Services │
│ /api/application/info │ │ /health/live │
│ │ │ │
│ Returns: │ │ Returns: │
│ - environment │ │ - status (Healthy/Unhealthy) │
│ - databaseName │ │ - version │
│ - prNumber │ │ - gitVersion │
│ - isProduction │ │ - gitSha │
│ - apiVersion │ │ │
└─────────────────────────┘ └──────────────────────────────────────┘
Key Design Decisions¶
- Separation of Concerns: Environment context (
/api/application/info) is separate from health/version (/health/live) - Real-time Health: Version dialog uses health endpoints for live status, not cached values
- Dual-Purpose Health Endpoints:
/health/liveserves both Kubernetes probes and version dialog - Fallback URL Derivation: Preview environments derive service URLs from API origin if not explicitly configured
Endpoints¶
/api/application/info (API and PM services)¶
Purpose: Provides environment context for the environment indicator banner.
Response:
{
"environment": "Preview",
"databaseName": "syrf_pr_2246",
"prNumber": "2246",
"isProduction": false,
"apiVersion": "9.22.0",
"apiFullVersion": "9.22.0-PullRequest2246.15",
"monorepoSha": "dc386ada"
}
Used by: EnvironmentInfoService on app initialization.
/health/live (All services: API, PM, Quartz)¶
Purpose: Kubernetes liveness probe AND version information for UI.
Response:
{
"status": "Healthy",
"version": "9.22.0",
"gitVersion": "9.22.0-PullRequest2246.15",
"gitSha": "dc386ada",
"gitInformationalVersion": "9.22.0-PullRequest2246.15+Branch.pull-2246-merge.Sha.dc386ada"
}
Used by: Version Info Dialog for real-time health and version status.
Implementation: See SyrfHealthCheckExtensions.cs and VersionHealthCheck.cs in SyRF.WebHostConfig.Common.
Configuration¶
Service Origin Configuration¶
The version dialog needs to know the URLs for each backend service. These are configured via Helm values and injected as environment variables.
| Config Key | Helm Path | Environment Variable | Description |
|---|---|---|---|
apiOrigin |
api.origin |
SYRF__ApiOrigin |
API service base URL |
pmOrigin |
pm.origin |
SYRF__PmOrigin |
PM service base URL |
quartzOrigin |
quartz.origin |
SYRF__QuartzOrigin |
Quartz service base URL |
Preview Environment URL Derivation¶
For preview environments, if service origins aren't explicitly configured, the version dialog derives them from apiOrigin:
// In version-info-dialog.component.ts
const isPreview = this.config.runtimeEnvironment.toLowerCase() === 'preview';
const pmOrigin = this.config.pmOrigin ||
(isPreview && apiOrigin ? apiOrigin.replace('://api.', '://project-management.') : null);
const quartzOrigin = this.config.quartzOrigin ||
(isPreview && apiOrigin ? apiOrigin.replace('://api.', '://quartz.') : null);
This allows the dialog to work even before the ApplicationSet fully propagates origin configs.
CORS Requirements¶
Backend services must allow CORS from the web application for the health endpoints to be accessible:
// In each service's Program.cs
var uiUrl = context.Configuration.GetValue<string>("AppSettingsConfig:UiUrl") ?? "";
registry.AddCors(options =>
{
options.AddPolicy(corsPolicyName, builder =>
builder
.WithOrigins(uiUrl, "https://localhost:4200", ...)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);
});
// In middleware pipeline
app.UseCors(corsPolicyName);
Component Reference¶
Web Application¶
| Component | Location | Purpose |
|---|---|---|
VersionInfoDialogComponent |
src/app/shared/dialogs/version-info-dialog/ |
Main dialog component |
EnvironmentInfoService |
src/app/core/services/environment-info/ |
Fetches and caches environment info |
EnvironmentBannerComponent |
src/app/shared/components/environment-banner/ |
Dismissible warning banner |
Backend Services¶
| Component | Location | Purpose |
|---|---|---|
VersionHealthCheck |
SyRF.WebHostConfig.Common/HealthChecks/ |
Health check that includes version data |
SyrfHealthCheckExtensions |
SyRF.WebHostConfig.Common/Extensions/ |
Maps /health/live with version response |
ApplicationController |
Each service's Controllers folder | Provides /api/application/info |
Status Indicators¶
The version dialog uses the following status indicators:
| Status | Icon | Color | Meaning |
|---|---|---|---|
healthy |
check_circle |
Green (#4caf50) | Service is responding and healthy |
unhealthy |
error |
Red (#f44336) | Service responded but reported unhealthy |
unavailable |
help_outline |
Gray (#9e9e9e) | Service didn't respond (timeout/error) |
loading |
Spinner | Orange (#ff9800) | Request in progress |
Suggested Improvements¶
High Priority¶
- Add S3 Notifier Version (Static)
- The S3 Notifier is a Lambda function that can't be health-checked in real-time
- Could display its version statically from config (already have
s3NotifierVersionin config) -
Show as "Lambda (on-demand)" with version but no health status
-
Error Details in Tooltip
- When a service is unavailable, show the actual error message in the tooltip
-
Currently just shows "unavailable" - could show "CORS error", "Timeout", "Network error"
-
Retry Logic with Backoff
- Add automatic retry with exponential backoff for failed health checks
- Currently a single 5-second timeout with no retry
Medium Priority¶
- WebSocket-Based Health Monitoring
- Instead of polling on dialog open, maintain a WebSocket connection for real-time updates
-
Could show service going down/up in real-time while dialog is open
-
Health Check Caching with TTL
- Cache health responses for a short period (e.g., 10 seconds)
-
Reduces load on health endpoints if user rapidly opens/closes dialog
-
Service Dependency Visualization
- Show which services depend on which (e.g., API depends on MongoDB, RabbitMQ)
-
Could surface dependency health issues more clearly
-
Version Mismatch Detection
- Highlight when services have different monorepo SHAs
- Indicates potential version skew during deployments
Low Priority¶
- Historical Health Data
- Show a small sparkline of recent health status
-
Useful for identifying intermittent issues
-
Deep Link to ArgoCD/Kubernetes
- For admin users, provide links to ArgoCD app status or Kubernetes dashboards
-
Helps with quick investigation of issues
-
Export to Support Ticket
- "Copy to Clipboard" already exists, but could format as a proper support ticket template
- Include browser info, timestamps, and suggested troubleshooting steps
Infrastructure Improvements¶
- Unified Health Aggregation Endpoint
- Create a single endpoint that aggregates health from all services
- Reduces number of CORS-enabled cross-origin requests
-
Could be implemented as a BFF (Backend for Frontend) pattern
-
Service Mesh Integration
- If using Istio/Linkerd, leverage mesh-level health data
- More accurate than application-level health checks