| name | openevidence-multi-env-setup |
| description | Configure OpenEvidence across development, staging, and production environments.
Use when setting up multiple environments, managing environment-specific configurations,
or implementing environment promotion strategies for clinical AI applications.
Trigger with phrases like "openevidence environments", "openevidence staging",
"openevidence dev setup", "multi-environment openevidence".
|
| allowed-tools | Read, Write, Edit |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
OpenEvidence Multi-Environment Setup
Overview
Configure and manage OpenEvidence integrations across development, staging, and production environments with proper isolation and promotion strategies.
Prerequisites
- OpenEvidence accounts for each environment
- Separate API keys per environment
- Infrastructure for each environment (cloud or on-premise)
- CI/CD pipeline configured
Environment Strategy
| Environment | API Endpoint | Purpose | Data |
|---|
| Development | sandbox.openevidence.com | Local development | Synthetic |
| Staging | sandbox.openevidence.com | Integration testing | Synthetic |
| Production | api.openevidence.com | Live clinical use | Real (PHI) |
Instructions
Step 1: Environment Configuration Files
export const developmentConfig = {
env: 'development',
openevidence: {
baseUrl: 'https://api.sandbox.openevidence.com',
timeout: 60000,
retries: 1,
rateLimit: {
enabled: false,
},
},
cache: {
enabled: false,
ttlSeconds: 0,
},
logging: {
level: 'debug',
prettyPrint: true,
},
features: {
deepConsult: true,
webhooks: false,
auditLogging: false,
},
};
export const stagingConfig = {
env: 'staging',
openevidence: {
baseUrl: 'https://api.sandbox.openevidence.com',
timeout: 45000,
retries: 2,
rateLimit: {
enabled: true,
: ,
},
},
: {
: ,
: ,
},
: {
: ,
: ,
},
: {
: ,
: ,
: ,
},
};
productionConfig = {
: ,
: {
: ,
: ,
: ,
: {
: ,
: ,
},
},
: {
: ,
: ,
},
: {
: ,
: ,
},
: {
: ,
: ,
: ,
},
};
Step 2: Configuration Loader
import { developmentConfig } from './environments/development';
import { stagingConfig } from './environments/staging';
import { productionConfig } from './environments/production';
type Environment = 'development' | 'staging' | 'production';
const configs = {
development: developmentConfig,
staging: stagingConfig,
production: productionConfig,
};
export function loadConfig(env?: Environment) {
const environment = env || (process.env.NODE_ENV as Environment) || 'development';
if (!configs[environment]) {
throw new Error(`Unknown environment: ${environment}`);
}
const baseConfig = configs[environment];
return {
...baseConfig,
openevidence: {
...baseConfig.openevidence,
apiKey: process.env.OPENEVIDENCE_API_KEY,
orgId: process.env.OPENEVIDENCE_ORG_ID,
...(process.. && {
: process..,
}),
...(process.. && {
: (process..),
}),
},
};
}
: < loadConfig> | = ;
() {
(!configInstance) {
configInstance = ();
}
configInstance;
}
() {
configInstance = ;
}
Step 3: Environment-Aware Client Factory
import { OpenEvidenceClient } from '@openevidence/sdk';
import { getConfig } from '../config';
import { ClinicalQueryCache } from './cache';
import { MetricsCollector } from '../monitoring/metrics';
export class OpenEvidenceClientFactory {
private static instances: Map<string, OpenEvidenceClient> = new Map();
static getClient(environment?: string): OpenEvidenceClient {
const config = getConfig();
const env = environment || config.env;
if (!this.instances.has(env)) {
const client = new OpenEvidenceClient({
apiKey: config.openevidence.apiKey,
orgId: config.openevidence.orgId,
baseUrl: config..,
: config..,
});
..(env, client);
}
..(env)!;
}
(: , : ): {
..(env, client);
}
(): {
..();
}
}
Step 4: Secret Management Per Environment
import { SecretManagerServiceClient } from '@google-cloud/secret-manager';
interface SecretPaths {
apiKey: string;
orgId: string;
webhookSecret?: string;
}
const SECRET_PATHS: Record<string, SecretPaths> = {
development: {
apiKey: 'local',
orgId: 'local',
},
staging: {
apiKey: 'projects/staging-project/secrets/openevidence-api-key/versions/latest',
orgId: 'projects/staging-project/secrets/openevidence-org-id/versions/latest',
webhookSecret: 'projects/staging-project/secrets/openevidence-webhook-secret/versions/latest',
},
production: {
apiKey: 'projects/prod-project/secrets/openevidence-api-key/versions/latest',
orgId: 'projects/prod-project/secrets/openevidence-org-id/versions/latest',
webhookSecret: 'projects/prod-project/secrets/openevidence-webhook-secret/versions/latest',
},
};
export class SecretManager {
private client: SecretManagerServiceClient;
constructor() {
. = ();
}
(: ): <{
: ;
: ;
?: ;
}> {
paths = [env];
(!paths) {
();
}
(paths. === ) {
{
: process..!,
: process..!,
: process..,
};
}
[apiKeyVersion] = ..({ : paths. });
[orgIdVersion] = ..({ : paths. });
: = {
: apiKeyVersion.?.?.(),
: orgIdVersion.?.?.(),
};
(paths.) {
[webhookVersion] = ..({ : paths. });
secrets. = webhookVersion.?.?.();
}
secrets;
}
}
Step 5: Environment Promotion Workflow
name: Environment Promotion
on:
workflow_dispatch:
inputs:
source_env:
description: 'Source environment'
required: true
type: choice
options:
- staging
target_env:
description: 'Target environment'
required: true
type: choice
options:
- production
version:
description: 'Version to promote (e.g., v1.2.3)'
required: true
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate version exists in source
run: |
# Check that the version exists and is deployed in source
SOURCE_VERSION=$(curl -sf "${{ secrets.STAGING_URL }}/health" | jq -r '.version')
if [ "$SOURCE_VERSION" != "${{ inputs.version }}" ]; then
echo "Version mismatch: staging has $SOURCE_VERSION, expected ${{ inputs.version }}"
exit 1
fi
Step 6: Environment Health Checks
import { OpenEvidenceClientFactory } from '../openevidence/client-factory';
import { getConfig } from '../config';
interface EnvironmentHealth {
environment: string;
status: 'healthy' | 'degraded' | 'unhealthy';
checks: {
openevidence: { status: string; latencyMs?: number };
cache: { status: string; hitRate?: number };
database: { status: string };
};
version: string;
timestamp: string;
}
export async function checkEnvironmentHealth(): Promise<EnvironmentHealth> {
const config = getConfig();
const checks: EnvironmentHealth['checks'] = {
openevidence: { status: 'unknown' },
cache: { status: },
: { : },
};
{
client = .();
start = .();
client..();
checks. = {
: ,
: .() - start,
};
} (: ) {
checks. = { : };
}
{
(config..) {
stats = cache.();
checks. = {
: ,
: stats.,
};
} {
checks. = { : };
}
} {
checks. = { : };
}
{
db.;
checks. = { : };
} {
checks. = { : };
}
unhealthyCount = .(checks).(
c. ===
).;
: [] = ;
(unhealthyCount > ) status = ;
(checks.. === ) status = ;
{
: config.,
status,
checks,
: process.. || ,
: ().(),
};
}
Output
- Environment-specific configuration files
- Configuration loader with env var overrides
- Secret management per environment
- Promotion workflow
- Health checks per environment
Environment Checklist
Development
Staging
Production
Error Handling
| Environment Issue | Detection | Resolution |
|---|
| Wrong API endpoint | Health check fails | Verify baseUrl in config |
| Secret not found | Startup failure | Check Secret Manager permissions |
| Config mismatch | Unexpected behavior | Validate config loading |
| Promotion failure | CI/CD error | Check version tagging |
Resources
Next Steps
For observability setup, see openevidence-observability.