pbs-obsidian-vault/PBS/Tech/Projects/content-hub-phase5-planning.md

6.0 KiB
Raw Permalink Blame History

project type status tags created updated path
content-hub-phase5-planning project-plan active
pbs
flask
mysql
n8n
instagram
automation
docker
2026-03-19 2026-03-19 PBS/Tech/Projects/

PBS Content Hub — Phase 5 Planning Decisions

Context

Phases 14 of the Instagram Automation & Content Hub master plan are complete:

  • Phase 1 — MySQL schema with single instagram_posts table
  • Phase 2 — Reply workflow refactored with error notifications
  • Phase 3 — WordPress → MySQL sync via webhook
  • Phase 4 — Instagram reel publish webhook capturing reel IDs

Phase 5 focuses on building the Content Hub UI layer that gives Jenny and her assistant self-service access to recipe/reel management — removing Travis as the manual middleman for MySQL lookups.


Key Architecture Decisions

1. Recipe-to-Reel Linking Strategy

Decision: Manual selection in Content Hub (Option B)

Jenny selects the recipe from a dropdown when creating a reel record in the hub. This auto-populates the post ID, keyword, and URL. No caption parsing, no fragile keyword matching.

Rationale: Jenny is already in the hub building captions — selecting the recipe is one extra dropdown click. Most reliable approach with zero parsing ambiguity.

2. Reel Record Lifecycle (Two-Stage)

Decision: Local-first, then matched to live data

  • Stage 1 (Pre-publish): Jenny creates a reel record in the Content Hub before anything exists on Instagram. This is a local planning record — working title, linked recipe, keyword, built caption.
  • Stage 2 (Post-publish): After Jenny posts the reel, the Instagram webhook fires, n8n writes the reel ID to instagram_posts in MySQL. The hub reads from that table and matches it to the local record.

3. n8n Stays Decoupled From the Hub

Decision: n8n is dumb to the hub

  • n8n writes to instagram_posts in MySQL — that's its job
  • n8n does NOT call the Content Hub API or know about hub reel records
  • The Content Hub reads from instagram_posts to display what's live
  • The hub owns the matching logic between its local records and n8n's data

Rationale: Keeps n8n focused on automation. The hub is the human workflow layer on top.

4. Auto-Match Routine

Decision: Triggered by n8n ping after new insert

After n8n writes a new row to instagram_posts, it sends a simple ping to the hub (POST /api/match/run). The hub then runs the matching logic:

For each hub reel record in "Ready" status (no reel ID linked):
    → Look in instagram_posts for unmatched rows where:
        - post_id matches (recipe link) OR keyword matches
    → Single match → auto-link, status → "Live — Matched" ✅
    → Multiple matches → flag as "Needs Review" 🟡
    → No match → leave as-is

Jenny's manual match UI is the fallback for anything the auto-matcher can't confidently link.

5. Recipe Dropdown Source

Decision: MySQL recipes table (not WordPress REST API)

The recipe dropdown in the reel creation form pulls from the local MySQL recipes table, which is already kept in sync via the WordPress publish webhook. Faster, no external API calls during form interactions.


UI Structure Decisions

Reel Detail Page — Tabbed Layout

[ Overview ]  [ Caption Builder ]

Overview tab:

  • Reel Title (free text)
  • Recipe dropdown (from MySQL) → auto-fills keyword + URL
  • Keyword (editable — this is the recipe review/confirm step)
  • Recipe URL (read-only)
  • Status indicator
  • Save / Delete

Caption Builder tab:

  • Select library blocks (hashtags, links, CTAs, about snippets)
  • Preview assembled caption
  • Copy to clipboard

Reel List View

Data points shown per reel (layout TBD — getting Jenny's input on table vs cards):

  • Reel title
  • Linked recipe name (or "No Recipe" warning)
  • Keyword
  • Status (color dot + label)
  • Date created or last updated

Recipe Review UI

Decision: Not a separate screen. Baked into the reel creation flow — when Jenny selects a recipe from the dropdown, she sees the record (title, URL, keyword) and confirms/edits the keyword right there.

Manual Match Correction

A "Link Reel" button on flagged records in the dashboard. Jenny selects from a list of unmatched instagram_posts rows to connect the dots.


Reel Status States (Draft)

  1. Draft — reel record created, no recipe linked yet
  2. Ready — recipe linked, keyword confirmed, caption built. Waiting to be posted
  3. Live — Matched — Instagram webhook received, reel ID attached, auto-reply active
  4. Live — Unmatched / Needs Review — auto-match couldn't confidently link

Open Questions (Still To Decide)

  • Reel list layout: table rows vs cards (get Jenny's feedback)
  • Jenny's assistant access: same login or separate user accounts?
  • Status Dashboard details: per-reel health indicators + system health panel (next planning session)
  • Database schema for hub reel records table (next planning session)
  • Define green/yellow/red status thresholds in detail

Target Automation Flow (Full Picture)

Jenny creates reel record in hub → selects recipe → builds caption
    ↓
Jenny posts reel to Instagram
    ↓
Instagram webhook → n8n → writes reel ID to instagram_posts
    ↓
n8n pings hub (POST /api/match/run)
    ↓
Hub auto-match runs:
    - Finds match → links record → status = Live — Matched ✅
    - No confident match → status = Needs Review 🟡
    ↓
Comment comes in on Instagram → n8n looks up instagram_posts → sends DM +
reply
    ↓
Dashboard shows green across the board 🟢

Next Steps

  • Define reel status states in detail (green/yellow/red thresholds)
  • Sketch Status Dashboard UI
  • Define database schema for hub reel records
  • Get Jenny's feedback on reel list layout (table vs cards)
  • Address assistant access model
  • Build once requirements are locked

Project: Plant Based Southerner Content Hub Planning Session: March 19, 2026 Participants: Travis & Claude