# Design — `ourdigital-estimate-engine` skill - **Status**: Approved design (2026-05-28). Implementing. - **Origin**: Extracted from `ourdigital-presales-seo`'s estimate engine and generalized to cover all OurDigital / D.intelligence professional services via multiple costing methods. - **Source data**: real quotes in Google Drive `06_Working Template` (SEO) and `견적 자료` (GA4/GTM, education). Company: (주)디인텔리전스 / D.intelligence Lab, info@ourdigital.org. ## 1. Purpose & scope A reusable, **method-aware** estimate engine that produces OurDigital 견적 for any service line. Consuming skills (e.g. `ourdigital-presales-seo`) map their context → a generic `scope.json` and call the engine CLI. The engine owns the rate card + service catalog (single source of truth). ### Costing methods (from real data) 1. **effort** — `role_rate × billing_rate(0.70) × hours`, grouped into modules; tiering, sub-brand scaling, premium-vertical floor, 절사. (SEO Audit & Treatment, etc.) 2. **coaching** — `Σ(lesson_type_price × hours)` over a lesson plan, with student-count discount. Base type prices reproduce real quotes; optional subject×level list-price matrix (`base × level_multiple`). (GA4/GTM courses, workshops, education.) 3. **procurement** — `unit_cost × qty × (1 + 0.15)` for non-labor items (tools, 3rd-party). All methods share: cover-sheet output, 부가세 별도, 유효기간 14d, 현금, 십만 단위 미만 절사 (500k floor for project quotes), quote no `OD-YYYY-NNN`. ### Non-goals - No invented rates. `digital_ads` / `digital_branding` are built from real docs (디하이브 ads 대행 계약, TNS 브랜딩 진단 견적); any future service without real data ships as a flagged stub. - No GA4/GTM *effort-implementation* catalog (delivered as coaching → a course in education). - Does not replace consuming skills' domain logic (e.g. SEO findings→scope mapping stays in presales-seo). ## 2. Structure ``` 96-ourdigital-estimate-engine/ SKILL.md references/ rate_card.yaml # UNIVERSAL pricing config (see §3) catalog/ seo.yaml # method: effort — tiers smb/basic/treatment (real) education.yaml # method: coaching — courses + per-subject levels (real) digital_ads.yaml # method: effort — REAL (₩6.0M/월 retainer + per-deal media commission) digital_branding.yaml # method: effort — REAL (fixed 진단 stages → ₩9.0M) scripts/ estimate.py # CLI dispatcher methods/effort.py methods/coaching.py methods/procurement.py render.py # md / xlsx / json output (cover-sheet) scope.schema.json ``` ## 3. `rate_card.yaml` (universal) - `company`, `quote_prefix: OD`, `currency: KRW`, `rounding_unit: 500000` - `terms`: vat 부가세 별도, validity_days 14, payment 현금 - **effort**: `billing_rate: 0.70` (floor 0.60), `basis {8h/day, 4wk/mo}`, `procurement_markup: 0.15`, `role_rates {대표 180k … 과장 70k … 인턴 12k}`, `tiering {premium_verticals, premium_min_tier}`, `scaling {driver: subbrands_total, bands cap ×2.0}`, `tools`. - **coaching**: - `lesson_type_prices`: 화상 80,000 · 대면 100,000 · 실습 150,000 · 워크숍 300,000 · 트리트먼트 500,000 - `level_multiple`: Beginners 1.0 · Intermediate 1.5 · Advanced 2.0 · Expert 2.5 · Trainers 3.0 - `subject_levels`: {Content Marketing: Beginners, SEO: Beginners, Google Analytics: Intermediate, Google Tag Manager: Advanced, Digital Marketing Strategy: Advanced, Digital Communication: Intermediate, KPI Setup & Measurement Plan: Expert, Business Model Canvas: Expert, e-Commerce Audit: Advanced} - `pricing_mode: base` (default; reproduces real quotes) | `matrix` (list price = base×level_multiple) - `student_discount_bands`: [[5,0.20],[10,0.0],[20,0.20],[30,0.30]] (30+ = 별도 협의) ## 4. Catalog entries Each file: `service`, `method`, and method-specific body. - **seo.yaml** (effort): the current `sow_templates.yaml` verbatim (tiers smb/basic/treatment, modules→tasks with role/hours/scale). Validated to reproduce 10.5M/25.0M. - **education.yaml** (coaching): `courses:` — named lesson plans, each `lessons: [{subject, type, hours}]`. Seed with `ga4_gtm_intermediate` (the real 17-lesson, ₩1,570,000 plan) and `ga4_gtm_marketing_analytics`. Subjects resolve levels from rate_card.subject_levels. - **digital_ads.yaml / digital_branding.yaml** (effort): STUB — one placeholder tier + `_stub: true`, with a header comment to populate from a real quote. ## 5. `scope.json` (generic input — `scope.schema.json`) ```jsonc // effort {"service":"seo","method":"effort","tier":"auto", // or smb|basic|treatment "signals":{"properties_total":25,"subbrands_total":5,"vertical":"hotel_resort"}, "billing_rate":null, "seq":1, "prospect":{"name":"","audit_date":""}} // coaching {"service":"education","method":"coaching","course":"ga4_gtm_intermediate", "students":1, "pricing_mode":"base", "prospect":{...}} // or "lessons":[{subject,type,hours}] ``` `tier:"auto"` → engine runs tiering (size + premium floor) from `signals`. ## 6. CLI `python scripts/estimate.py --catalog-dir catalog --rate-card references/rate_card.yaml --scope scope.json --out-dir