[object Object]

← back to Designerssalesreps

fix: convert to 301-redirect server + add deploy scaffold

7bb1bb202d20be659d0e4bbcc28b7980a8a9b3f4 · 2026-07-27 14:39:39 -0700 · Steve Abrams

designerssalesreps.com (plural/typo variant) now permanently 301-redirects
all traffic to designersalesreps.com. Adds ecosystem.config.js (port 9916),
deploy-kamatera.sh, nginx vhost (also handles 301 at nginx layer), .deploy.conf.
Deploy gated pending Steve NS-swap approval.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Files touched

Diff

commit 7bb1bb202d20be659d0e4bbcc28b7980a8a9b3f4
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Jul 27 14:39:39 2026 -0700

    fix: convert to 301-redirect server + add deploy scaffold
    
    designerssalesreps.com (plural/typo variant) now permanently 301-redirects
    all traffic to designersalesreps.com. Adds ecosystem.config.js (port 9916),
    deploy-kamatera.sh, nginx vhost (also handles 301 at nginx layer), .deploy.conf.
    Deploy gated pending Steve NS-swap approval.
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---
 .deploy.conf                                 |  4 +++
 deploy-kamatera.sh                           | 36 +++++++++++++++++++++
 docs/nginx-vhost-designerssalesreps.com.conf | 29 +++++++++++++++++
 ecosystem.config.js                          | 24 ++++++++++++++
 server.js                                    | 47 ++++++----------------------
 5 files changed, 102 insertions(+), 38 deletions(-)

diff --git a/.deploy.conf b/.deploy.conf
new file mode 100644
index 0000000..86b2771
--- /dev/null
+++ b/.deploy.conf
@@ -0,0 +1,4 @@
+PROJECT_NAME=designerssalesreps-redirect
+DEPLOY_PATH=/root/Projects/designerssalesreps
+HEALTH_URL=https://designerssalesreps.com/health
+PORT=9916
diff --git a/deploy-kamatera.sh b/deploy-kamatera.sh
new file mode 100644
index 0000000..7b5dbf6
--- /dev/null
+++ b/deploy-kamatera.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+# deploy-kamatera.sh — designerssalesreps.com (301 redirect) → Kamatera 45.61.58.125
+# This is the typo/plural variant — it redirects everything to designersalesreps.com.
+# Usage: bash deploy-kamatera.sh
+set -euo pipefail
+
+REMOTE=root@45.61.58.125
+LOCAL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+REMOTE_DIR=/root/Projects/designerssalesreps
+HEALTH_URL=http://127.0.0.1:9916/health
+
+echo "==> Syncing to $REMOTE:$REMOTE_DIR"
+rsync -az --delete \
+  --exclude='node_modules/' \
+  --exclude='.git/' \
+  --exclude='.env*' \
+  --exclude='*.log' \
+  --exclude='logs/' \
+  "$LOCAL_DIR/" "$REMOTE:$REMOTE_DIR/"
+
+echo "==> npm install on remote"
+ssh "$REMOTE" "cd $REMOTE_DIR && npm install --omit=dev --silent"
+
+echo "==> mkdir logs"
+ssh "$REMOTE" "mkdir -p $REMOTE_DIR/logs"
+
+echo "==> pm2 startOrReload"
+ssh "$REMOTE" "cd $REMOTE_DIR && pm2 startOrReload ecosystem.config.js --update-env && pm2 save"
+
+echo "==> Health check (origin direct)"
+ssh "$REMOTE" "curl -sf $HEALTH_URL" && echo "PASS: origin direct" || { echo "FAIL: health check"; exit 1; }
+
+echo "==> Verifying 301 redirect from CF-proxied variant"
+curl -sI https://designerssalesreps.com/ 2>/dev/null | grep -i "location:\|301" || echo "WARN: CF not yet routed (DNS pending?)"
+
+echo "==> Done. designerssalesreps.com 301-redirect is live on :9916"
diff --git a/docs/nginx-vhost-designerssalesreps.com.conf b/docs/nginx-vhost-designerssalesreps.com.conf
new file mode 100644
index 0000000..fa025bb
--- /dev/null
+++ b/docs/nginx-vhost-designerssalesreps.com.conf
@@ -0,0 +1,29 @@
+# nginx vhost — designerssalesreps.com (301 redirect to primary)
+# Copy to: /etc/nginx/sites-available/designerssalesreps.com
+# Enable: ln -s /etc/nginx/sites-available/designerssalesreps.com /etc/nginx/sites-enabled/
+# Reload: nginx -t && systemctl reload nginx
+
+server {
+    listen 80;
+    server_name designerssalesreps.com www.designerssalesreps.com;
+
+    # Cloudflare real-IP passthrough
+    set_real_ip_from 103.21.244.0/22;
+    set_real_ip_from 104.16.0.0/13;
+    set_real_ip_from 104.24.0.0/14;
+    set_real_ip_from 172.64.0.0/13;
+    set_real_ip_from 173.245.48.0/20;
+    set_real_ip_from 162.158.0.0/15;
+    real_ip_header CF-Connecting-IP;
+
+    # Node handles the 301 on :9916, but nginx-level redirect is belt+suspenders.
+    # The node server.js also returns 301 so either layer catches it.
+    location /health {
+        proxy_pass http://127.0.0.1:9916;
+        proxy_set_header Host $host;
+    }
+
+    location / {
+        return 301 https://designersalesreps.com$request_uri;
+    }
+}
diff --git a/ecosystem.config.js b/ecosystem.config.js
new file mode 100644
index 0000000..1b89475
--- /dev/null
+++ b/ecosystem.config.js
@@ -0,0 +1,24 @@
+module.exports = {
+  apps: [{
+    name: 'designerssalesreps-redirect',
+    script: 'server.js',
+    cwd: '/root/Projects/designerssalesreps',
+    env: {
+      PORT: 9916,
+      NODE_ENV: 'production'
+    },
+    instances: 1,
+    autorestart: true,
+    watch: false,
+    max_memory_restart: '256M',
+    error_file: './logs/err.log',
+    out_file: './logs/out.log',
+    log_file: './logs/combined.log',
+    time: true,
+    max_restarts: Infinity,
+    min_uptime: '5s',
+    restart_delay: 1000,
+    exp_backoff_restart_delay: 100,
+    kill_timeout: 5000
+  }]
+};
diff --git a/server.js b/server.js
index d9d2a3d..177b3fd 100644
--- a/server.js
+++ b/server.js
@@ -1,46 +1,17 @@
 'use strict';
+// designerssalesreps.com — permanent 301 redirect to the canonical primary.
+// This is the typo/plural variant; the real site lives at designersalesreps.com.
 const express = require('express');
-const fs = require('fs');
-const path = require('path');
 const app = express();
 const PORT = process.env.PORT || 9916;
-const DOMAIN = 'designerssalesreps.com';
 
-app.use(express.json());
+app.get('/health', (req, res) => res.json({ ok: true, redirect: 'designersalesreps.com' }));
 
-// Hard 404 guard: never serve snapshot/backup files even if they
-// land in public/. Mirrors the standing fleet rule.
-app.use((req, res, next) => {
-  if (/\.(bak|bak\..+|pre-[^/]+)$/i.test(req.path) || /\.pre-/i.test(req.path)) {
-    return res.status(404).send('Not found');
-  }
-  next();
+app.use((req, res) => {
+  const target = 'https://designersalesreps.com' + req.originalUrl;
+  res.redirect(301, target);
 });
 
-app.use(express.static(path.join(__dirname, 'public')));
-
-const reps = JSON.parse(fs.readFileSync(path.join(__dirname, 'data/reps.json'), 'utf8'));
-
-app.get('/api/search', (req, res) => {
-  const { q = '', territory = '', vertical = '', sort = 'name' } = req.query;
-  let results = reps.filter(r => {
-    const qLow = q.toLowerCase();
-    const matchQ = !q || r.name.toLowerCase().includes(qLow) || r.agency.toLowerCase().includes(qLow) || r.lines.some(l => l.toLowerCase().includes(qLow)) || r.city.toLowerCase().includes(qLow);
-    const matchT = !territory || r.territories.includes(territory);
-    const matchV = !vertical || r.vertical.includes(vertical);
-    return matchQ && matchT && matchV;
-  });
-  if (sort === 'agency') results.sort((a, b) => a.agency.localeCompare(b.agency));
-  else if (sort === 'city') results.sort((a, b) => a.city.localeCompare(b.city));
-  else results.sort((a, b) => a.name.localeCompare(b.name));
-  res.json({ total: results.length, results });
-});
-
-app.post('/api/claim', (req, res) => {
-  const entry = { ...req.body, ts: new Date().toISOString(), domain: DOMAIN };
-  fs.appendFileSync(path.join(__dirname, 'claims.jsonl'), JSON.stringify(entry) + '\n');
-  res.json({ ok: true });
-});
-
-app.get('/health', (req, res) => res.json({ ok: true, domain: DOMAIN }));
-app.listen(PORT, '127.0.0.1', () => console.log(`${DOMAIN} listening on ${PORT}`));
+app.listen(PORT, '127.0.0.1', () =>
+  console.log(`designerssalesreps.com redirect → designersalesreps.com on :${PORT}`)
+);

← 1279c63 server: add 404 guard for .bak/.pre- snapshot paths  ·  back to Designerssalesreps  ·  auto-save: 2026-07-27T14:51:27 (1 files) — package-lock.json 1e0eb23 →