195 lines
6.0 KiB
Markdown
195 lines
6.0 KiB
Markdown
---
|
||
project: content-hub-phase5-planning
|
||
type: project-plan
|
||
status: active
|
||
tags:
|
||
- pbs
|
||
- flask
|
||
- mysql
|
||
- n8n
|
||
- instagram
|
||
- automation
|
||
- docker
|
||
created: 2026-03-19
|
||
updated: 2026-03-19
|
||
path: PBS/Tech/Projects/
|
||
---
|
||
|
||
# PBS Content Hub — Phase 5 Planning Decisions
|
||
|
||
## Context
|
||
|
||
Phases 1–4 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* |