Skip to content

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:

  1. Environment Indicator Banner - A dismissible banner showing non-production environment warnings
  2. 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

  1. Separation of Concerns: Environment context (/api/application/info) is separate from health/version (/health/live)
  2. Real-time Health: Version dialog uses health endpoints for live status, not cached values
  3. Dual-Purpose Health Endpoints: /health/live serves both Kubernetes probes and version dialog
  4. 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

  1. Add S3 Notifier Version (Static)
  2. The S3 Notifier is a Lambda function that can't be health-checked in real-time
  3. Could display its version statically from config (already have s3NotifierVersion in config)
  4. Show as "Lambda (on-demand)" with version but no health status

  5. Error Details in Tooltip

  6. When a service is unavailable, show the actual error message in the tooltip
  7. Currently just shows "unavailable" - could show "CORS error", "Timeout", "Network error"

  8. Retry Logic with Backoff

  9. Add automatic retry with exponential backoff for failed health checks
  10. Currently a single 5-second timeout with no retry

Medium Priority

  1. WebSocket-Based Health Monitoring
  2. Instead of polling on dialog open, maintain a WebSocket connection for real-time updates
  3. Could show service going down/up in real-time while dialog is open

  4. Health Check Caching with TTL

  5. Cache health responses for a short period (e.g., 10 seconds)
  6. Reduces load on health endpoints if user rapidly opens/closes dialog

  7. Service Dependency Visualization

  8. Show which services depend on which (e.g., API depends on MongoDB, RabbitMQ)
  9. Could surface dependency health issues more clearly

  10. Version Mismatch Detection

  11. Highlight when services have different monorepo SHAs
  12. Indicates potential version skew during deployments

Low Priority

  1. Historical Health Data
  2. Show a small sparkline of recent health status
  3. Useful for identifying intermittent issues

  4. Deep Link to ArgoCD/Kubernetes

  5. For admin users, provide links to ArgoCD app status or Kubernetes dashboards
  6. Helps with quick investigation of issues

  7. Export to Support Ticket

  8. "Copy to Clipboard" already exists, but could format as a proper support ticket template
  9. Include browser info, timestamps, and suggested troubleshooting steps

Infrastructure Improvements

  1. Unified Health Aggregation Endpoint
  2. Create a single endpoint that aggregates health from all services
  3. Reduces number of CORS-enabled cross-origin requests
  4. Could be implemented as a BFF (Backend for Frontend) pattern

  5. Service Mesh Integration

  6. If using Istio/Linkerd, leverage mesh-level health data
  7. More accurate than application-level health checks