--- created: '2026-06-30' path: Sources/Dev project: pbs-n8n-update tags: - pbs - n8n - automation - mysql - docker - python - cloudflare type: project-plan --- # PBS n8n Update — Import & Mock-Harness Bring the live PBS Instagram-automation n8n workflows up on the sandbox test server, driven by synthetic feeds, so their logic can be worked on without the real Instagram/Facebook/Cloudflare/Google-Chat edges. ## Goal Import the 9 production n8n workflows from `petal-power/pbs-n8n` into the existing n8n on the PBS test server (VM 202 / `pbs-wp-test`, 10.0.21.101) and get them **running end-to-end against mocked Instagram feeds**, resolving against the real prod-dump MySQL data, with every outbound message captured to a trackable file sink. **Success condition (the run is done when):** 8 of the 9 workflows — all **except `PBS_Cloudflare_Cache_Warmer_5_days`** — are imported, active, and demonstrably **respond to input and produce output, as close to live production behavior as possible**. That means: a synthetic Instagram feed POSTed to the webhook drives the workflow chain, the MySQL lookups resolve against real `platform_posts`/`pbs_recipes` rows, and the resulting messages land in the sink. The cache-warmer is explicitly excluded from the running condition. ## Locked Decisions - **Target box:** VM 202 `wp-dev-vm` / `pbs-wp-test` (10.0.21.101). Existing n8n at `:5678`, MySQL `wordpress_mysql` with full prod dump. Full verified access reference lives in Trellis thread **`pbs-dev-connect` (#995)** — SSH, n8n API, MySQL, and PVE lifecycle API all tested 2026-06-30. - **Import into the EXISTING n8n.** It already runs **8 live PBSII monitoring/healer/security workflows** (incl. a `PBS: Google Chat Notify` sub). Import the 9 as a **self-contained, isolated cluster**, re-link them only among themselves, and **touch nothing existing**. - **MySQL = real, full prod data.** The IG-reply lookup chain (`platform_posts` → `projects` → `pbs_recipes`) resolves against actual rows (platform_posts ~169, pbs_recipes 100). - **Sink:** one Flask catcher → JSONL (`timestamp`, `sink-label`, `body`). All outbound — Google Chat ×3, Facebook ×2, Cloudflare purge — repointed at it, each **labeled so messages are identifiable**. - **HMAC `x-hash` gate disabled** for the harness — it's proven in production, safe to bypass to inject synthetic events. - **Feeds to mock:** `reel-publish` + `new-comment`. **No subscribe handshake.** - **Import path:** n8n public API with `X-N8N-API-KEY` (key verified working, no expiry; stored in the thread). - **Out of scope for "running":** `PBS_Cloudflare_Cache_Warmer_5_days`. ## Open Items - Exact synthetic payload shapes — to be reversed from each webhook's IF/`set` nodes during Phases A/D. - Name near-collision: existing `PBS: Google Chat Notify (Sub-Workflow)` vs the import's own copy — keep the import isolated, don't repoint onto the live one. - gitea container on 202 is unhealthy (unrelated; flagged in #995). ## Phases **0 — Safety.** `vmstate=1` snapshot of VM 202 (`pre-n8n-import`) via the PVE token *before* touching the box. n8n carries live monitoring, so the snapshot is load-bearing, not tidy. Rollback path: one API call (see #995). **A — Import & re-link.** Push the 9 JSON via the n8n API. Repair every `executeWorkflow` cross-reference (they carry stale n8n internal IDs that won't survive import) — re-linking **only within the imported set**. Disable the `x-hash` node in `insta-webhook` and the matching `stopAndError` gate in `PostPBSUpdate`. Leave the 8 existing workflows untouched. **B — Sink.** Stand up the Flask catcher on 202 → JSONL. Repoint all outbound httpRequest nodes (Google Chat ×3, FB ×2, CF purge) at it, each tagged with a sink label. **C — MySQL wiring.** Point the imported workflows' MySQL credential at `wordpress_mysql:3306` / `pbs_automation` (user `pbs_api`). Verify `platform_posts`, `pbs_recipes`, `instagram_posts_processed`, `instagram_replies`. **D — Mock feeds.** Reverse the exact payload shape from the webhook's IF/`set` nodes, build `reel-publish` + `new-comment` synthetic events, POST to the webhook path. The comment event uses a **real reel ID from `platform_posts`** so the reply lookup resolves recipe→keyword→reply. **E — Observe / prove success.** Fire both feeds; tail the catcher JSONL; confirm `instagram_replies` / `instagram_posts_processed` inserts. Verify the 8 in-scope workflows respond-to-input and produce-output ≈ live. ## Notes - Workflows cloned to `~/dev-projects/pbs-n8n` on herbys-dev — 9 exports, single commit. Cluster shape: Instagram pipeline (insta-webhook + 3 subs), Cloudflare cache (purge + warmer), chat/notify (PostPBSUpdate + 2 senders). - The stale-internal-ID cross-references are the #1 thing that breaks on import. - Exports carry **live secrets** (Google Chat API keys, CF zone id) — fine for a throwaway harness, flagged. - **Execution model:** a worker on herbys-dev SSHing into 202 does the import/sink/feed work on the box. - **Deliverables:** working 8-workflow set in n8n · the catcher service · the mock-feed injector scripts · a short runbook (how to fire a feed, where to watch output). - **Unattended tier:** version-warrior (done = version running). Run contract recorded in the Trellis thread before going heads-down.