[object Object]

← back to Stars of Design

api/version: deploy fingerprint endpoint (asim parity)

49fd5af83e30674f293d05a94225b21a68b2f78e · 2026-05-13 10:04:40 -0700 · Steve Abrams

Files touched

Diff

commit 49fd5af83e30674f293d05a94225b21a68b2f78e
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed May 13 10:04:40 2026 -0700

    api/version: deploy fingerprint endpoint (asim parity)
---
 routes/public.js | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/routes/public.js b/routes/public.js
index fc551a2..f14d8d6 100644
--- a/routes/public.js
+++ b/routes/public.js
@@ -15,6 +15,21 @@ const statsPool = new Pool({
   max: 2,
 });
 
+// Cached version metadata: package.json version + git short SHA (best-effort).
+// Resolved once at module-load so /api/version stays sub-1ms.
+const PKG_VERSION = (() => {
+  try { return require('../package.json').version || '0.0.0'; }
+  catch (_) { return '0.0.0'; }
+})();
+const GIT_SHA = (() => {
+  try {
+    return require('child_process')
+      .execSync('git rev-parse --short HEAD', { cwd: require('path').resolve(__dirname, '..'), stdio: ['ignore', 'pipe', 'ignore'] })
+      .toString().trim() || 'unknown';
+  } catch (_) { return 'unknown'; }
+})();
+const STARTED_AT_ISO = new Date().toISOString();
+
 const SITE_TITLE = 'Stars of Design';
 const META_DESC = 'Stars of Design — a curated profile directory of the world\'s most influential interior designers, decade by decade, with the wallcoverings that match each designer\'s signature style.';
 
@@ -40,6 +55,19 @@ router.get('/healthz', (req, res) => {
   res.json({ ok: true, ts: Date.now() });
 });
 
+// /api/version — deploy fingerprint. Lets Steve verify which build is live
+// without inspecting pm2 logs. Static at boot, so no DB hit.
+router.get('/api/version', (_req, res) => {
+  res.setHeader('Cache-Control', 'no-store');
+  res.json({
+    name:       'starsofdesign',
+    version:    PKG_VERSION,
+    git:        GIT_SHA,
+    node:       process.version,
+    started_at: STARTED_AT_ISO,
+  });
+});
+
 // /api/health — slightly heavier liveness + count snapshot. Mirrors asim
 // /api/health pattern; uses the same shared statsPool. no-store so monitor
 // tools always see fresh state. Includes uptime_s and as_of for ops dashboards.
@@ -407,6 +435,7 @@ router.get('/api', (_req, res) => {
     base: 'https://starsofdesign.com',
     endpoints: {
       'GET /api/health':                 'Liveness probe (SELECT 1) — JSON ok+ts',
+      'GET /api/version':                'Deploy fingerprint — JSON {name, version, git, node, started_at}',
       'GET /api/stats':                  'Aggregate counts (designers/firms/claimed/links/likes/comments/candidates)',
       'GET /api/clients/:id/comments':   'Comments on a DW client profile (chronological)',
       'POST /api/clients/:id/like':      'Toggle like on a DW client (anonymous ID via cookie)',

← 90ada6d smoke: uptime_s + counts.designers assertions on /api/health  ·  back to Stars of Design  ·  smoke: 4 assertions for /api/version 95b38f5 →