# Content Pipeline v2 — Integration Test Guide **Date:** 2026-04-22 **Status:** Ready for testing **Prerequisites:** Backend running, Gaming PC online --- ## Test 1: API Connectivity **Purpose:** Verify all endpoints respond ```bash cd /home/hoffmann_admin/.openclaw/workspace-socrates/hoffdesk-api # Start the API (if not running) python -m uvicorn main:app --host 127.0.0.1 --port 8000 --reload # In another terminal, test connectivity curl -H "X-Admin-Token: hoffdesk-admin-2025" \ http://127.0.0.1:8000/api/v1/content/briefs # Expected: {"briefs": [], "count": 0} or list of existing briefs ``` **✅ Pass:** HTTP 200 with JSON response **❌ Fail:** Connection refused, 401 (check token), 500 (check logs) --- ## Test 2: Style Reference Endpoint **Purpose:** Verify dns-night.json loads correctly ```bash curl -H "X-Admin-Token: hoffdesk-admin-2025" \ http://127.0.0.1:8000/api/v1/content/style-references # Expected: [{"slug": "dns-night", "title": "...", "excerpt": "..."}] ``` **✅ Pass:** Returns style example with correct metadata **❌ Fail:** Empty array (check file path), 404 (check endpoint) --- ## Test 3: Create Brief **Purpose:** Verify brief creation and validation ```bash # Create test brief curl -X POST \ -H "Content-Type: application/json" \ -H "X-Admin-Token: hoffdesk-admin-2025" \ http://127.0.0.1:8000/api/v1/content/briefs \ -d '{ "title": "Test: The Morning I Broke Coffee", "struggle_angle": "I broke the coffee maker at 6 AM when Aundrea needed caffeine", "origin_story": "It was Monday morning. Aundrea was already running late. I was 'just cleaning' the coffee maker...", "attempts": [ {"attempt": "Took it apart to clean", "why_failed": "Couldn't remember how to reassemble"}, {"attempt": "Watched YouTube tutorial", "why_failed": "Our model was different"} ], "the_moment": "I found the broken plastic piece under the sink. It had been broken the whole time.", "the_fix": "Bought a new coffee maker on Amazon Same-Day. Delivered by 9 AM.", "reflection": "Never disassemble critical appliances before morning coffee. Also: always have backup caffeine.", "style_reference": "dns-night", "target_length": 800 }' # Expected: {"brief_id": "...", "status": "draft", "created_at": "..."} # Save the brief_id for next test ``` **✅ Pass:** Returns brief_id, status "draft" **❌ Fail:** 400 validation error (check required fields), 500 (server error) --- ## Test 4: Submit for Approval **Purpose:** Verify Telegram notification triggers ```bash # Replace BRIEF_ID with actual ID from Test 3 curl -X POST \ -H "X-Admin-Token: hoffdesk-admin-2025" \ http://127.0.0.1:8000/api/v1/content/briefs/BRIEF_ID/submit # Expected: {"success": true, "status": "submitted"} ``` **✅ Pass:** Status changes to "submitted", you receive Telegram DM **❌ Fail:** 400 (brief not complete), Telegram error (check token) **Check Telegram:** You should receive DM: > "New brief: Test: The Morning I Broke Coffee — Approve? [Yes] [No] [Edit]" --- ## Test 5: Approve Brief **Purpose:** Verify generation triggers ```bash # Option A: Click [Yes] in Telegram (recommended) # Option B: API call curl -X POST \ -H "X-Admin-Token: hoffdesk-admin-2025" \ http://127.0.0.1:8000/api/v1/content/briefs/BRIEF_ID/approve # Expected: {"success": true, "status": "generating"} ``` **✅ Pass:** Status changes to "generating" **❌ Fail:** 403 (not authorized), Gaming PC unavailable --- ## Test 6: Monitor Generation **Purpose:** Verify generation completes ```bash # Poll every 10 seconds curl -H "X-Admin-Token: hoffdesk-admin-2025" \ http://127.0.0.1:8000/api/v1/content/briefs/BRIEF_ID # Watch status: generating → complete ``` **Expected timeline:** - T+0s: Approved, generation started - T+60-120s: Generation completes - T+120s: Status "complete", output available **✅ Pass:** Status becomes "complete", struggle_score present **❌ Fail:** Stuck on "generating" (check Gaming PC), timeout (check model) --- ## Test 7: View Output **Purpose:** Verify content generated with struggle-first voice ```bash curl -H "X-Admin-Token: hoffdesk-admin-2025" \ http://127.0.0.1:8000/api/v1/content/briefs/BRIEF_ID/output # Expected: { # "content": "# Test: The Morning...", # "html": "

Test: The Morning...

...", # "struggle_score": 82, # "interpretation": "Strong struggle narrative...", # "checks": {...} # } ``` **✅ Pass:** Content present, struggle_score >75, first-person voice **❌ Fail:** Low score (<50), generic tone, missing voice markers --- ## Test 8: End-to-End Live Script **Purpose:** Full pipeline test with actual generation ```bash cd /home/hoffmann_admin/.openclaw/workspace-socrates/hoffdesk-api # Run live test (creates job, generates content, saves output) python test_pipeline_live.py "How I learned to stop worrying and love local DNS" # Check Gaming PC only python test_pipeline_live.py --check-only ``` **Expected output:** ``` ✅ Gaming PC available Created job: uuid 📄 TITLE: [generated title] 📝 WORD COUNT: ~1500 ⏱️ READING TIME: 6 min ✅ COMPLIANCE: replacements_made: 2, warnings: [] ``` **✅ Pass:** Complete content, word count reasonable, saved to JSON **❌ Fail:** Gaming PC unavailable, generation timeout, empty output --- ## Test 9: Web UI — StruggleBriefForm **Purpose:** Verify frontend components render **Steps:** 1. Open browser to `http://127.0.0.1:8000/admin/pipeline/new` 2. Verify: 4-step wizard visible 3. Fill Step 1 (title, struggle_angle, origin_story) 4. Click Continue → Step 2 5. Add 2 attempts, click Continue → Step 3 6. Fill moment/fix/reflection, click Continue → Step 4 7. Verify VoiceChecklist shows all 6 items 8. Check boxes → Submit enabled 9. Submit → "Brief Submitted" confirmation **✅ Pass:** Form validates, wizard advances, checklist gates submit, API success **❌ Fail:** 404 (templates not served), JavaScript error (check console), API 401/500 --- ## Test 10: Web UI — BriefReview **Purpose:** Verify approval UI and content preview **Steps:** 1. After Test 4 (submitted brief), open `/admin/pipeline/brief/BRIEF_ID` 2. Verify: Status shows "Submitted — Awaiting Matt's approval" 3. Verify: [Approve & Generate] and [Reject] buttons visible 4. Click [Approve & Generate] 5. Verify: "Generating..." state appears 6. Wait 60-120s (or poll status) 7. Verify: Status "Complete", struggle score visible 8. Verify: Side-by-side preview (brief left, generated right) 9. Verify: [Create Post from Output] button **✅ Pass:** Approval triggers generation, score displays, preview renders **❌ Fail:** Approval fails, generation stuck, preview missing --- ## Success Criteria | Test | Required | Score | |------|----------|-------| | API connectivity | ✅ | — | | Brief creation | ✅ | — | | Telegram approval | ✅ | — | | Generation | ✅ | — | | **Struggle score** | ✅ | **≥75** | | First-person voice | ✅ | Detected | | **Side-by-side preview** | ✅ | Renders | | **3 successful posts** | ✅ | All score >75 | --- ## Troubleshooting | Symptom | Likely Cause | Fix | |---------|--------------|-----| | 401 Unauthorized | Token mismatch | Check `X-Admin-Token: hoffdesk-admin-2025` | | Gaming PC unavailable | Tailscale down | Check `ping matt-pc.tail864e81.ts.net` | | Generation timeout | phi4:14b not loaded | `curl http://matt-pc.tail864e81.ts.net:11434/api/tags` | | No Telegram DM | Bot token missing | Check `blog/notifications/telegram.py` config | | Low struggle score | Prompt injection failed | Verify `dns-night.json` loads, check logs | | Template 404 | Static files not served | Check `app.mount("/blog/static", ...)` | --- ## Quick Health Check ```bash cd /home/hoffmann_admin/.openclaw/workspace-socrates/hoffdesk-api # 1. API up? curl -s http://127.0.0.1:8000/health || echo "❌ API down" # 2. Gaming PC reachable? curl -s http://matt-pc.tail864e81.ts.net:11434/api/tags | head -1 || echo "❌ Gaming PC unreachable" # 3. Style example loads? curl -s -H "X-Admin-Token: hoffdesk-admin-2025" \ http://127.0.0.1:8000/api/v1/content/style-references | grep "dns-night" || echo "❌ Style not loaded" echo "✅ All systems ready for testing" ``` --- **Ready to begin?** Start with Test 1 (API connectivity), or jump to Test 8 (live script) for immediate feedback.