fix(tracker-web): probe platform health
Some checks failed
Publish @bytelyst/* packages / publish (push) Failing after 40s
CI — Common Platform / Build, Test & Typecheck (push) Successful in 1m22s
Size limit / size-limit (push) Failing after 1m8s

This commit is contained in:
Saravana Kumar 2026-05-30 19:26:26 +00:00
parent 325dfcae8e
commit e25969d5dc
2 changed files with 67 additions and 3 deletions

View File

@ -2,7 +2,7 @@
* Tests for GET /api/health (tracker dashboard)
*/
import { describe, it, expect, afterEach } from 'vitest';
import { describe, it, expect, afterEach, vi } from 'vitest';
import { GET } from '@/app/api/health/route';
@ -11,12 +11,17 @@ describe('GET /api/health', () => {
afterEach(() => {
process.env = { ...originalEnv };
vi.unstubAllGlobals();
});
it('returns ok when all required env vars are set', async () => {
it('returns ok when all required env vars are set and platform-service is healthy', async () => {
process.env.PLATFORM_API_URL = 'http://localhost:4003';
process.env.JWT_SECRET = 'test-secret';
process.env.DEFAULT_PRODUCT_ID = 'test-product';
vi.stubGlobal(
'fetch',
vi.fn(async () => new Response(JSON.stringify({ status: 'ok' }), { status: 200 }))
);
const res = await GET();
expect(res.status).toBe(200);
@ -30,7 +35,33 @@ describe('GET /api/health', () => {
status: 'pass',
message: '3 required vars set',
},
{
name: 'platform-service',
status: 'pass',
message: 'healthy',
},
]);
expect(fetch).toHaveBeenCalledWith('http://localhost:4003/health', expect.any(Object));
});
it('returns degraded when platform-service health check fails', async () => {
process.env.PLATFORM_API_URL = 'http://localhost:4003';
process.env.JWT_SECRET = 'test-secret';
process.env.DEFAULT_PRODUCT_ID = 'test-product';
vi.stubGlobal(
'fetch',
vi.fn(async () => new Response(JSON.stringify({ status: 'degraded' }), { status: 503 }))
);
const res = await GET();
expect(res.status).toBe(503);
const data = await res.json();
expect(data.status).toBe('degraded');
expect(data.checks).toContainEqual({
name: 'platform-service',
status: 'fail',
message: 'HTTP 503',
});
});
it('returns degraded when env vars are missing', async () => {

View File

@ -7,6 +7,7 @@ interface Check {
}
const REQUIRED_ENV = ['PLATFORM_API_URL', 'JWT_SECRET', 'DEFAULT_PRODUCT_ID'];
const PLATFORM_HEALTH_TIMEOUT_MS = 2_000;
function checkEnvVars(): Check {
const missing = REQUIRED_ENV.filter(key => !process.env[key]);
@ -16,10 +17,42 @@ function checkEnvVars(): Check {
return { name: 'env', status: 'pass', message: `${REQUIRED_ENV.length} required vars set` };
}
async function checkPlatformService(): Promise<Check> {
const baseUrl = process.env.PLATFORM_API_URL;
if (!baseUrl) {
return { name: 'platform-service', status: 'fail', message: 'PLATFORM_API_URL missing' };
}
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), PLATFORM_HEALTH_TIMEOUT_MS);
try {
const res = await fetch(new URL('/health', baseUrl).toString(), {
cache: 'no-store',
signal: controller.signal,
});
if (!res.ok) {
return { name: 'platform-service', status: 'fail', message: `HTTP ${res.status}` };
}
return { name: 'platform-service', status: 'pass', message: 'healthy' };
} catch (err) {
return {
name: 'platform-service',
status: 'fail',
message: err instanceof Error ? err.message : 'health check failed',
};
} finally {
clearTimeout(timeout);
}
}
export async function GET() {
const checks: Check[] = [];
checks.push(checkEnvVars());
const envCheck = checkEnvVars();
checks.push(envCheck);
if (envCheck.status === 'pass') {
checks.push(await checkPlatformService());
}
const overall = checks.every(c => c.status === 'pass') ? 'ok' : 'degraded';