Files
beantownbabeandClaude Sonnet 5 5b4918d2af Document the Opportunities module and list it as a fifth branch
- opportunities/README.md: what's in the folder, how to update the
  OPPORTUNITIES/SCOUT_RESULTS data, and the fetch-based loading
  architecture (why it's separate from the index.html monolith and
  what that means for anyone editing it)
- Root README.md was still describing four branches with no mention
  of Opportunities at all — added it as the fifth

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 13:35:55 +02:00

3.2 KiB

Opportunities

Tracks conferences and events worth attending or watching, plus Conference Scout, a scheduled agent that finds new candidates automatically. Lives in the Sales & Marketing dash's Opportunities tab (localhost:8500).

Files

  • opportunities.html — the tab's markup (Events list + calendar card, Conference Scout drill-view). Fetched and injected into the shell's empty #tab-opportunities container at page load — it is not present in index.html itself.
  • opportunities.js — everything behavioral: the OPPORTUNITIES (Events list + calendar) and SCOUT_RESULTS (Conference Scout candidates) data arrays, the calendar renderer, event-list renderer, and the drill-view registration that plugs this module into the shared shell (see "Architecture" below). Loaded as a normal <script src> right after the HTML above is injected.
  • opportunities.css — all styling for both cards and the calendar.

Updating the data

Both data arrays live as plain JS literals at the top of opportunities.js — no build step, just edit and reload the page.

  • OPPORTUNITIES — confirmed events TXproducts is tracking or attending. One entry per event: { start, end (optional, defaults to start), title, location, attendee (optional), url (optional), abstract (optional) }. Dates are "YYYY-MM-DD". Multi-day entries render as a single bar spanning their date range on the calendar.
  • SCOUT_RESULTS — this week's Conference Scout candidates, hand-copied in from the routine's latest run (see agents/conference-scout/). Each entry: { title, dates (display text, not parsed), location, url (optional), reason }. This list is fully replaced on each sync, not accumulated — it's a snapshot of the latest run, not a running history.

There is currently no automated sync between a Conference Scout run finishing and this array being updated — see agents/conference-scout/README.md for why, and what the actual weekly workflow looks like.

Architecture: why this is fetched instead of inline

Every other tab in this dash (Team, Directory, Marketing, Sales) is still authored directly inside index.html. Opportunities was pulled out into its own module as a first step toward breaking up that monolith, so it uses a small loader pattern instead:

index.html:
  <div id="tab-opportunities" class="tab-content">…</div>   <!-- empty on load -->
  fetch("opportunities/opportunities.html") → inject as innerHTML
    → then append <script src="opportunities/opportunities.js">

Two consequences worth knowing if you're editing this:

  • The module registers itself. index.html's shared HERO_NAV_BY_TAB, DRILL_CONFIG, and DRILL_DEFAULT_VIEW objects do not contain an opportunities entry — opportunities.js adds one at the bottom, once its own HTML exists in the DOM. setDrillView() in the shell tolerates a scope that isn't registered yet (it just no-ops), which is what makes the load order safe.
  • Nothing here runs until the fetch resolves. For a local static file this is near-instant, so in practice there's no visible delay, but if you ever see the Opportunities tab stuck on "Loading…", check the browser console for a fetch/network error first.