Files
our-claude-skills/custom-skills/95-ourdigital-presales-seo/SKILL.md
Andrew Yim c9bdbb57f7 Extract ourdigital-estimate-engine; presales-seo now calls it
New skill 96-ourdigital-estimate-engine: method-aware quoting engine
(effort / coaching / procurement) with universal rate_card + per-service
catalog. Real catalogs: seo (effort), education (coaching); stubs:
digital_ads, digital_branding. Validated to reproduce real quotes —
SEO basic ₩10.5M / treatment ₩25.0M, SHR chain ₩29.5M, L'Escape basic
₩10.5M, GA4/GTM coaching ₩1,570,000, procurement +15%.

Refactor 95-ourdigital-presales-seo: remove rate_card.yaml, sow_templates.yaml,
estimate.py (migrated to engine); add findings_to_scope.py; Stage 5 now maps
findings→scope.json and calls the engine CLI. build_deck/kg_query unchanged;
end-to-end validated on SHR (29.5M) + deck renders engine estimate.json.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 01:54:11 +09:00

93 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: ourdigital-presales-seo
description: Standardized pre-sales SEO + Knowledge Graph diagnostic for a prospect domain that produces a technical/on-page scan, KG/entity analysis, consolidated brief, a rate-card-based cost estimate (견적), and an editable PPTX sales deck. Use for pre-sales prospecting, sales briefing prep, "pre-sales SEO audit", "프리세일즈 진단", "견적 + 제안 슬라이드", or when preparing for a prospect meeting. Public-data only (no client GSC/GA4 access required). Korean-first output.
---
# OurDigital Pre-sales SEO Workflow
Runs the full pre-sales diagnostic for **any prospect domain** as **step-by-step
confirmed stages**, ending in a cost estimate and a sales-briefing deck. Public-data
only — designed for prospects where you don't yet have GSC/GA4/GTM access.
Origin: standardizes the Sono Hotels & Resorts pre-sales diagnostic.
## Execution model — STEP BY STEP
Run one stage at a time. After each stage, **present the result and WAIT for the
user's go-ahead** before the next. Create a TodoWrite/Task item per stage. Stages 5
(estimate) and 6 (deliverables) are explicit review gates — never send without sign-off.
## Stage 0 — Scope & preflight
Collect (ask only for what you can't infer):
- `domain` (required); `brand_name` + `aliases` (앤/& / EN variants — infer from `<title>`/og first)
- `sub_brands`, `properties` (auto-extract from crawl URL patterns in Stage 1 if not given)
- `competitors` (else pick a set from `references/competitor_sets.md` by vertical)
- `market`/`language` (default South Korea / ko), `vertical`
- `output_dir` — default routing: if `~/Workspaces/<slug>-workspace/` exists →
`…/audits/<YYYY-MM-DD>-presales/`, else `~/Workspaces/seo-workspace/prospecting/<YYYY-MM-DD>-<prospect>/`
Preflight tool check (report missing + fallback): Firecrawl, DataForSEO, `GOOGLE_KG_API_KEY`,
headless Chrome, python-pptx. Create `data/` subfolder. Initialize `findings.json` (see `findings.schema.json`).
## Stage 1 — Discovery & crawl
- `WebFetch` robots.txt + `/sitemap.xml` + `/sitemap_index.xml` (note status; 500/404 = finding).
- `firecrawl_map` (limit high, includeSubdomains) → URL inventory; record `discoverable_urls`,
derive URL architecture, `estimated_pages`, and hygiene flags (`/test`, params, duplicate path schemes).
- Populate `findings.json.discovery`. → write scan §1.
## Stage 2 — Technical / on-page
- `firecrawl_scrape` (json) homepage + 1-2 property pages: JSON-LD `@type`s, Organization completeness
(sameAs/alternateName/address), meta/title/H1, hreflang set, robots/googlebot meta.
- `mcp__dfs-mcp__on_page_lighthouse` homepage (+ a property) → CWV.
- Populate `findings.json.technical`. → write `01_technical-onpage-scan.md`.
- **Honesty rule:** never claim "noindexed" if the page ranks — flag conflicting directives as "verify".
## Stage 3 — Knowledge Graph / entity
- `python scripts/kg_query.py --brand … --aliases … --parent … --legacy … --subbrands … --properties … --competitors … --out-dir <out>/data`
(needs `GOOGLE_KG_API_KEY`; run with sandbox disabled — read-only API GET).
- Live SERP panel verification: `mcp__dfs-mcp__serp_organic_live_advanced` (ko, South Korea) for brand,
a sub-brand, a property, and one competitor → record actual panel type/title, local packs, reseller leakage.
- Populate `findings.json.entity` (panel, name_split, legacy_contamination, sub-brand/property entity counts,
competitor_benchmark[], wikipedia). → write `02_knowledge-graph-entity.md` + `data/serp_panels_findings.md`.
## Stage 4 — Consolidated brief
- Synthesize, rank by severity, build the competitive-gap table. Populate `findings.json.findings[]`.
→ write `03_presales-opportunity-brief.md`.
## Stage 5 — Estimate (견적) — REVIEW GATE
Pricing is delegated to the **`ourdigital-estimate-engine`** skill (`../96-ourdigital-estimate-engine`); this skill only maps findings → scope, then calls the engine:
- `python scripts/findings_to_scope.py --findings <out>/data/findings.json --out <out>/data/scope.json --seq <N> [--tier auto|smb|basic|treatment] [--billing 0.70]`
- `ENG=../96-ourdigital-estimate-engine; python $ENG/scripts/estimate.py --rate-card $ENG/references/rate_card.yaml --catalog-dir $ENG/catalog --scope <out>/data/scope.json --out-dir <out>`
- Engine (effort method, `seo` catalog): auto-tier (smb/basic/treatment) by portfolio + premium-vertical floor; On-page hours scale by `subbrands_total` (cap ×2.0); 제안가 = 합계 절사. Reproduces Basic ₩10.5M / Treatment ₩25.0M; SMB ~₩3M; 25-property chain ~₩29.5M.
- Produces `05_estimate_ko.md`, `05_estimate.xlsx`, `data/estimate.json` (effort shape → consumed by `build_deck.py`). Present the 견적; get sign-off.
- SEO findings→scope/tier mapping lives here (`findings_to_service.md`); **rates/hours/tiers live in the engine** (`rate_card.yaml` + `catalog/seo.yaml`) — edit pricing there, not here.
## Stage 6 — Deliverables — REVIEW GATE before send
- **Client PDF**: author the short brief HTML from `templates/client_brief.html` (fill the content; keep the CSS),
then `bash scripts/render_pdf.sh <brief>.html` → PDF. Verify Korean renders (Read the PDF).
- **Sales deck**: `python scripts/build_deck.py --findings <out>/data/findings.json --estimate <out>/data/estimate.json --out <out>/sales-deck.pptx`
- Sanitize the client-facing pieces: no internal pricing strategy beyond the 견적; tasteful competitor benchmark only.
## Stage 7 — Archive (standard)
Push the consolidated report to the OurDigital SEO Audit DB:
```
python <notion-writer path>/notion_writer.py \
--database 2c8581e5-8a1e-8035-880b-e38cefc2f3ef \
--title "<프로스펙트> SEO 사전진단 (Pre-sales) — <YYYY-MM-DD>" \
--properties '{"Target URL": "<domain>", "Audit Date": "<YYYY-MM-DD>", "Account Code": "<CODE>"}' \
--file <out>/03_presales-opportunity-brief.md
```
Property names are exact: `Target URL`, `Audit Date`, `Account Code`. **Do NOT set `Audit ID`**
(read-only formula). notion-writer path: `~/Project/our-claude-skills/custom-skills/32-notion-writer/code/scripts/notion_writer.py`.
## Tool gotchas (learned)
- OurSEO `crawl_website` **caps ~60 pages** regardless of `max_pages` — use Firecrawl `map` for inventory; report the discoverable count as a finding.
- Firecrawl `scrape` cache may return empty — re-scrape.
- KG API + headless Chrome + Notion push need network → run those Bash calls with the sandbox disabled.
- Korean PDF: headless Chrome uses system fonts (AppleSDGothicNeo on macOS). On Windows set deck font to Malgun Gothic in `build_deck.py`.
## Conventions
- Korean-first for all client-facing output; keep technical terms in English (SEO, CWV, Schema, hreflang).
- File names: `01_/02_/03_/05_` prefixes as above; raw artifacts in `data/`.
- Outputs go to the workspace (Stage 0 routing), **never** into this skills repo.