From 73f47a0f9a148ca728bdb378311384a7e274966a Mon Sep 17 00:00:00 2001 From: Codex Date: Tue, 16 Jun 2026 13:08:14 +0800 Subject: [PATCH] docs: add geo optimizer design and plan --- ...6-06-16-geo-agent-article-optimizer-mvp.md | 655 ++++++++++++++++++ 1 file changed, 655 insertions(+) create mode 100644 docs/superpowers/plans/2026-06-16-geo-agent-article-optimizer-mvp.md diff --git a/docs/superpowers/plans/2026-06-16-geo-agent-article-optimizer-mvp.md b/docs/superpowers/plans/2026-06-16-geo-agent-article-optimizer-mvp.md new file mode 100644 index 0000000..5ff8ab7 --- /dev/null +++ b/docs/superpowers/plans/2026-06-16-geo-agent-article-optimizer-mvp.md @@ -0,0 +1,655 @@ +# 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: + +```bash +npm install next react react-dom better-sqlite3 zod openai docx nanoid +``` + +Development dependencies: + +```bash +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: + +```bash +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: + +```text +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: + + ```json + { + "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: + + ```bash + 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`: + + ```text + OPENAI_API_KEY= + OPENAI_MODEL=gpt-4.1-mini + APP_DATA_DIR=./data + ``` + + `.gitignore` must include: + + ```text + node_modules/ + .next/ + .env + .env.* + !.env.example + data/app.db + data/exports/ + ``` + +- [ ] **Step 4: Add initial Next.js app shell** + + `src/app/layout.tsx`: + + ```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 ( + + {children} + + ); + } + ``` + + `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: + + ```bash + npm run build + npm test + ``` + + Expected: build succeeds. Test command may report no test files until Task 2 adds tests. + +- [ ] **Step 6: Commit scaffold** + + ```bash + 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: + + ```bash + npm test -- src/lib/domain/__tests__/validation.test.ts + ``` + + Expected: all validation tests pass. + +- [ ] **Step 5: Commit** + + ```bash + 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** + + ```bash + npm test -- src/lib/db/__tests__/repositories.test.ts + ``` + +- [ ] **Step 5: Commit** + + ```bash + 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(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** + + ```bash + npm test -- src/lib/workflow + ``` + +- [ ] **Step 5: Commit** + + ```bash + 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** + + ```bash + npm test -- src/app/api + npm run build + ``` + +- [ ] **Step 4: Commit** + + ```bash + 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: + + ```bash + npm run dev + ``` + + Open `http://localhost:3000`, paste one sample article, confirm the fact card, optimize, review QA, and download files. + +- [ ] **Step 7: Commit** + + ```bash + 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** + + ```bash + npm test -- src/lib/workflow/__tests__/exporter.test.ts + npm run build + ``` + +- [ ] **Step 5: Commit** + + ```bash + 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** + + ```bash + npm test + npm run build + npx playwright test + ``` + +- [ ] **Step 4: Commit** + + ```bash + 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** + + ```bash + npm test + npm run build + ``` + + Expected: all tests pass and production build succeeds. + +- [ ] **Step 3: Commit docs** + + ```bash + 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.