# Architecture Research: Content Automation Pipeline

**Researched:** 2026-04-05

## System Overview

```
┌─────────────────────────────────────────────────────────────────┐
│                        n8n (Orchestration)                       │
│                                                                   │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐           │
│  │ AI Idea  │ │ News/RSS │ │ Client   │ │ Market   │           │
│  │ Generator│ │ Scraper  │ │ Pipeline │ │ Intel    │           │
│  └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘           │
│       │             │            │             │                  │
│       └─────────────┴────────────┴─────────────┘                 │
│                          │                                        │
│                    ┌─────▼─────┐                                 │
│                    │  Content  │                                  │
│                    │   Pool    │◄── NocoDB                       │
│                    └─────┬─────┘                                 │
│                          │                                        │
│                    ┌─────▼─────┐                                 │
│                    │  Script   │                                  │
│                    │ Generator │──── Claude API                   │
│                    └─────┬─────┘                                 │
│                          │                                        │
│                    ┌─────▼─────┐                                 │
│                    │  Human    │                                  │
│                    │  Review   │◄── NocoDB UI                    │
│                    └─────┬─────┘                                 │
│                          │                                        │
│                    ┌─────▼─────┐                                 │
│                    │  Video    │                                  │
│                    │ Generate  │──── HeyGen API                  │
│                    └─────┬─────┘                                 │
│                          │                                        │
│                    ┌─────▼─────┐                                 │
│                    │  Post-    │                                  │
│                    │Production │──── Creatomate API               │
│                    └─────┬─────┘                                 │
│                          │                                        │
│                    ┌─────▼─────┐                                 │
│                    │  Client   │                                  │
│                    │ Approval  │◄── NocoDB UI                    │
│                    └─────┬─────┘                                 │
│                          │                                        │
│                    ┌─────▼─────┐                                 │
│                    │ Publish   │                                  │
│                    │ Instagram │──── Meta Graph API               │
│                    └─────┬─────┘                                 │
│                          │                                        │
│                    ┌─────▼─────┐                                 │
│                    │ Analytics │                                  │
│                    │ Tracker   │──── Instagram Insights API       │
│                    └───────────┘                                  │
└─────────────────────────────────────────────────────────────────┘
```

## Component Boundaries

### 1. n8n Workflows (Orchestration Layer)

**Separate workflows per concern** (not one monolithic workflow):

| Workflow | Trigger | Purpose |
|----------|---------|---------|
| `idea-generator-ai` | Cron (daily 8am) | AI generates content ideas from client profile |
| `idea-generator-news` | Cron (every 6h) | Pull RSS, filter, score, insert ideas |
| `idea-generator-market` | Cron (weekly Mon) | Pull Destatis/Bundesbank data, create angles |
| `idea-generator-client` | NocoDB webhook | Client adds listing -> auto-create content idea |
| `script-generator` | Manual trigger / n8n trigger | Take approved idea -> Claude API -> draft script |
| `video-generator` | n8n trigger (after script approval) | Script -> HeyGen API -> wait for render -> download |
| `post-production` | n8n trigger (after video ready) | Raw video -> Creatomate template -> branded video |
| `review-notifier` | NocoDB webhook (status change) | Notify team/client when content needs review |
| `publisher` | Cron (scheduled times) | Check for approved+scheduled content -> publish |
| `token-refresh` | Cron (every 50 days) | Refresh Instagram long-lived token |
| `analytics-collector` | Cron (daily) | Pull Instagram Insights for posted content |

**Why separate:** Each workflow can fail independently, be debugged independently, and be version-controlled independently. Monolithic workflows become unmaintainable.

### 2. NocoDB Schema (Data Layer + Client UI)

**Tables:**

```
clients
├── id (auto)
├── name (text)
├── brand_kit_path (text) — path to brand assets on VPS
├── instagram_account_id (text)
├── instagram_token (text, hidden)
├── avatar_configs (JSON) — HeyGen avatar IDs
├── content_strategy (JSON) — categories, split, tone
└── active (boolean)

content_ideas
├── id (auto)
├── client_id (link -> clients)
├── source (single select: ai_generator | news | client | market)
├── category (single select: property | market_insight | company | educational)
├── title (text) — brief idea title
├── description (long text) — full idea description
├── data_points (JSON) — any stats/numbers to include
├── source_url (URL) — original article/data source
├── relevance_score (number 0-10) — AI-assigned
├── status (single select: new | selected | scripted | rejected | duplicate)
├── created_at (date)
└── content_hash (text) — for dedup checking

scripts
├── id (auto)
├── idea_id (link -> content_ideas)
├── client_id (link -> clients)
├── avatar (single select: owner | employee)
├── format (single select: talking_head | avatar_visuals | avatar_broll)
├── instagram_format (single select: reel | feed | story)
├── script_text (long text) — the full German script
├── caption (long text) — Instagram caption
├── hashtags (text)
├── hook (text) — first 3 seconds
├── cta (text) — call to action
├── visual_notes (long text) — what visuals to show alongside
├── duration_seconds (number)
├── internal_status (single select: draft | internal_review | approved | needs_changes)
├── client_status (single select: pending | approved | needs_changes)
├── internal_reviewer (text)
├── client_notes (long text)
└── approved_at (date)

generated_videos
├── id (auto)
├── script_id (link -> scripts)
├── client_id (link -> clients)
├── heygen_job_id (text) — for polling/webhook
├── raw_video_path (text) — unbranded video file
├── branded_video_path (text) — post-production video file
├── thumbnail_path (text)
├── creatomate_render_id (text)
├── status (single select: generating | raw_ready | branding | branded_ready | failed)
├── generation_cost (number) — track API credits used
├── error_message (text)
└── created_at (date)

published_posts
├── id (auto)
├── video_id (link -> generated_videos)
├── client_id (link -> clients)
├── instagram_post_id (text)
├── instagram_format (single select: reel | feed | story)
├── published_at (datetime)
├── scheduled_for (datetime)
├── caption (long text)
├── hashtags (text)
├── status (single select: scheduled | published | failed)
└── publish_error (text)

analytics
├── id (auto)
├── post_id (link -> published_posts)
├── client_id (link -> clients)
├── collected_at (date)
├── likes (number)
├── comments (number)
├── shares (number)
├── saves (number)
├── reach (number)
├── impressions (number)
├── engagement_rate (number) — calculated
└── category (single select) — from content_ideas for performance analysis

content_calendar
├── id (auto)
├── client_id (link -> clients)
├── slot_date (date)
├── slot_time (time)
├── day_of_week (single select)
├── category (single select) — recurring theme
├── assigned_content_id (link -> scripts or generated_videos)
└── status (single select: open | assigned | published)
```

### 3. File Storage (VPS)

```
/var/www/neg-marketing/
├── brand-kits/
│   └── neg/
│       ├── logo.svg
│       ├── logo-white.svg
│       ├── fonts/
│       ├── colors.json
│       └── templates/        — Creatomate template configs
├── avatars/
│   └── neg/
│       ├── owner-source.mp4  — original recording
│       └── employee-source.mp4
├── generated/
│   └── neg/
│       └── 2026-04/
│           ├── raw/          — HeyGen output
│           ├── branded/      — Creatomate output (final)
│           └── thumbnails/
├── assets/
│   └── neg/
│       ├── properties/       — property photos from client
│       ├── b-roll/           — location footage
│       └── music/            — royalty-free tracks
└── temp/                     — processing workspace
```

### 4. Data Flow

```
[Content Sources] ──► [NocoDB: content_ideas] ──► [Human selects]
                                                        │
                                                        ▼
[Claude API] ◄── [n8n: script-generator] ──► [NocoDB: scripts]
                                                        │
                                              [Human edits/approves]
                                                        │
                                              [Client approves]
                                                        │
                                                        ▼
[HeyGen API] ◄── [n8n: video-generator] ──► [VPS: raw video]
                                                        │
                                                        ▼
[Creatomate API] ◄── [n8n: post-production] ──► [VPS: branded video]
                                                        │
                                                        ▼
                  [n8n: publisher] ──► [Instagram via Meta Graph API]
                                                        │
                                                        ▼
                  [n8n: analytics] ──► [NocoDB: analytics]
```

### 5. Review/Approval Flow via NocoDB

NocoDB status fields drive the workflow. n8n watches for status changes via webhooks:

```
Script created (draft)
  → n8n notifies internal reviewer
  → Reviewer opens NocoDB, reads script, sets status:
    - "approved" → n8n triggers client notification
    - "needs_changes" → n8n notifies script author
  → Client opens NocoDB, reads script, sets status:
    - "approved" → n8n triggers video generation
    - "needs_changes" → n8n notifies team with client notes
```

**No custom review UI needed.** NocoDB's form view + gallery view provides a clean approval interface. Client sees only their content via filtered views.

## Suggested Build Order

```
Phase 1: Foundation
├── NocoDB setup (tables, views, API)
├── n8n setup (base configuration)
├── File storage structure on VPS
├── Brand kit upload and template design
└── Meta Developer App + Instagram Business setup

Phase 2: Content Generation Pipeline
├── AI Idea Generator workflow (n8n + Claude API)
├── News/RSS ingestion workflow
├── Client input pipeline (NocoDB webhook)
├── Content dedup logic
└── Script generation workflow (n8n + Claude API)

Phase 3: Video Production Pipeline
├── HeyGen avatar creation from recordings
├── Video generation workflow (n8n + HeyGen API)
├── Creatomate branded template design
├── Post-production workflow (n8n + Creatomate)
└── Review/approval workflow

Phase 4: Publishing + Analytics
├── Instagram publishing workflow
├── Scheduling system (content calendar + cron)
├── Analytics collection workflow
├── Token refresh workflow
└── Performance feedback into content strategy
```

**Dependencies:**
- Phase 2 depends on Phase 1 (NocoDB + n8n must exist)
- Phase 3 depends on Phase 2 (need scripts to generate videos) + Phase 1 (brand templates)
- Phase 4 depends on Phase 3 (need videos to publish)
- Content generators (Phase 2) can partially overlap with Phase 3

---
*Researched: 2026-04-05*
