Architecture Overview - bcgov/eagle-dev-guides GitHub Wiki
This document describes the Eagle system architecture, component interactions, and request flow.
flowchart TB
subgraph Users[" "]
direction LR
User["👤 Public User"]
Staff["👔 EAO Staff"]
end
subgraph OpenShift["OpenShift Cluster"]
Route["🌐 OpenShift Route<br/>projects.eao.gov.bc.ca"]
subgraph Proxy["Reverse Proxy"]
RProxy["eao-nginx"]
end
subgraph Apps["Application Layer"]
direction LR
Public["eagle-public<br/>Angular SPA"]
Admin["eagle-admin<br/>Angular SPA"]
API["eagle-api<br/>Node.js"]
end
subgraph Analytics["Analytics"]
direction LR
Collector["penguin-analytics<br/>Event Collector"]
Metabase["Metabase<br/>Dashboards"]
end
subgraph Data["Data Layer"]
direction LR
MongoDB[("MongoDB")]
TimescaleDB[("TimescaleDB")]
Typesense[("Typesense")]
end
end
subgraph External["External Services"]
Keycloak["🔐 BC Gov Keycloak<br/>loginproxy.gov.bc.ca"]
end
User --> Route
Staff --> Route
Route --> RProxy
RProxy -->|"/"|Public
RProxy -->|"/admin/"|Admin
RProxy -->|"/api/"|API
RProxy -->|"/analytics"|Collector
Public & Admin -.->|config|API
Public & Admin -.->|events|Collector
Staff -.->|OIDC login|Keycloak
Admin & API -.->|token validation|Keycloak
API --> MongoDB
API -->|sync| Typesense
Public -.->|search| Typesense
Collector --> TimescaleDB
Metabase --> TimescaleDB
The reverse proxy (rproxy service) routes all incoming requests from projects.eao.gov.bc.ca to appropriate backend services based on URL path:
| Path | Service | Description |
|---|---|---|
/ |
eagle-public | Public-facing website |
/admin/ |
eagle-admin | Staff administration portal |
/api/ |
eagle-api | REST API endpoints |
/analytics |
penguin-analytics | Event tracking API |
Repository: bcgov/eao-nginx
Key Configuration (conf.d/server.conf.tmpl):
- Environment variables for upstream service URLs
- Response caching via
proxy_cache globalcache - HTTP header passthrough for authentication tokens
- Technology: Angular 21 with nginx
- Node Version: Node.js 24.x
- Purpose: Public-facing interface for viewing environmental assessments
-
Config Pattern: Fetches runtime configuration from
/api/public/config - Features: Project search, document viewing, comment submission
- Technology: Angular 21 with nginx
- Node Version: Node.js 22.x
- Purpose: Staff portal for managing projects and documents
-
Config Pattern: Fetches runtime configuration from
/api/config - Features: Project management, document uploads, user administration
- Technology: Node.js with Express
- Node Version: Node.js 22.x
- Purpose: REST API backend for all data operations
- Database: MongoDB for document storage
-
Key Endpoints:
-
GET /api/public/config- Public app configuration -
GET /api/config- Admin app configuration -
GET /api/project- Project data -
GET /api/document- Document management
-
-
Search: Typesense powers full-text project search.
typesense-sync(CronJob + change-stream Deployment) keeps the index in sync with MongoDB.
- Technology: Node.js Express
- Purpose: Event collection and storage for usage analytics
- Database: TimescaleDB (time-series PostgreSQL)
-
Key Endpoints:
-
POST /analytics- Single event ingestion -
POST /analytics/batch- Batch event ingestion (up to 100) -
GET /health- Health check
-
- Dashboards: Metabase instance for visualization
External authentication service provided by BC Government Common Services:
| Environment | URL |
|---|---|
| Dev/Test | https://dev.loginproxy.gov.bc.ca/auth |
| Prod | https://loginproxy.gov.bc.ca/auth |
-
Realm:
eao-epic -
Client ID (Admin):
eagle-admin-console -
Client ID (API):
eagle-api-console - Protocol: OpenID Connect (OIDC)
sequenceDiagram
participant User
participant Route as OpenShift Route
participant RProxy as eao-nginx
participant Public as eagle-public
participant API as eagle-api
participant DB as MongoDB
User->>Route: GET projects.eao.gov.bc.ca/p/project-123
Route->>RProxy: Forward (TLS terminated)
RProxy->>Public: GET /p/project-123
Public->>User: Return Angular SPA
Note over User,Public: Browser loads Angular app
User->>Route: GET /api/public/config
Route->>RProxy: Forward
RProxy->>API: GET /api/public/config
API->>User: Return app configuration
User->>Route: GET /api/public/project/project-123
Route->>RProxy: Forward
RProxy->>API: GET /api/public/project/project-123
API->>DB: Query project
DB->>API: Project data
API->>User: Return project JSON
Both Angular applications use a runtime configuration pattern to avoid rebuilding containers for configuration changes:
flowchart LR
subgraph Build["Build Time"]
Code[Source Code] --> Build1[yarn build]
Build1 --> Artifact[Static Files]
Artifact --> Image[Container Image]
end
subgraph Runtime["Runtime"]
Image --> Container[Running Container]
Container --> Nginx[nginx serves SPA]
Nginx --> Browser[Browser loads app]
Browser --> Config[Fetch /api/config]
Config --> API[eagle-api]
API --> App[App configured]
end
-
Dockerfile sets
configEndpoint = trueinenv.js - Browser loads Angular application
- App fetches configuration from API endpoint
- API returns environment-specific configuration (URLs, feature flags, etc.)
- App applies configuration and renders
| Namespace | Purpose | Contains |
|---|---|---|
6cdc9e-tools |
Shared tooling | Image registry, build artifacts |
6cdc9e-dev |
Development | All services (dev tag) |
6cdc9e-test |
Testing/UAT | All services (test tag) |
6cdc9e-prod |
Production | All services (prod tag) |
| Tag | Purpose | Mutable |
|---|---|---|
dev |
Latest development build | Yes |
ci-latest |
Latest CI-verified build | Yes |
test |
Currently deployed to test | Yes |
prod |
Currently deployed to prod | Yes |
v1.2.3 |
Specific release version | No |
abc1234 |
Git commit SHA | No |
- TLS Termination: Handled at OpenShift Route level
- Authentication: Keycloak/IDIR for admin users
- API Security: JWT tokens for authenticated endpoints
- Container Scanning: Trivy scans for CRITICAL/HIGH vulnerabilities
- Network Policies: Namespace isolation (if configured)
- Deployment Pipeline - How code gets deployed
- Helm Charts - Kubernetes configuration details
- Local Development - Setting up locally