[object Object]

← back to Dw Marketing Reels

Add glitter_walls_design as a tracked (non-postable) IG source on marketing.dw

c0c76ea3ae6b95e649f95e33cf958b522e50de33 · 2026-08-26 11:20:25 -0700 · Steve Abrams

External account (NOT DW-owned) seeded the Glitter Walls collection; add it as a
read-only tracked/inspiration source via data/tracked-ig-sources.json + a read-only
/api/tracked-ig-sources endpoint + a labeled 'Tracked / inspiration accounts' panel.
Deliberately kept OUT of readAccountsUnion() so it can never appear in the publish
dropdown or pass the /api/reel-account validity check. TK-10884.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit c0c76ea3ae6b95e649f95e33cf958b522e50de33
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Aug 26 11:20:25 2026 -0700

    Add glitter_walls_design as a tracked (non-postable) IG source on marketing.dw
    
    External account (NOT DW-owned) seeded the Glitter Walls collection; add it as a
    read-only tracked/inspiration source via data/tracked-ig-sources.json + a read-only
    /api/tracked-ig-sources endpoint + a labeled 'Tracked / inspiration accounts' panel.
    Deliberately kept OUT of readAccountsUnion() so it can never appear in the publish
    dropdown or pass the /api/reel-account validity check. TK-10884.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 data/tracked-ig-sources.json | 14 ++++++++++++++
 public/index.html            | 18 +++++++++++++++++-
 server.js                    |  7 +++++++
 3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/data/tracked-ig-sources.json b/data/tracked-ig-sources.json
new file mode 100644
index 0000000..1b2f343
--- /dev/null
+++ b/data/tracked-ig-sources.json
@@ -0,0 +1,14 @@
+[
+  {
+    "id": "src-glitter-walls-design",
+    "label": "Glitter Walls Design",
+    "handle": "glitter_walls_design",
+    "url": "https://www.instagram.com/glitter_walls_design/",
+    "type": "tracked-source",
+    "owned": false,
+    "source": "scraped-content",
+    "related_collection": "/collections/glitter-walls",
+    "note": "External Instagram account (NOT DW-owned). Its glitter/sequin wallcovering content seeded the DW Glitter Walls collection + flipbook (data/glitter-walls.json). Inspiration / content-source reference only — never a publish target.",
+    "added_at": "2026-08-26"
+  }
+]
diff --git a/public/index.html b/public/index.html
index 6b9d986..bdca66a 100644
--- a/public/index.html
+++ b/public/index.html
@@ -144,6 +144,9 @@
   <h2 id="sec-accts">Instagram accounts <span style="font-size:13px;color:#8a8272">(choose per reel below)</span></h2>
   <div class="accts" id="accts"></div>
 
+  <h2 id="sec-tracked" style="margin-top:22px">Tracked / inspiration accounts <span style="font-size:13px;color:#8a8272">(external · read-only · never a publish target)</span></h2>
+  <div class="accts" id="tracked"></div>
+
   <h2 id="sec-reels">Reels</h2>
   <div class="reels" id="reels"></div>
 
@@ -288,6 +291,19 @@ async function loadAccounts() {
 function acctOptions(sel) {
   return ACCTS.map(a => `<option value="${a.id}" ${a.id===sel?'selected':''}>${escapeHtml(a.label)}${a.status==='ready'?'':' (needs creds)'}</option>`).join('');
 }
+// ── tracked / inspiration accounts (external, NOT postable) ──
+// Read-only render off /api/tracked-ig-sources — deliberately NOT wired into ACCTS or
+// the publish dropdown so a non-owned account can never become a publish target.
+async function loadTracked() {
+  const el = $('#tracked'); if (!el) return;
+  const list = await (await fetch('api/tracked-ig-sources')).json().catch(() => []);
+  el.innerHTML = list.map(a => `
+    <div class="acct" title="${escapeAttr(a.note||'')}">
+      <span class="dot" style="background:#8a8272"></span>
+      <span>${escapeHtml(a.label)}</span>
+      <span class="h">${a.handle ? '<a href="'+escapeAttr(a.url||('https://instagram.com/'+a.handle))+'" target="_blank" rel="noopener noreferrer">@'+escapeHtml(a.handle)+'</a>' : 'handle TBD'} · tracked · not postable</span>
+    </div>`).join('') || '<span style="color:#8a8272">No tracked accounts.</span>';
+}
 // edit existing account → reuse the account modal
 $('#accts').addEventListener('click', e => {
   const ed = e.target.closest('.edit-acct'); if (!ed) return;
@@ -592,7 +608,7 @@ $('#btnBuild').addEventListener('click', ()=>job('api/build','▶ generating ree
   } catch {}
 })();
 
-loadAccounts().then(loadReels); loadNA(); loadVideos(); loadJobs(); loadSuggestions();
+loadAccounts().then(loadReels); loadTracked(); loadNA(); loadVideos(); loadJobs(); loadSuggestions();
 </script>
 </body>
 </html>
diff --git a/server.js b/server.js
index e94dc7d..f5a5095 100644
--- a/server.js
+++ b/server.js
@@ -187,6 +187,13 @@ const server = http.createServer(async (req, res) => {
       }
       return res.writeHead(200, { 'content-type': 'application/json' }).end(JSON.stringify(await readAccountsUnion()));
     }
+    // Tracked / inspiration IG accounts — external, NOT DW-owned, NEVER a publish target.
+    // Read-only and deliberately kept OUT of readAccountsUnion() so these can never appear
+    // in the publish dropdown or pass the /api/reel-account account-validity check.
+    if (p === '/api/tracked-ig-sources') {
+      const fp = join(ROOT, 'data', 'tracked-ig-sources.json');
+      return res.writeHead(200, { 'content-type': 'application/json' }).end(existsSync(fp) ? await readFile(fp) : '[]');
+    }
     if (p === '/api/reel-account' && req.method === 'POST') {
       // set which IG account a reel will publish to: {file, accountId}
       const { file, accountId } = await readBody(req);

← 9de1fc9 Reel Studio: render a single photo + song → mp4 (Composer ha  ·  back to Dw Marketing Reels  ·  auto-data-snapshot: 2026-08-26T11:30:17 (1 data files) — dat aa363eb →