diff --git a/Dockerfile b/Dockerfile index f8b453e..8edc502 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,6 +12,10 @@ WORKDIR /app ENV NODE_ENV=production ENV HOSTNAME=0.0.0.0 ENV PORT=3001 +# ARGs don't cross stage boundaries; redeclare so /health reads real provenance at runtime. +ARG COMMIT_SHA="" BUILD_TIME="" +ENV COMMIT_SHA=${COMMIT_SHA} +ENV BUILD_TIME=${BUILD_TIME} COPY --from=builder /app/public ./public COPY --from=builder /app/.next/standalone ./ diff --git a/docker-compose.yml b/docker-compose.yml index ee1d6c8..55f65ad 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -51,7 +51,7 @@ services: memory: 128M healthcheck: - test: ['CMD', 'wget', '--quiet', '--tries=1', '--spider', 'http://127.0.0.1:3001/'] + test: ['CMD', 'wget', '--quiet', '--tries=1', '--spider', 'http://127.0.0.1:3001/health'] interval: 30s timeout: 10s retries: 3 diff --git a/package-lock.json b/package-lock.json index 1d99818..e5dfc3b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "6.0.0", "license": "MIT", "dependencies": { - "@agentage/observability": "^0.6.1", + "@agentage/observability": "^0.8.0", "@vercel/otel": "^2.1.3", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -61,9 +61,9 @@ "license": "MIT" }, "node_modules/@agentage/observability": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@agentage/observability/-/observability-0.6.2.tgz", - "integrity": "sha512-0majcV+z1GWJ5D9ANjXeCxvrGea0e7z0qafwJfD7bmvHvT1K1lsqIp9sviPVRDgEgj5fj6fyDOxOFNuSfFd8QA==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@agentage/observability/-/observability-0.8.1.tgz", + "integrity": "sha512-haJ2YFpLigtHlnKOp93y6c0PWFudn9izuzRioffYadJjNTzy/Ovg/7DI943bXANAW4iYbK3MAlJYT3qmxa521Q==", "license": "MIT", "dependencies": { "@opentelemetry/api": "1.9.1", diff --git a/package.json b/package.json index f1ddbe3..e561ffd 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "verify": "npx tsc --noEmit && next lint && npm run build && vitest run" }, "dependencies": { - "@agentage/observability": "^0.6.1", + "@agentage/observability": "^0.8.0", "@vercel/otel": "^2.1.3", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", diff --git a/src/app/health/route.test.ts b/src/app/health/route.test.ts new file mode 100644 index 0000000..4f5a2ba --- /dev/null +++ b/src/app/health/route.test.ts @@ -0,0 +1,13 @@ +import { describe, it, expect } from 'vitest'; +import { GET } from './route'; + +describe('GET /health', () => { + it('reports the v1 envelope for diffractwd-web', async () => { + const res = await GET(); + const body = await res.json(); + + expect(res.status).toBe(200); + expect(body.data.service).toBe('diffractwd-web'); + expect(body.data.status).toBe('ok'); + }); +}); diff --git a/src/app/health/route.ts b/src/app/health/route.ts new file mode 100644 index 0000000..f2df5f1 --- /dev/null +++ b/src/app/health/route.ts @@ -0,0 +1,6 @@ +import { healthResponse } from '@agentage/observability/health'; + +// Never prerender, or commit/buildTime are baked at build instead of read from the +// running container. +export const dynamic = 'force-dynamic'; +export const GET = () => healthResponse({ service: 'diffractwd-web' });