# Marketing Command Center Implementation Plan > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. **Goal:** Build a self-hosted Next.js dashboard that orchestrates a 7-agent AI marketing pipeline, previews generated assets, integrates with Claude Code (Max plan) for feedback, and publishes to Instagram/TikTok via Postiz and Nextdoor via direct API. **Architecture:** Next.js 15 App Router with SQLite (Prisma), NextAuth credentials auth, Server-Sent Events for realtime, Claude Code subprocess spawning (Max plan OAuth, no API key), Postiz for media hosting + social publishing. Everything in Docker Compose. **Tech Stack:** Next.js 15, TypeScript, Tailwind CSS, shadcn/ui, Prisma + SQLite, NextAuth v5, @postiz/node, Docker Compose, Remotion, Playwright, Tavily AI SDK **Reference docs (read before starting any task):** - `FRONTEND_ARCHITECTURE.md` — full technical architecture, DB schema, code samples - `THE_COMPLETE_PICTURE.md` — system overview, data flow, user journey - `AUTONOMOUS_MARKETING_PLAN.md` — 7-agent pipeline design, creative frameworks - `PLATFORM_SPECS.md` — Instagram/TikTok/Nextdoor API specs and dimensions - `BEST_PRACTICES_GUIDE.md` — Anthropic skill authoring guidelines, knowledge file templates --- ## Phase 1: Project Scaffold + Docker ### Task 1: Initialize Next.js Project **Files:** - Create: `package.json` - Create: `tsconfig.json` - Create: `next.config.ts` - Create: `tailwind.config.ts` - Create: `postcss.config.mjs` - Create: `.gitignore` - Create: `app/layout.tsx` - Create: `app/page.tsx` **Step 1: Create the Next.js project** Run: ```bash cd ~/Desktop/code/claude_marketing npx create-next-app@latest . --typescript --tailwind --eslint --app --src-dir=false --import-alias="@/*" --turbopack ``` Expected: Project scaffold created, `package.json` exists **Step 2: Verify it runs** Run: `npm run dev` Expected: Server starts at http://localhost:3000 **Step 3: Commit** ```bash git init git add -A git commit -m "feat: scaffold Next.js 15 project with TypeScript and Tailwind" ``` --- ### Task 2: Add shadcn/ui **Files:** - Modify: `package.json` (new deps) - Create: `components/ui/` (component files) - Create: `lib/utils.ts` - Modify: `tailwind.config.ts` (shadcn theme) **Step 1: Initialize shadcn/ui** Run: ```bash npx shadcn@latest init -d ``` Expected: `components.json` created, `lib/utils.ts` created **Step 2: Add core components we'll need** Run: ```bash npx shadcn@latest add button card input label badge dialog tabs table textarea separator avatar dropdown-menu sheet sidebar toast ``` Expected: Components installed in `components/ui/` **Step 3: Commit** ```bash git add -A git commit -m "feat: add shadcn/ui with core components" ``` --- ### Task 3: Set Up Prisma + SQLite Database **Files:** - Create: `prisma/schema.prisma` - Create: `lib/prisma.ts` **Step 1: Install Prisma** Run: ```bash npm install prisma @prisma/client npx prisma init --datasource-provider sqlite ``` Expected: `prisma/schema.prisma` created with SQLite datasource **Step 2: Write the full schema** Replace `prisma/schema.prisma` with the complete schema from `FRONTEND_ARCHITECTURE.md` lines 68-156. Models: User, Campaign, AgentRun, Asset, ClaudeSession, TrendReport. **Step 3: Create the Prisma client singleton** Create `lib/prisma.ts`: ```typescript import { PrismaClient } from "@prisma/client"; const globalForPrisma = globalThis as unknown as { prisma: PrismaClient }; export const prisma = globalForPrisma.prisma || new PrismaClient(); if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma; ``` **Step 4: Push schema to database** Run: `npx prisma db push` Expected: SQLite file created at `prisma/data/marketing.db` **Step 5: Commit** ```bash git add -A git commit -m "feat: add Prisma with SQLite schema — campaigns, assets, agent runs" ``` --- ### Task 4: Set Up NextAuth Authentication **Files:** - Create: `lib/auth.ts` - Create: `app/api/auth/[...nextauth]/route.ts` - Create: `prisma/seed.ts` - Create: `middleware.ts` - Modify: `package.json` (add deps) **Step 1: Install auth dependencies** Run: `npm install next-auth@beta @auth/prisma-adapter bcryptjs && npm install -D @types/bcryptjs` **Step 2: Create auth config** Create `lib/auth.ts` with NextAuth Credentials provider from `FRONTEND_ARCHITECTURE.md` lines 170-201. JWT session strategy, bcrypt password comparison. **Step 3: Create the API route** Create `app/api/auth/[...nextauth]/route.ts`: ```typescript import { handlers } from "@/lib/auth"; export const { GET, POST } = handlers; ``` **Step 4: Create auth middleware** Create `middleware.ts` that protects all routes except `/login` and `/api/auth`. **Step 5: Create seed script** Create `prisma/seed.ts` from `FRONTEND_ARCHITECTURE.md` lines 206-222. Reads `ADMIN_EMAIL` and `ADMIN_PASSWORD` from env, bcrypt hashes, upserts user. Add to `package.json`: ```json "prisma": { "seed": "npx tsx prisma/seed.ts" } ``` **Step 6: Create .env.local** Create `.env.local`: ``` NEXTAUTH_SECRET=dev-secret-change-in-production-32chars NEXTAUTH_URL=http://localhost:3000 ADMIN_EMAIL=admin@localhost ADMIN_PASSWORD=admin123 ``` **Step 7: Seed the database** Run: `npx prisma db seed` Expected: Admin user created **Step 8: Commit** ```bash git add -A git commit -m "feat: add NextAuth credentials auth with admin seed" ``` --- ### Task 5: Create Login Page **Files:** - Create: `app/(auth)/login/page.tsx` - Create: `app/(auth)/layout.tsx` **Step 1: Create auth layout** Centered layout, no sidebar. Just a card in the middle of the screen. **Step 2: Create login page** Form with email + password inputs, submit button, error state. Uses `signIn("credentials", { ... })` from next-auth. Redirects to `/` on success. **Step 3: Test login flow** Run: `npm run dev` Navigate to http://localhost:3000 → should redirect to `/login` Log in with admin@localhost / admin123 → should redirect to dashboard **Step 4: Commit** ```bash git add -A git commit -m "feat: add login page with credentials auth" ``` --- ### Task 6: Create Dashboard Layout Shell **Files:** - Create: `app/(dashboard)/layout.tsx` - Create: `app/(dashboard)/page.tsx` - Create: `components/app-sidebar.tsx` - Create: `components/header.tsx` **Step 1: Create sidebar navigation** Using shadcn Sidebar component. Navigation items: - Dashboard (home icon) - Campaigns (megaphone icon) - Assets (image icon) - Trends (trending-up icon) - Queue (calendar icon) **Step 2: Create header bar** Shows current page title, user avatar dropdown with sign out. **Step 3: Create dashboard home page** Placeholder cards: "Active Campaigns", "Pending Review", "Published This Week", plus a "New Campaign" button. **Step 4: Verify layout** Run: `npm run dev`, log in, verify sidebar + header + content area render correctly. **Step 5: Commit** ```bash git add -A git commit -m "feat: add dashboard layout with sidebar navigation" ``` --- ### Task 7: Docker Compose Setup **Files:** - Create: `Dockerfile` - Create: `docker-compose.yml` - Create: `.env.example` - Create: `.dockerignore` **Step 1: Create Dockerfile** Multi-stage build from `FRONTEND_ARCHITECTURE.md` lines 478-499. Stages: base (node:20-alpine + Claude CLI + Playwright), deps, builder, runner. Output: standalone Next.js. **Step 2: Create docker-compose.yml** 4 services from `FRONTEND_ARCHITECTURE.md` lines 516-557: app, postiz, postiz-db, redis. 7 named volumes. App mounts pipeline-outputs and pipeline-knowledge. **Step 3: Create .env.example** ```bash TAVILY_API_KEY=tvly-your-key POSTIZ_URL=http://postiz:5000 POSTIZ_API_KEY=your-postiz-key POSTGRES_PASSWORD=secure-password NEXTDOOR_API_TOKEN=your-token NEXTDOOR_ADVERTISER_ID=your-id NEXTAUTH_SECRET=generate-random-32-char-string ADMIN_EMAIL=you@yourdomain.com ADMIN_PASSWORD=your-password ``` **Step 4: Create .dockerignore** ``` node_modules .next prisma/data .env.local ``` **Step 5: Test Docker build** Run: `docker compose build app` Expected: Image builds successfully **Step 6: Commit** ```bash git add -A git commit -m "feat: add Docker Compose with Postiz, Postgres, Redis" ``` --- ## Phase 2: Pipeline Integration ### Task 8: Create Pipeline Directory Structure **Files:** - Create: `pipeline/CLAUDE.md` - Create: `pipeline/knowledge/brand_identity.md` - Create: `pipeline/knowledge/platform_guidelines.md` - Create: `pipeline/knowledge/product_campaign.md` - Create: `pipeline/assets/.gitkeep` - Create: `pipeline/outputs/.gitkeep` - Create: `pipeline/package.json` **Step 1: Create CLAUDE.md** Write the project source-of-truth file following the template in `BEST_PRACTICES_GUIDE.md` Section 2. Declares all 7 agents, folder structure, pipeline execution order, output conventions, safety rules. **Step 2: Create knowledge file templates** Use the templates from `BEST_PRACTICES_GUIDE.md` Section 3. Placeholder content for each — user fills in their actual brand details. **Step 3: Create pipeline package.json** ```json { "name": "marketing-pipeline", "private": true, "dependencies": { "@tavily/core": "^0.7.2" } } ``` **Step 4: Install pipeline deps** Run: `cd pipeline && npm install` **Step 5: Commit** ```bash git add -A git commit -m "feat: add pipeline directory with CLAUDE.md and knowledge templates" ``` --- ### Task 9: Create the 7 Agent Skills **Files:** - Create: `pipeline/skills/trend-scout/SKILL.md` - Create: `pipeline/skills/marketing-research-agent/SKILL.md` - Create: `pipeline/skills/script-writer/SKILL.md` - Create: `pipeline/skills/ad-creative-designer/SKILL.md` - Create: `pipeline/skills/video-ad-producer/SKILL.md` - Create: `pipeline/skills/copywriter-agent/SKILL.md` - Create: `pipeline/skills/distribution-agent/SKILL.md` **Step 1: Write each SKILL.md** Follow the template from `BEST_PRACTICES_GUIDE.md` Section 4. Each skill needs: - YAML frontmatter (name, description with trigger phrases, ≤1024 chars) - CRITICAL: Read Knowledge Files section - Step-by-step workflow - Output convention: `outputs/{task_name}_{date}/{subfolder}/` - Troubleshooting + Quality Checklist Use the agent specs from `AUTONOMOUS_MARKETING_PLAN.md` for each agent's purpose, inputs, outputs, and tools. Use platform dimensions from `PLATFORM_SPECS.md`. Key details per agent: - **trend-scout**: Tavily queries for trending hooks, competitor ads, viral formats. Outputs `trend_report.json`. - **marketing-research-agent**: 5 Tavily queries (trends, competitors, pain points, hooks, viral). Outputs `research_results.json` + `research_brief.md` + `interactive_report.html`. - **script-writer**: Reads research → writes 5 hook variations × 3 platform styles. Outputs to `scripts/` folder. - **ad-creative-designer**: NanoBanana MCP → HTML/CSS layout → Playwright screenshot. Configs for IG 1080x1080, IG Stories 1080x1920, Nextdoor 1200x1200, Nextdoor 1200x628. - **video-ad-producer**: Remotion compositions. Style param: polished (IG), authentic (TikTok), local (Nextdoor). Auto-render to MP4. - **copywriter-agent**: Platform-tuned captions. Outputs `instagram_captions.json`, `tiktok_captions.json`, `nextdoor_posts.json`. - **distribution-agent**: Assembles publish manifest. Gate-protected. Outputs `Publish_{campaign}_{date}.md`. **Step 2: Verify skills are discoverable** Run from `pipeline/` directory: ```bash claude -p "What skills are available?" --allowedTools "Read,Grep,Glob" ``` Expected: All 7 skills listed **Step 3: Commit** ```bash git add -A git commit -m "feat: add 7 agent skills — trend scout through distribution" ``` --- ### Task 10: Set Up Remotion Video Project **Files:** - Create: `pipeline/remotion-ad/` (full Remotion project) **Step 1: Initialize Remotion** Run: ```bash cd pipeline npx create-video@latest remotion-ad --template blank ``` Expected: Remotion project created in `pipeline/remotion-ad/` **Step 2: Install Remotion deps** Run: ```bash cd pipeline/remotion-ad npm install @remotion/google-fonts ``` **Step 3: Verify Remotion renders** Run: `npx remotion render src/index.ts MyComp --output out.mp4` Expected: MP4 file created **Step 4: Commit** ```bash git add -A git commit -m "feat: add Remotion video project for ad generation" ``` --- ### Task 11: Claude Subprocess Spawner (lib/claude.ts) **Files:** - Create: `lib/claude.ts` **Step 1: Write the failing test** Create `__tests__/lib/claude.test.ts`: ```typescript import { runAgentStep, buildCampaignPrompt } from "@/lib/claude"; describe("buildCampaignPrompt", () => { it("builds a prompt from campaign config", () => { const config = { name: "test", platforms: ["instagram", "tiktok"], goal: "app downloads", keyMessage: "test message", }; const prompt = buildCampaignPrompt(config); expect(prompt).toContain("instagram"); expect(prompt).toContain("tiktok"); expect(prompt).toContain("app downloads"); }); }); ``` **Step 2: Run test to verify it fails** Run: `npx jest __tests__/lib/claude.test.ts` Expected: FAIL **Step 3: Implement lib/claude.ts** Create `lib/claude.ts` with: - `buildCampaignPrompt(config)` — turns campaign form data into the prompt string - `runAgentStep(agentName, prompt, cwd)` — spawns `claude -p` as subprocess, returns `{ sessionId, output }` - `launchPipeline(campaignId, prompt, cwd)` — runs all agent steps sequentially, emits SSE events - `pipelineEvents` — EventEmitter for SSE broadcasting - `sendChatMessage(sessionId, message, cwd)` — for the Claude feedback chat Follow the code from `FRONTEND_ARCHITECTURE.md` lines 290-365. Key: each agent runs as its own short `claude -p` call (not one long session) to avoid the Max plan SIGTERM timeout issue. **Step 4: Run test to verify it passes** Run: `npx jest __tests__/lib/claude.test.ts` Expected: PASS (at least buildCampaignPrompt — subprocess tests need integration test) **Step 5: Commit** ```bash git add -A git commit -m "feat: add Claude subprocess spawner with per-agent-step execution" ``` --- ### Task 12: Postiz Client (lib/postiz.ts) **Files:** - Create: `lib/postiz.ts` **Step 1: Install Postiz SDK** Run: `npm install @postiz/node` **Step 2: Write lib/postiz.ts** Implement from `FRONTEND_ARCHITECTURE.md` lines 371-424: - `uploadToPostiz(filePath)` — multipart upload, returns `{ mediaId, publicUrl }` - `pushToPostiz(asset, scheduledAt)` — uploads media + creates scheduled post - `getPostizIntegrations()` — lists connected channels **Step 3: Commit** ```bash git add -A git commit -m "feat: add Postiz client for media upload and scheduling" ``` --- ### Task 13: File Serving API Route **Files:** - Create: `app/api/files/[...path]/route.ts` **Step 1: Implement file server** From `FRONTEND_ARCHITECTURE.md` lines 433-466. Auth-gated, path-traversal protected, serves images/videos/JSON/HTML/markdown from the pipeline outputs directory. **Step 2: Test manually** Place a test image in `pipeline/outputs/test.png`, run dev server, navigate to `/api/files/outputs/test.png` → should see image (after login). **Step 3: Commit** ```bash git add -A git commit -m "feat: add authenticated file serving for pipeline outputs" ``` --- ## Phase 3: Campaign CRUD + Pipeline UI ### Task 14: Campaign List Page **Files:** - Create: `app/(dashboard)/campaigns/page.tsx` - Create: `app/api/campaigns/route.ts` **Step 1: Create API route** `GET /api/campaigns` — returns all campaigns ordered by createdAt desc. `POST /api/campaigns` — creates a new campaign (name, platforms, config). **Step 2: Create the campaigns list page** Table or card grid showing: campaign name, status badge, platforms, created date, "View" button. Plus a "New Campaign" link. **Step 3: Commit** ```bash git add -A git commit -m "feat: add campaign list page with CRUD API" ``` --- ### Task 15: New Campaign Form **Files:** - Create: `app/(dashboard)/campaigns/new/page.tsx` - Create: `components/campaign-form.tsx` **Step 1: Build the campaign form component** Fields: - Campaign name (text input) - Platforms (checkboxes: Instagram, TikTok, Nextdoor) - Campaign goal (select: app downloads, brand awareness, engagement) - Key message (textarea) - Social proof (textarea) - Variations per platform (number input, default 5) - Use latest trend report (checkbox) Submit → POST to `/api/campaigns` → redirect to campaign detail page. **Step 2: Commit** ```bash git add -A git commit -m "feat: add new campaign form" ``` --- ### Task 16: Campaign Detail Page — Pipeline Progress Tab **Files:** - Create: `app/(dashboard)/campaigns/[id]/page.tsx` - Create: `app/(dashboard)/campaigns/[id]/layout.tsx` - Create: `app/api/campaigns/[id]/route.ts` - Create: `app/api/campaigns/[id]/launch/route.ts` - Create: `app/api/campaigns/[id]/stream/route.ts` - Create: `components/pipeline-progress.tsx` - Create: `hooks/usePipelineProgress.ts` **Step 1: Create campaign detail layout** Tab navigation: Pipeline | Assets | Claude Chat. Shows campaign name + status badge in header. "Launch Pipeline" button (only when status is draft). **Step 2: Create launch API route** `POST /api/campaigns/[id]/launch` — calls `launchPipeline()` from `lib/claude.ts`. Creates output directory, builds prompt from campaign config, spawns Claude subprocess. Returns immediately (pipeline runs async). **Step 3: Create SSE stream route** `GET /api/campaigns/[id]/stream` — SSE endpoint from `FRONTEND_ARCHITECTURE.md` lines 231-266. Subscribes to `pipelineEvents` for this campaign ID. **Step 4: Create usePipelineProgress hook** From `FRONTEND_ARCHITECTURE.md` lines 270-285. Connects to SSE endpoint, updates agent status in real-time. **Step 5: Create pipeline progress component** Shows the 7 agent steps as a vertical list. Each step shows: status icon (pending/running/completed/failed), agent name, duration, output summary. Uses the SSE hook for live updates. **Step 6: Wire it all together** Campaign detail page shows pipeline progress. "Launch Pipeline" button triggers launch API → SSE updates flow to UI. **Step 7: Commit** ```bash git add -A git commit -m "feat: add campaign pipeline progress with real-time SSE updates" ``` --- ### Task 17: Campaign Detail — Asset Gallery Tab **Files:** - Create: `app/(dashboard)/campaigns/[id]/assets/page.tsx` - Create: `app/api/assets/route.ts` - Create: `app/api/assets/[id]/route.ts` - Create: `components/asset-gallery.tsx` - Create: `components/asset-card.tsx` **Step 1: Create assets API routes** `GET /api/assets?campaignId=X&type=image&platform=instagram` — filtered asset list. `PATCH /api/assets/[id]` — update status (approve/reject), update metadata. **Step 2: Create asset card component** Shows: thumbnail preview (images inline, video with play button), platform badge, dimensions badge, status badge, hook text preview, caption preview. Approve (green check) and Reject (red X) buttons. Images served via `/api/files/...` route. Videos served via `