feat(ops): /api/version endpoint with git SHA + build time

Adds a public, no-auth endpoint at /api/version that returns:
  { commit, commitShort, buildTime, nodeEnv, cutover, nextVersion }

Build-time injection via GIT_COMMIT + BUILD_TIME ARG/ENV propagated
from compose build.args through Dockerfile builder + runner stages.
Excluded from middleware auth gating.

Deploy command (run on satra after git pull):
  GIT_COMMIT=$(git rev-parse HEAD) \
    BUILD_TIME=$(date -u +%FT%TZ) \
    docker compose build architools

Without these env vars, falls back to "unknown" so the build never
fails; only the endpoint shows reduced info.

Useful for: confirming what's actually deployed after CI, cross-app
deploy correlation (api.gis.ac, eterra.live, orchestrator), uptime
monitors.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude VM
2026-05-18 23:06:35 +03:00
parent 6054d083b5
commit 64bccdb4b0
4 changed files with 47 additions and 1 deletions
+31
View File
@@ -0,0 +1,31 @@
import { NextResponse } from "next/server";
export const runtime = "nodejs";
export const dynamic = "force-dynamic";
/**
* Public version endpoint. Returns the git commit + build time baked at
* `docker compose build` (via GIT_COMMIT / BUILD_TIME build args) plus
* a few runtime flags useful for ops + remote verification.
*
* No auth. Excluded from middleware matcher.
*
* Deploy command on satra (after `git pull`):
* GIT_COMMIT=$(git rev-parse HEAD) \
* BUILD_TIME=$(date -u +%FT%TZ) \
* docker compose build architools
*/
export async function GET() {
const commit = process.env.GIT_COMMIT || "unknown";
return NextResponse.json({
commit,
commitShort: commit.slice(0, 7),
buildTime: process.env.BUILD_TIME || "unknown",
nodeEnv: process.env.NODE_ENV || "unknown",
cutover: {
useGisAcDefault: process.env.USE_GIS_AC === "1",
pilotUsers: (process.env.GIS_AC_PILOT_USERS || "").split(",").filter(Boolean).length,
},
nextVersion: "16.1.6",
});
}