Files
our-claude-skills/custom-skills/96-ourdigital-estimate-engine/SKILL.md
Andrew Yim 9b914b9dd4 fix(estimate-engine): quote SKILL.md description to fix verify-skills YAML error (#11)
The unquoted description contained "Costing methods: effort …" — the mid-string
": " made YAML treat it as a nested mapping ("mapping values are not allowed
here"), failing verify-skills since 2026-05-27. Single-quote the value (it has
inner double quotes but no apostrophes), preserving the exact text.

verify_skills.py: 76/76 skills valid.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 21:21:26 +09:00

67 lines
4.2 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-estimate-engine
description: 'Method-aware estimate/견적 engine for OurDigital / D.intelligence professional services (SEO, GA4/GTM, education/coaching, digital ads, branding, …). Generates a Korean 견적 (md/xlsx/json) from a generic scope.json using the real company rate card. Use for "OurDigital 견적", "estimate", "quote", "proposal pricing", "cost estimate", "견적서 생성", or when another skill needs to price a service. Costing methods: effort (role×billing×hours), coaching (lesson×hours), procurement (+15%).'
---
# OurDigital Estimate Engine
Single source of truth for OurDigital/D.intelligence pricing. Consuming skills map their
context into a `scope.json` and call the engine CLI; the engine owns the rate card + service
catalog and renders the 견적.
## Costing methods (catalog entry declares its `method`)
- **effort** — `role_rate × 청구율(0.70) × 표준 업무시간`, by module; auto-tier (smb/basic/treatment)
by portfolio size + premium-vertical floor; On-page hours scale by sub-brands (cap ×2.0);
제안가 = 합계 절사. Also supports **fixed-amount tasks** (`fixed:` Unit Cost — e.g. branding
진단 stages) and **monthly retainers** (`unit: monthly` — e.g. ads 대행). Reproduces real
SEO (10.5M/25.0M), branding (₩9.0M), ads (₩6.0M/월).
- **coaching** — `Σ(lesson_type_price × hours)` over a lesson plan; student discount opt-in.
Reproduces real GA4/GTM 코칭 (₩1,570,000). Base prices default; subject×level matrix optional.
- **procurement** — `unit_cost × qty × (1 + 0.15)` for non-labor items.
## Files
- `references/rate_card.yaml` — universal: role rates, billing, basis, terms, tiering, scaling,
procurement, coaching prices/levels/discounts, tools. **Private.**
- `catalog/<service>.yaml` — per-service: `service`, `method`, body. All real:
`seo` (effort, role-hours tiers), `education` (coaching, incl. GA4/GTM course),
`digital_branding` (effort, fixed 진단 stages → ₩9.0M), `digital_ads` (effort, ₩6.0M/월
retainer; media commission % is per-deal, not in catalog).
- `scripts/estimate.py` — CLI dispatcher; `scripts/methods/{effort,coaching,procurement}.py`;
`scripts/render.py` (md/xlsx/json). `scope.schema.json` — input contract.
## Usage
```
python scripts/estimate.py \
--rate-card references/rate_card.yaml --catalog-dir catalog \
--scope scope.json --out-dir <engagement> [--seq N]
```
`scope.json` examples (see `scope.schema.json`):
- effort: `{"service":"seo","tier":"auto","signals":{"properties_total":25,"subbrands_total":5,"vertical":"hotel_resort"},"prospect":{"name":"…","audit_date":"YYYY-MM-DD"}}`
- coaching: `{"service":"education","course":"ga4_gtm_intermediate","students":1,"prospect":{…}}`
- procurement: `{"service":"seo","method":"procurement","items":[{"label":"SEMrush Guru","unit_cost":330000,"qty":6}]}`
Outputs `05_estimate_ko.md`, `05_estimate.xlsx`, `data/estimate.json`. The effort `estimate.json`
shape is consumed by `ourdigital-presales-seo/build_deck.py`.
## Consuming from another skill (CLI)
1. Map your context → `scope.json` (service, tier signals or lessons, prospect).
2. Call `estimate.py`. 3. Use the rendered 견적; for SEO, feed `data/estimate.json` to the deck.
Example consumer: `ourdigital-presales-seo` (`findings_to_scope.py` → engine → 견적 + deck).
## Adding / editing services
- New real service: add `catalog/<service>.yaml` with `method` + body from a **real quote**.
- Any new stub should carry `_stub: true` (the 견적 prints a ⚠STUB banner) until replaced with
real quote data. All current catalogs are real.
- Rates change in `rate_card.yaml` only (single source). Validate against a known real quote.
## Output location
Estimates are archived centrally in OurDigital's space:
`~/Workspaces/ourdigital-space/estimates/<YYYY-MM-DD>_<prospect|account>_<service>/`
(e.g. `…/estimates/2026-05-27_shr_seo/`). The engine stays `--out-dir`-agnostic — the caller
passes that path. Client engagements keep their audit docs/deck in their own workspace but the
견적 lives here (single quote archive).
## Conventions
Korean-first output · 부가세 별도 · 유효기간 14d · 현금 · `OD-YYYY-NNN`. Don't invent rates —
stub and flag instead. Legal entity (주)디인텔리전스 / info@ourdigital.org.