144 lines
3.2 KiB
Markdown
144 lines
3.2 KiB
Markdown
# GEO Agent Article Optimizer
|
|
|
|
Local MVP for optimizing pasted GEO-related articles while preserving confirmed
|
|
brand facts. The app extracts a fact card, requires user confirmation, rewrites
|
|
under those constraints, runs QA gates, and exports Markdown, Word, and JSON.
|
|
|
|
## Setup
|
|
|
|
```bash
|
|
npm install
|
|
cp .env.example .env.local
|
|
npm run dev
|
|
```
|
|
|
|
Open `http://localhost:3000`.
|
|
|
|
## Environment
|
|
|
|
Required for live model calls:
|
|
|
|
```text
|
|
LLM_PROVIDER=deepseek
|
|
DEEPSEEK_API_KEY=
|
|
DEEPSEEK_BASE_URL=https://api.deepseek.com
|
|
DEEPSEEK_MODEL=deepseek-v4-pro
|
|
DEEPSEEK_THINKING=disabled
|
|
APP_DATA_DIR=./data
|
|
API_ACCESS_KEY=local-dev-key
|
|
API_AUTH_DISABLED=false
|
|
```
|
|
|
|
OpenAI-compatible fallback keys are also accepted:
|
|
|
|
```text
|
|
OPENAI_API_KEY=
|
|
OPENAI_MODEL=gpt-4.1-mini
|
|
```
|
|
|
|
When a DeepSeek or OpenAI-compatible key is configured, the workflow uses the
|
|
provider for fact extraction, article optimization, QA enrichment, and targeted
|
|
rewrite. Every LLM response is validated with Zod before use. When no API key is
|
|
configured, or when the provider response is invalid, deterministic local
|
|
fallbacks keep the workflow usable for tests and local review.
|
|
|
|
All API requests require the configured access key:
|
|
|
|
```text
|
|
x-api-key: <API_ACCESS_KEY>
|
|
```
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
npm test
|
|
npm run build
|
|
npx playwright test
|
|
```
|
|
|
|
## Cloudflare Workers Deployment
|
|
|
|
Cloudflare deployment is manual. Pushing to Git does not deploy or hot-update
|
|
the production Worker.
|
|
|
|
Local development:
|
|
|
|
```bash
|
|
npm run dev
|
|
```
|
|
|
|
Cloudflare preview:
|
|
|
|
```bash
|
|
cp .dev.vars.example .dev.vars
|
|
npm run d1:migrate:local
|
|
npm run preview:worker
|
|
```
|
|
|
|
Create private staging resources:
|
|
|
|
```bash
|
|
npx wrangler d1 create geo-agent-article-optimizer-staging
|
|
npx wrangler r2 bucket create geo-agent-article-optimizer-staging
|
|
```
|
|
|
|
Create private production resources:
|
|
|
|
```bash
|
|
npx wrangler d1 create geo-agent-article-optimizer-production
|
|
npx wrangler r2 bucket create geo-agent-article-optimizer-production
|
|
```
|
|
|
|
After D1 creation, copy the returned database IDs into the matching
|
|
`wrangler.jsonc` environment entries. Keep R2 buckets private; do not add public
|
|
bucket domains.
|
|
|
|
Set secrets:
|
|
|
|
```bash
|
|
npx wrangler secret put API_ACCESS_KEY --env staging
|
|
npx wrangler secret put DEEPSEEK_API_KEY --env staging
|
|
npx wrangler secret put API_ACCESS_KEY --env production
|
|
npx wrangler secret put DEEPSEEK_API_KEY --env production
|
|
```
|
|
|
|
D1 schema changes only through migrations. Runtime code must not rebuild or
|
|
clear production tables. Apply migrations in this order:
|
|
|
|
```bash
|
|
npm run d1:migrate:local
|
|
npm run d1:migrate:staging
|
|
npm run deploy:worker:staging
|
|
npm run d1:migrate:production
|
|
npm run deploy:worker:production
|
|
```
|
|
|
|
## Exports
|
|
|
|
Local generated files are written under:
|
|
|
|
```text
|
|
data/exports/<job_id>/
|
|
```
|
|
|
|
Cloudflare exports are written to the private R2 bucket bound as
|
|
`EXPORT_BUCKET` and served only through authenticated API routes.
|
|
|
|
Each passing or warning-only QA run can produce:
|
|
|
|
- `optimized.md`
|
|
- `optimized.docx`
|
|
- `qa_report.json`
|
|
|
|
Hard QA failures block export.
|
|
|
|
## MVP Limits
|
|
|
|
- Pasted text only; no direct `.docx` parsing.
|
|
- Local SQLite by default; Cloudflare deployments use D1.
|
|
- No account permissions or collaboration.
|
|
- No publishing platform APIs.
|
|
- No batch queue.
|
|
- Basic Word export layout only.
|
|
- Unconfirmed facts are never used as truth.
|