From 0892e96b5095bb9819bc966f56946114b4636e95 Mon Sep 17 00:00:00 2001 From: mikim <1441941+mikim@users.noreply.github.com> Date: Wed, 9 Sep 2026 22:48:22 +0900 Subject: [PATCH] =?UTF-8?q?health:=20=EC=9D=91=EB=8B=B5=20=EC=8B=9C?= =?UTF-8?q?=EA=B0=81=EC=9D=84=20timestamp=20=EB=A1=9C=EB=8F=84=20=EB=82=B4?= =?UTF-8?q?=EB=B3=B4=EB=82=B8=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /api/health 가 생태계 health 규약이 요구하는 timestamp 를 빠뜨리고 있었다. 값 자체는 이미 ts 로 있었으므로 새로 만들 것은 없고, 이름만 하나 더 붙인다. 한 번 계산한 instant 를 now 로 올려 ts 와 timestamp 에 같이 넣는다. new Date() 를 두 번 부르면 tick 을 사이에 두고 갈라져 같은 응답이 두 개의 생성 시각을 주장할 수 있다. ts 는 그대로 둔다 — 기존 소비자가 읽는 이름이다. 순수 추가이므로 기존 필드는 하나도 지우거나 옮기지 않았고, status 값("fail")과 ?strict=1 의 503 동작도 건드리지 않았다. Co-Authored-By: Claude Opus 5 --- app/api/health/route.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/api/health/route.ts b/app/api/health/route.ts index 365fb06..2144fc9 100644 --- a/app/api/health/route.ts +++ b/app/api/health/route.ts @@ -37,12 +37,19 @@ export async function GET(req: Request) { const sys = detailed || strict ? getSystemHealth() : null; const failing = !dbOk || sys?.worstStatus === "fail"; + // One instant under two names. `ts` is what every existing consumer reads; + // `timestamp` is the ecosystem health contract's spelling. Computing it once + // is the point — two `new Date()` calls could disagree across a tick and + // leave the same response claiming two generation times. + const now = new Date().toISOString(); + const base = { status: failing ? "fail" : "ok", service: "alpha", db: dbOk ? "ok" : "fail", seo_pages: seoCount.n, - ts: new Date().toISOString(), + ts: now, + timestamp: now, // Only meaningful when the roll-up ran; otherwise say so rather than // implying every subsystem was checked. worst_status: sys ? sys.worstStatus : "not_evaluated",