Files
GEOAgentArticleOptimizer/docs/superpowers/plans/2026-06-16-geo-agent-article-optimizer-mvp.md

18 KiB

GEO Agent Article Optimizer MVP Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Build the local MVP described in docs/superpowers/specs/2026-06-16-geo-agent-article-optimizer-design.md: paste an article, confirm facts, optimize under constraints, run QA gates, and export Markdown, Word, and JSON.

Architecture: Use a single Next.js application with server-side route handlers for workflow execution and SQLite persistence. Keep each workflow node as a focused TypeScript module so fact extraction, optimization, QA, rewriting, and exporting can be tested independently.

Tech Stack: Node.js 22, npm, Next.js, React, TypeScript, Tailwind CSS, better-sqlite3, zod, OpenAI-compatible SDK, docx, Vitest, Playwright.


Environment Summary

The current device is suitable for development:

  • macOS 26.3 on Apple M4.
  • 16 GB memory, 10 CPU cores.
  • Node.js v22.22.3, npm 10.9.8.
  • SQLite CLI 3.51.0.
  • Git, curl, jq, and Xcode command line tools are available.

Missing but required or recommended:

  • Required project npm dependencies listed below.
  • One LLM credential in .env.local, preferably OPENAI_API_KEY.
  • Optional pnpm, yarn, bun, pandoc, and LibreOffice are not needed for this MVP.

Dependency Set

Runtime dependencies:

npm install next react react-dom better-sqlite3 zod openai docx nanoid

Development dependencies:

npm install -D typescript @types/node @types/react @types/react-dom @types/better-sqlite3 eslint eslint-config-next prettier vitest @vitejs/plugin-react jsdom playwright

Environment file:

cat > .env.local <<'EOF'
OPENAI_API_KEY=replace-with-real-key
OPENAI_MODEL=gpt-4.1-mini
APP_DATA_DIR=./data
EOF

The implementation must never commit .env.local, data/app.db, or generated export files.

Planned File Structure

Create or modify these files:

package.json
tsconfig.json
next.config.ts
eslint.config.mjs
postcss.config.mjs
tailwind.config.ts
vitest.config.ts
.gitignore
.env.example
data/.gitkeep
samples/articles/*.json
src/app/globals.css
src/app/layout.tsx
src/app/page.tsx
src/app/api/jobs/route.ts
src/app/api/jobs/[jobId]/confirm-fact-card/route.ts
src/app/api/jobs/[jobId]/optimize/route.ts
src/app/api/jobs/[jobId]/exports/[fileName]/route.ts
src/components/article-input-form.tsx
src/components/fact-card-editor.tsx
src/components/optimized-preview.tsx
src/components/qa-report-panel.tsx
src/lib/db/connection.ts
src/lib/db/schema.ts
src/lib/db/repositories.ts
src/lib/domain/types.ts
src/lib/domain/validation.ts
src/lib/llm/client.ts
src/lib/llm/prompts.ts
src/lib/workflow/input-normalizer.ts
src/lib/workflow/fact-extractor.ts
src/lib/workflow/article-optimizer.ts
src/lib/workflow/quality-inspector.ts
src/lib/workflow/targeted-rewriter.ts
src/lib/workflow/exporter.ts
src/lib/workflow/orchestrator.ts
src/lib/workflow/__tests__/*.test.ts

Responsibilities:

  • src/app/page.tsx: single-screen local workflow UI.
  • src/app/api/**: server endpoints for create, confirm, optimize, and download actions.
  • src/components/**: focused UI components for the four page areas in the spec.
  • src/lib/domain/**: shared TypeScript types and Zod schemas.
  • src/lib/db/**: SQLite connection, schema initialization, and repository functions.
  • src/lib/llm/**: model client and prompts. All model calls are isolated here.
  • src/lib/workflow/**: one module per internal agent node from the spec.
  • samples/articles/**: five required risk samples for testing.

Task 1: Scaffold The Application

Files:

  • Create: package.json

  • Create: tsconfig.json

  • Create: next.config.ts

  • Create: eslint.config.mjs

  • Create: postcss.config.mjs

  • Create: tailwind.config.ts

  • Create: vitest.config.ts

  • Modify: .gitignore

  • Create: .env.example

  • Create: src/app/layout.tsx

  • Create: src/app/globals.css

  • Create: src/app/page.tsx

  • Create: data/.gitkeep

  • Step 1: Initialize npm metadata

    Use npm init -y, then set scripts and package metadata:

    {
      "name": "geo-agent-article-optimizer",
      "version": "0.1.0",
      "private": true,
      "scripts": {
        "dev": "next dev",
        "build": "next build",
        "start": "next start",
        "lint": "next lint",
        "test": "vitest run",
        "test:watch": "vitest"
      }
    }
    
  • Step 2: Install dependencies

    Run:

    npm install next react react-dom better-sqlite3 zod openai docx nanoid
    npm install -D typescript @types/node @types/react @types/react-dom @types/better-sqlite3 eslint eslint-config-next prettier vitest @vitejs/plugin-react jsdom playwright
    

    Expected: package-lock.json is created and npm ls --depth=0 shows the listed packages.

  • Step 3: Add environment and ignore rules

    .env.example:

    OPENAI_API_KEY=
    OPENAI_MODEL=gpt-4.1-mini
    APP_DATA_DIR=./data
    

    .gitignore must include:

    node_modules/
    .next/
    .env
    .env.*
    !.env.example
    data/app.db
    data/exports/
    
  • Step 4: Add initial Next.js app shell

    src/app/layout.tsx:

    import "./globals.css";
    
    export const metadata = {
      title: "GEO Agent Article Optimizer",
      description: "Local article optimization and QA workflow",
    };
    
    export default function RootLayout({ children }: { children: React.ReactNode }) {
      return (
        <html lang="zh-CN">
          <body>{children}</body>
        </html>
      );
    }
    

    src/app/page.tsx initially renders a heading and four empty sections: article input, fact card, optimized result, and quality report.

  • Step 5: Verify scaffold

    Run:

    npm run build
    npm test
    

    Expected: build succeeds. Test command may report no test files until Task 2 adds tests.

  • Step 6: Commit scaffold

    git add package.json package-lock.json tsconfig.json next.config.ts eslint.config.mjs postcss.config.mjs tailwind.config.ts vitest.config.ts .gitignore .env.example data/.gitkeep src/app
    git commit -m "chore: scaffold local optimizer app"
    

Task 2: Define Domain Types And Validation

Files:

  • Create: src/lib/domain/types.ts

  • Create: src/lib/domain/validation.ts

  • Test: src/lib/domain/__tests__/validation.test.ts

  • Step 1: Write validation tests

    Cover:

    • Valid article input accepts title, body, image descriptions or links, platform, and user instructions.
    • Fact card with unresolved uncertain_items is not ready for optimization.
    • Confirmed fact card with empty company full name is invalid.
    • QA report accepts only pass, warn, or fail.
  • Step 2: Implement shared enums and interfaces

    Include:

    • PublishPlatform: official_site, media_article, comparison_review, recommendation_list.
    • CheckStatus: pass, warn, fail.
    • QualityRuleId: the 10 rule IDs from the spec.
    • ArticleInput, ImageInput, CandidateFactCard, ConfirmedFactCard, OptimizedArticle, QaReport, QaCheck.
  • Step 3: Implement Zod schemas

    Add schemas matching the interfaces. Use .min(1) for required user text fields and .array(...).default([]) for list fields.

  • Step 4: Verify

    Run:

    npm test -- src/lib/domain/__tests__/validation.test.ts
    

    Expected: all validation tests pass.

  • Step 5: Commit

    git add src/lib/domain
    git commit -m "feat: define optimizer domain model"
    

Task 3: Add SQLite Persistence

Files:

  • Create: src/lib/db/connection.ts

  • Create: src/lib/db/schema.ts

  • Create: src/lib/db/repositories.ts

  • Test: src/lib/db/__tests__/repositories.test.ts

  • Step 1: Write repository tests

    Use a temporary SQLite database path. Test:

    • Schema initialization creates all tables.
    • A brand template can be inserted and fetched.
    • An article job can be inserted and fetched.
    • A confirmed fact card can be saved for a job.
    • Optimized article revisions increment correctly.
    • QA report can be saved and fetched by job/revision.
  • Step 2: Implement schema

    Tables:

    • brand_templates
    • article_jobs
    • fact_cards
    • optimized_articles
    • qa_reports

    Store structured arrays and nested objects as JSON text. Add created_at and updated_at timestamps where relevant.

  • Step 3: Implement repository functions

    Required functions:

    • createBrandTemplate
    • listBrandTemplates
    • getBrandTemplate
    • createArticleJob
    • getArticleJob
    • saveFactCard
    • getFactCard
    • saveOptimizedArticle
    • getLatestOptimizedArticle
    • saveQaReport
    • getLatestQaReport
  • Step 4: Verify

    npm test -- src/lib/db/__tests__/repositories.test.ts
    
  • Step 5: Commit

    git add src/lib/db
    git commit -m "feat: add sqlite persistence"
    

Task 4: Implement Workflow Nodes With Deterministic Fallbacks

Files:

  • Create: src/lib/llm/client.ts

  • Create: src/lib/llm/prompts.ts

  • Create: src/lib/workflow/input-normalizer.ts

  • Create: src/lib/workflow/fact-extractor.ts

  • Create: src/lib/workflow/article-optimizer.ts

  • Create: src/lib/workflow/quality-inspector.ts

  • Create: src/lib/workflow/targeted-rewriter.ts

  • Create: src/lib/workflow/orchestrator.ts

  • Test: src/lib/workflow/__tests__/*.test.ts

  • Step 1: Write node tests before implementation

    Tests must cover:

    • InputNormalizer trims whitespace and converts image lines into image inputs.
    • FactExtractor places missing or conflicting company facts into uncertain_items.
    • ArticleOptimizer refuses to add claims outside the confirmed fact card.
    • QualityInspector returns the 10 required checks.
    • Hard failures are produced for incomplete company names, hallucinated numeric claims, industry drift, and conflicting experience years.
    • TargetedRewriter edits only the failing target area.
    • Orchestrator stops after two failed rewrite rounds.
  • Step 2: Add LLM abstraction

    src/lib/llm/client.ts exports:

    • generateJson<T>(input) for structured JSON responses.
    • generateText(input) for prose responses.
    • isLlmConfigured() for UI/API warnings.

    If no API key exists, workflow modules use deterministic local fallbacks so tests and the UI remain usable.

  • Step 3: Implement workflow nodes

    Implement the modules from the spec exactly:

    • normalizeInput
    • extractCandidateFactCard
    • optimizeArticle
    • inspectQuality
    • rewriteFailedSections
    • runOptimizationWorkflow

    Each node accepts typed input and returns typed output. No node reads from the database directly.

  • Step 4: Verify

    npm test -- src/lib/workflow
    
  • Step 5: Commit

    git add src/lib/llm src/lib/workflow
    git commit -m "feat: implement article optimization workflow"
    

Task 5: Add API Routes

Files:

  • Create: src/app/api/jobs/route.ts

  • Create: src/app/api/jobs/[jobId]/confirm-fact-card/route.ts

  • Create: src/app/api/jobs/[jobId]/optimize/route.ts

  • Create: src/app/api/jobs/[jobId]/exports/[fileName]/route.ts

  • Test: src/app/api/__tests__/jobs.test.ts

  • Step 1: Write route tests

    Test:

    • POST /api/jobs validates input, creates a job, and returns a candidate fact card.
    • POST /api/jobs/:jobId/confirm-fact-card rejects unresolved uncertain items.
    • POST /api/jobs/:jobId/optimize rejects jobs without confirmed fact cards.
    • Successful optimize returns optimized article and QA report.
    • Export route rejects unknown filenames.
  • Step 2: Implement routes

    Route behavior:

    • Create job: normalize input, extract candidate fact card, persist job.
    • Confirm fact card: validate user-confirmed facts, save brand template, save fact card.
    • Optimize: run orchestrator, save optimized revision, save QA report.
    • Export download: return existing generated file with correct content type.
  • Step 3: Verify

    npm test -- src/app/api
    npm run build
    
  • Step 4: Commit

    git add src/app/api
    git commit -m "feat: expose optimizer workflow api"
    

Task 6: Build The Local Web UI

Files:

  • Modify: src/app/page.tsx

  • Create: src/components/article-input-form.tsx

  • Create: src/components/fact-card-editor.tsx

  • Create: src/components/optimized-preview.tsx

  • Create: src/components/qa-report-panel.tsx

  • Modify: src/app/globals.css

  • Step 1: Build Article Input form

    Include fields:

    • Title.
    • Body.
    • Image description or image link, one per line.
    • Target platform.
    • User instructions.

    Submit calls POST /api/jobs.

  • Step 2: Build Fact Card editor

    Render all fact-card fields from the spec. Disable optimization while uncertain_items is non-empty. Save calls POST /api/jobs/:jobId/confirm-fact-card.

  • Step 3: Build Optimize action and preview

    Optimize button calls POST /api/jobs/:jobId/optimize. Preview displays title, summary, body markdown, image suggestions, changed sections, and content requiring user confirmation.

  • Step 4: Build QA report panel

    Show each gate as pass, warn, or fail with evidence, reason, suggested fix, and target agent. Hard failures must visibly block export.

  • Step 5: Build export buttons

    Enable downloads for:

    • optimized.md
    • optimized.docx
    • qa_report.json

    Disable export when QA has hard failures.

  • Step 6: Verify manually

    Run:

    npm run dev
    

    Open http://localhost:3000, paste one sample article, confirm the fact card, optimize, review QA, and download files.

  • Step 7: Commit

    git add src/app src/components
    git commit -m "feat: build local optimizer interface"
    

Task 7: Implement Exporter

Files:

  • Create: src/lib/workflow/exporter.ts

  • Test: src/lib/workflow/__tests__/exporter.test.ts

  • Step 1: Write exporter tests

    Test:

    • Markdown includes optimized title, summary, body, and image suggestions.
    • JSON export serializes the QA report.
    • Word export creates a .docx buffer with nonzero length.
    • Exporter writes all three files under data/exports/job_xxx/.
  • Step 2: Implement export functions

    Functions:

    • renderOptimizedMarkdown
    • renderQaReportJson
    • renderOptimizedDocx
    • writeJobExports

    Use the docx package for the Word document. Do not use pandoc or LibreOffice.

  • Step 3: Integrate exporter with optimize route

    After each successful optimization run, write the three export files and persist paths in the job result.

  • Step 4: Verify

    npm test -- src/lib/workflow/__tests__/exporter.test.ts
    npm run build
    
  • Step 5: Commit

    git add src/lib/workflow/exporter.ts src/lib/workflow/__tests__/exporter.test.ts src/app/api/jobs
    git commit -m "feat: export optimized article files"
    

Task 8: Add Minimum Test Samples And End-To-End Checks

Files:

  • Create: samples/articles/industry-drift.json

  • Create: samples/articles/company-name.json

  • Create: samples/articles/title-quality.json

  • Create: samples/articles/experience-conflict.json

  • Create: samples/articles/image-text-mismatch.json

  • Create: tests/e2e/mvp.spec.ts

  • Step 1: Add five sample articles

    Each JSON file includes:

    • name
    • input
    • expectedHardFailures
    • expectedWarnings
  • Step 2: Add Playwright smoke test

    Test the happy path:

    • Load page.
    • Submit article input.
    • Edit and confirm fact card.
    • Run optimize.
    • See QA report.
    • Download Markdown, Word, and JSON links are present when hard failures are absent.
  • Step 3: Verify full suite

    npm test
    npm run build
    npx playwright test
    
  • Step 4: Commit

    git add samples tests package.json package-lock.json
    git commit -m "test: add optimizer mvp samples and smoke test"
    

Task 9: Final Documentation And Runbook

Files:

  • Create: README.md

  • Create: docs/superpowers/specs/2026-06-16-geo-agent-article-optimizer-design.md remains unchanged unless the implementation reveals a spec correction.

  • Step 1: Write README

    Include:

    • Project goal.
    • Local setup commands.
    • Required .env.local keys.
    • How to run tests.
    • How to start the local app.
    • Export file location.
    • MVP limitations from the spec.
  • Step 2: Run final verification

    npm test
    npm run build
    

    Expected: all tests pass and production build succeeds.

  • Step 3: Commit docs

    git add README.md docs/superpowers/specs/2026-06-16-geo-agent-article-optimizer-design.md
    git commit -m "docs: add local mvp runbook"
    

Acceptance Mapping

  • Paste title, body, image descriptions, and target platform: Task 6.
  • Extract fact card and require confirmation: Tasks 2, 4, 5, 6.
  • Save and reuse brand template: Task 3 and Task 5.
  • Generate optimized article without changing confirmed facts: Task 4.
  • Generate structured QA report for 10 gates: Task 4 and Task 6.
  • Block export on hard failures: Task 4, Task 6, Task 7.
  • Download Markdown and Word document: Task 7.
  • Minimum five risk samples: Task 8.

Development Order

Recommended execution order:

  1. Scaffold app.
  2. Domain model.
  3. SQLite.
  4. Workflow nodes.
  5. API routes.
  6. UI.
  7. Exporter.
  8. Samples and E2E.
  9. README and final verification.

This order keeps each task independently testable and avoids building UI against unstable data contracts.

Self-Review

  • Spec coverage: all MVP scope items, page areas, workflow nodes, data model, error handling, acceptance criteria, and minimum samples are mapped to tasks.
  • Placeholder scan: the plan contains no unresolved TBD, TODO, or open-ended implementation placeholders.
  • Type consistency: planned names match the spec and remain stable across tasks.
  • Scope check: this is one coherent local MVP. Publishing integrations, permissions, batching, direct .docx parsing, and complex Word templates remain excluded.