[object Object]

← back to Rentv Sheet Enrich

header-driven writer + Why(Marketing/VP) rationale column; Event Sponsors Layer-2 complete (30 LI, 22 marketing/VP+why)

0c99341064dc0392ce4f046e15299489aaa6f6fa · 2026-08-13 10:21:40 -0700 · Steve Abrams

Files touched

Diff

commit 0c99341064dc0392ce4f046e15299489aaa6f6fa
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu Aug 13 10:21:40 2026 -0700

    header-driven writer + Why(Marketing/VP) rationale column; Event Sponsors Layer-2 complete (30 LI, 22 marketing/VP+why)
---
 write_results.py | 79 +++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 56 insertions(+), 23 deletions(-)

diff --git a/write_results.py b/write_results.py
index f05b9d7..43f9fb7 100644
--- a/write_results.py
+++ b/write_results.py
@@ -2,47 +2,80 @@
 """
 write_results.py <gid> <results.json>
 
-Central writer used by research subagents. Reads a results JSON (list of dicts) and
-writes ONLY the non-empty enrichment fields into the correct new columns for that tab,
-each stamped light-green. LinkedIn fields are written as clickable =HYPERLINK formulas.
-
-results.json item shape (all fields optional except row):
-  {"row": <1-based row>, "website": "domain.com",
-   "company_li": "https://www.linkedin.com/company/slug",
-   "contact_li": "https://www.linkedin.com/in/slug",
-   "mvp": "Name — Title — https://www.linkedin.com/in/slug",
-   "updated_email": "person@corp.com"}
-
-Never overwrites a cell that already has content (idempotent + safe for parallel runs).
+Header-DRIVEN central writer. Finds each enrichment column by its HEADER LABEL in the
+tab's header row (never by fragile offset math), so data always lands in the right column
+regardless of each tab's hidden Status column. Auto-creates any missing enrichment header
+(e.g. "Why (Marketing/VP)") in the next free column. Only fills EMPTY cells; every filled
+cell is light-green. LinkedIn fields become clickable =HYPERLINK formulas.
+
+results.json item shape (all optional except row):
+  {"row": <1-based>, "website": "...", "company_li": "https://linkedin.com/company/..",
+   "contact_li": "https://linkedin.com/in/..", "mvp": "Name — Title — <url>",
+   "updated_email": "person@corp.com", "why": "why this marketing/VP was chosen"}
 """
 import sys, os, json
 sys.path.insert(0, os.path.dirname(__file__))
 import lib, enrich
 
+# result key -> exact header label in the sheet
+LABELS = {
+    "website":       "Website",
+    "company_li":    "LinkedIn (Company)",
+    "contact_li":    "LinkedIn (Contact)",
+    "mvp":           "Marketing/VP Contact",
+    "updated_email": "Updated Email (found)",
+    "why":           "Why (Marketing/VP)",
+}
+LINK_KEYS = {"company_li", "contact_li"}
+
 gid = int(sys.argv[1]); results = json.load(open(sys.argv[2]))
-cfg = enrich.TABS[gid]; b = cfg["base"]
-COL = dict(website=b, company_li=b+1, contact_li=b+2, mvp=b+3, updated_email=b+4)
+cfg = enrich.TABS[gid]; hr = cfg["header_row"]
 
 tok = lib.access_token()
 meta = lib.get_meta(tok)
 title = {s["properties"]["sheetId"]: s["properties"]["title"] for s in meta["sheets"]}[gid]
 rows = lib.read_tab(tok, title)
-def cur(r0, c): return (rows[r0][c] if r0 < len(rows) and c < len(rows[r0]) else "").strip()
+def cell(r0, c): return (rows[r0][c] if r0 < len(rows) and c < len(rows[r0]) else "").strip()
+
+hdr = rows[hr] if hr < len(rows) else []
+def hcell(i): return (hdr[i] if i < len(hdr) else "").strip()
+
+# locate each label's column; track rightmost used column for placing new headers
+col = {}
+rightmost = 0
+for i, v in enumerate(hdr):
+    if v.strip():
+        rightmost = i
+for key, label in LABELS.items():
+    found = next((i for i in range(len(hdr)) if hcell(i) == label), None)
+    col[key] = found
+
+# create any missing header (e.g. Why) after the rightmost used column
+new_header_cells = []
+nxt = rightmost + 1
+for key, label in LABELS.items():
+    if col[key] is None:
+        col[key] = nxt
+        new_header_cells.append({"row0": hr, "col0": nxt, "value": label})
+        nxt += 1
+if new_header_cells:
+    lib.batch_fill(tok, gid, new_header_cells)
 
 cells = []
 for it in results:
     r0 = int(it["row"]) - 1
-    for key in ("website", "company_li", "contact_li", "mvp", "updated_email"):
+    for key in LABELS:
         val = (it.get(key) or "").strip()
         if not val:
             continue
-        col = COL[key]
-        if cur(r0, col):          # don't overwrite existing content
+        c = col[key]
+        if cell(r0, c):          # never overwrite existing content
             continue
-        if key in ("company_li", "contact_li"):
-            cells.append({"row0": r0, "col0": col,
-                          "value": '=HYPERLINK("%s")' % val.replace('"', ""), "formula": True})
+        if key in LINK_KEYS:
+            cells.append({"row0": r0, "col0": c, "value": '=HYPERLINK("%s")' % val.replace('"', ""), "formula": True})
         else:
-            cells.append({"row0": r0, "col0": col, "value": val})
+            cells.append({"row0": r0, "col0": c, "value": val})
 res = lib.batch_fill(tok, gid, cells)
-print(json.dumps({"gid": gid, "rows_in": len(results), "cells_written": res.get("totalUpdatedCells", 0)}))
+print(json.dumps({"gid": gid, "rows_in": len(results),
+                  "headers_added": [c["value"] for c in new_header_cells],
+                  "cells_written": res.get("totalUpdatedCells", 0)}))

← b91ae60 Layer 2 sweep harness: Updated Email column, contact-aware b  ·  back to Rentv Sheet Enrich  ·  FIX: name-matched writer (row-shift immune); reset+re-applie f5ee325 →