Files
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

52 lines
2.8 KiB
Markdown
Raw Permalink 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.
# Findings → estimate mapping (effort-based, SMB-aware)
`estimate.py` builds the 견적 from `sow_templates.yaml` priced via `rate_card.yaml`:
**cost = role_rate × billing_rate × standard_hours**, grouped by module; 제안가 = 합계
floored to `rounding_unit`. Mirrors OurDigital/D.intelligence's real SOW-based quoting.
## Tier selection (smb / basic / treatment)
- `treatment` if `properties_total > 5` OR `subbrands_total > 3` (multi-brand / chain)
- `smb` if `properties_total <= 1` AND `subbrands_total == 0` (single-property SMB)
- `basic` otherwise (small multi-property / mid)
- **Premium floor:** if `prospect.vertical` matches `rate_card.tiering.premium_verticals`
(luxury/premium/deluxe/5성/특1급…), the auto-tier is floored to `tiering.premium_min_tier`
(default `basic`) — a luxury single property won't auto-drop to `smb`.
- override with `--baseline`.
Per-tier billing: `smb` uses `billing_rate: 0.55` (set in sow_templates); `basic`/
`treatment` use `rate_card.billing_rate` (0.70). Override with `--billing`.
## Module inclusion
Each tier carries its standard module set (P&M · Technical SEO · On-page SEO ·
SEO Growth). Findings annotate modules via the `trigger` field:
| Module | trigger finding classes |
|---|---|
| Planning & Management | always |
| Technical SEO | crawlability, cwv, schema_entity |
| On-page SEO | onpage, schema_entity |
| SEO Growth | measurement, always |
## Hours scaling (portfolio)
Only **On-page** tasks (`scale: true`) scale, sub-linearly, by the
`rate_card.scaling.driver` (= `subbrands_total`, i.e. distinct brands/templates),
capped at **×2.0**. Rationale: chains share page templates, so on-page work grows
with template variety, not raw property count. **Technical SEO is fixed** site-wide
work (`scale: false`); P&M and SEO Growth are fixed too. Single-brand → ×1.0.
## Tools & terms
`tools` (e.g. SEMrush Guru) listed separately — client-subscribed, +15% procurement
markup if billed through us. VAT 별도 · 유효기간 14d · 현금 · 절사 from `rate_card.terms`.
## Validated (2026-05-28)
- `basic` ×1.0 → 합계 10,612,000 → 제안가 **10,500,000** (real Basic quote)
- `treatment` ×1.0 → 합계 25,340,000 → 제안가 **25,000,000** (real Treatment quote)
- `smb` single property → ~**3,000,000** (lean × 55% billing)
- chain example (SHR, 5 sub-brands ×1.6, treatment) → ~**29,500,000** (vs naive 71.5M)
**Pricing now lives in the `ourdigital-estimate-engine` skill** (`../96-ourdigital-estimate-engine`):
role rates/billing/tiering/scaling in `references/rate_card.yaml`, SEO tiers/hours in
`catalog/seo.yaml`. This skill maps findings → `scope.json` (`scripts/findings_to_scope.py`)
and calls the engine. Edit rates/hours/tiers **in the engine**, not here. This file documents
only the SEO findings→tier/scope mapping.