feat: add D.intelligence Agent Corps (9 skills + shared infra)
Add 9 agent skills (#70-#77, #88) for D.intelligence business operations: brand guardian, brand editor, doc secretary, quotation manager, service architect, marketing manager, back office manager, account manager, and skill update meta-agent. Includes shared Python package (dintel), reference docs, document/quotation templates, service module CSVs, cross-device installer, and comprehensive user guide. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
49
custom-skills/73-dintel-quotation-mgr/README.md
Normal file
49
custom-skills/73-dintel-quotation-mgr/README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# 73-dintel-quotation-mgr
|
||||
|
||||
> **Agent #73** | `dintel-quotation-mgr` v1.0.0 | D.intelligence Agent Corps
|
||||
|
||||
Quotation Manager -- the most complex skill in the D.intelligence Agent Corps. Uses a multi-agent sub-system (Scope, Resource, Pricing, Output) to generate professional quotations and estimates for D.intelligence service modules.
|
||||
|
||||
## Autonomy Level
|
||||
|
||||
**Draft & Wait** -- Generates a quote draft in branded Excel (.xlsx), then waits for Andrew's review. Andrew reviews in Google Sheets and leaves cell comments for feedback. The agent reads feedback and learns patterns over time via `shared/feedback-log.md`.
|
||||
|
||||
## Multi-Agent Sub-System
|
||||
|
||||
| Sub-Agent | Role |
|
||||
|-----------|------|
|
||||
| **Scope Agent** | Analyzes client requirements, maps to service modules (A1--G4) |
|
||||
| **Resource Agent** | Estimates effort hours, timeline, team allocation |
|
||||
| **Pricing Agent** | Calculates pricing using module rates, package discounts, discount policies |
|
||||
| **Output Generator** | Produces branded Excel .xlsx file using `dintel-shared/src/dintel/excel.py` |
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
73-dintel-quotation-mgr/
|
||||
├── code/
|
||||
│ ├── CLAUDE.md # Claude Code instructions
|
||||
│ └── scripts/
|
||||
│ └── generate_quotation.py # Excel generation script stub
|
||||
├── desktop/
|
||||
│ └── SKILL.md # Full skill definition (sub-agents, pricing, workflow)
|
||||
├── shared/
|
||||
│ ├── pricing-reference.md # Pricing quick reference
|
||||
│ └── feedback-log.md # Learning from Andrew's corrections
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## Key References
|
||||
|
||||
- Brand Guide: `../../dintel-shared/src/dintel/brand.py`
|
||||
- Excel utilities: `../../dintel-shared/src/dintel/excel.py`
|
||||
- Service Map: `/Users/ourdigital/Documents/D.intelligence Service Package/00_SERVICE-MAP.md`
|
||||
- Pricing Packages: `/Users/ourdigital/Documents/D.intelligence Service Package/06_PRICING-PACKAGES.md`
|
||||
|
||||
## Universal Guardrails
|
||||
|
||||
1. Never send to clients without Andrew's approval
|
||||
2. Never delete -- always archive
|
||||
3. **Never commit pricing without Andrew's sign-off** (CRITICAL)
|
||||
4. Korean-first, jargon = 한글(English) bilingual notation
|
||||
5. Never cross-reference client data without consent
|
||||
65
custom-skills/73-dintel-quotation-mgr/code/CLAUDE.md
Normal file
65
custom-skills/73-dintel-quotation-mgr/code/CLAUDE.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# D.intelligence Quotation Manager
|
||||
|
||||
> **Agent #73** | `dintel-quotation-mgr` v1.0.0 | D.intelligence Agent Corps
|
||||
|
||||
Generate professional quotations and estimates for D.intelligence service modules using a multi-agent sub-system (Scope, Resource, Pricing, Output).
|
||||
|
||||
## Agent Corps Context
|
||||
|
||||
- **Agent #73** -- Quotation Manager (Multi-Agent)
|
||||
- **Collaborates with**: Agent #70 (Brand Guardian), Agent #71 (Brand Editor)
|
||||
- **Shared constants**: `dintel-shared/src/dintel/brand.py` (colors, terminology, style tokens)
|
||||
- **Excel utilities**: `dintel-shared/src/dintel/excel.py` (branded workbook generation)
|
||||
|
||||
## Universal Guardrails
|
||||
|
||||
1. **Never send to clients without Andrew's approval** -- All quotations require Andrew's review.
|
||||
2. **Never delete -- always archive** -- Move outdated quotes to archive; never permanently delete.
|
||||
3. **Never commit pricing without Andrew's sign-off** -- CRITICAL. All pricing is draft until approved.
|
||||
4. **Korean-first, bilingual notation** -- Korean primary; jargon uses 한글(English) notation on first use.
|
||||
5. **Never cross-reference client data without consent** -- Client data is siloed by account.
|
||||
|
||||
## Autonomy Level: Draft & Wait
|
||||
|
||||
This agent generates quotation drafts and STOPS. It never finalizes or sends quotes without Andrew's explicit approval. All generated files are marked as DRAFT with yellow-highlighted price cells.
|
||||
|
||||
## Workflow
|
||||
|
||||
1. Receive client brief
|
||||
2. Run Scope Agent -> map requirements to modules (A1--G4)
|
||||
3. Run Resource Agent -> estimate hours, timeline, team
|
||||
4. Run Pricing Agent -> calculate prices, apply discounts
|
||||
5. Run Output Generator -> produce branded .xlsx
|
||||
6. **STOP** -- Notify Andrew for review
|
||||
7. Process feedback from Google Sheets comments -> update `shared/feedback-log.md`
|
||||
8. Revise if requested, then await final approval
|
||||
|
||||
## Quick Reference
|
||||
|
||||
- **Full skill definition**: `../desktop/SKILL.md` (sub-agents, pricing tables, discount rules, output format)
|
||||
- **Pricing reference**: `../shared/pricing-reference.md` and `../../dintel-shared/references/pricing-reference.md`
|
||||
- **Feedback log**: `../shared/feedback-log.md`
|
||||
- **Generate script**: `scripts/generate_quotation.py`
|
||||
- **Excel utilities**: `../../dintel-shared/src/dintel/excel.py`
|
||||
|
||||
## Quotation Template Library
|
||||
|
||||
Reference templates are available in `shared/quotation-templates/`:
|
||||
|
||||
| Template | Filename | Description |
|
||||
|----------|----------|-------------|
|
||||
| Standard 2026 | `D.intelligence-표준 견적서_2026.xlsx` | Current standard quotation template |
|
||||
| GA Analytics | `[템플릿] D.intelligence-Google Analytics-표준 견적서.xlsx` | GA4/GTM service quotes |
|
||||
| Content Marketing | `[템플릿] D.intelligence-콘텐츠 마케팅-표준 견적서 2026.xlsx` | Content marketing quotes |
|
||||
| GA Training | `[템플릿] D.intelligence-디지털 마케터를 위한 GA활용-중급-견적 _ 커리큘럼.xlsx` | Training/workshop quotes |
|
||||
|
||||
Use these as structural references for sheet layout, column headers, and formatting conventions when generating new quotations.
|
||||
|
||||
## Key Rules
|
||||
|
||||
- Quotation reference format: `DI-Q-{YYYYMMDD}-{NNN}`
|
||||
- All prices are VAT 별도
|
||||
- Discounts: apply highest single base discount; 재계약 10% stacks on top; never exceed 35% total
|
||||
- Payment terms default: 착수금 50% / 완료 후 50%
|
||||
- Validity: 견적 유효기간 30일
|
||||
- File naming: `DI-Q-{YYYYMMDD}-{NNN}_{ClientName}_DRAFT.xlsx`
|
||||
@@ -0,0 +1,355 @@
|
||||
"""
|
||||
D.intelligence Quotation Generator
|
||||
Agent #73 - dintel-quotation-mgr
|
||||
|
||||
Generates branded Excel .xlsx quotation files using dintel-shared utilities.
|
||||
This is a stub script -- extend with full implementation as needed.
|
||||
|
||||
Usage:
|
||||
python generate_quotation.py --client "고객사명" --modules A3,T6 --output ./output/
|
||||
|
||||
Dependencies:
|
||||
- dintel-shared (../../dintel-shared/)
|
||||
- openpyxl
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import date, timedelta
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Pricing data (mirrors shared/pricing-reference.md)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
MODULE_PRICING: dict[str, dict] = {
|
||||
# Analysis (진단)
|
||||
"A1": {"name": "비즈니스·브랜드 진단", "duration": "2-3주", "min": 3_000_000, "max": 5_000_000, "phase": "Analysis"},
|
||||
"A2": {"name": "고객·소비자 분석", "duration": "3-4주", "min": 4_000_000, "max": 7_000_000, "phase": "Analysis"},
|
||||
"A3": {"name": "데이터 분석 (웹·앱)", "duration": "3-5주", "min": 4_000_000, "max": 8_000_000, "phase": "Analysis"},
|
||||
"A4": {"name": "디지털 마케팅 진단", "duration": "2-4주", "min": 3_000_000, "max": 6_000_000, "phase": "Analysis"},
|
||||
"A5": {"name": "퍼포먼스 마케팅 진단", "duration": "2-3주", "min": 3_000_000, "max": 5_000_000, "phase": "Analysis"},
|
||||
"A6": {"name": "운영·관리 진단", "duration": "2-3주", "min": 2_000_000, "max": 4_000_000, "phase": "Analysis"},
|
||||
# Treatment (처방)
|
||||
"T1": {"name": "브랜드 스토리텔링 & 가이드", "duration": "4-8주", "min": 5_000_000, "max": 12_000_000, "phase": "Treatment"},
|
||||
"T2": {"name": "고객 접점 경험 최적화", "duration": "4-6주", "min": 4_000_000, "max": 8_000_000, "phase": "Treatment"},
|
||||
"T3": {"name": "디지털 자산 통합관리", "duration": "4-8주", "min": 6_000_000, "max": 15_000_000, "phase": "Treatment"},
|
||||
"T4": {"name": "콘텐츠 마케팅", "duration": "4-8주", "min": 4_000_000, "max": 10_000_000, "phase": "Treatment"},
|
||||
"T5": {"name": "광고·전환 최적화", "duration": "3-6주", "min": 4_000_000, "max": 8_000_000, "phase": "Treatment"},
|
||||
"T6": {"name": "Brand Visibility Treatment", "duration": "4-12주", "min": 5_000_000, "max": 15_000_000, "phase": "Treatment"},
|
||||
"T7": {"name": "운영 시스템·자동화", "duration": "4-8주", "min": 4_000_000, "max": 10_000_000, "phase": "Treatment"},
|
||||
# Growth (성장)
|
||||
"G1": {"name": "퍼포먼스 마케팅", "duration": "월간", "min": 2_000_000, "max": 5_000_000, "phase": "Growth", "monthly": True},
|
||||
"G2": {"name": "콘텐츠 마케팅 대행", "duration": "월간", "min": 3_000_000, "max": 6_000_000, "phase": "Growth", "monthly": True},
|
||||
"G3": {"name": "모니터링·이슈관리", "duration": "월간", "min": 2_000_000, "max": 4_000_000, "phase": "Growth", "monthly": True},
|
||||
"G4": {"name": "연간 계약·운영", "duration": "12개월", "min": 0, "max": 0, "phase": "Growth", "monthly": True},
|
||||
}
|
||||
|
||||
COMPLEXITY_PERCENTILE = {
|
||||
"standard": 0.30,
|
||||
"complex": 0.60,
|
||||
"enterprise": 0.90,
|
||||
}
|
||||
|
||||
DISCOUNT_POLICIES = {
|
||||
"multi_3plus": {"label": "3개 모듈 이상 동시 계약", "rate": 0.15},
|
||||
"analysis_treatment": {"label": "Analysis → Treatment 연계", "rate": 0.20},
|
||||
"full_cycle": {"label": "Full cycle (A→T→G)", "rate": 0.25},
|
||||
"g4_annual": {"label": "G4 연간 계약", "rate": 0.20},
|
||||
"renewal": {"label": "재계약 (기존 고객)", "rate": 0.10, "stackable": True},
|
||||
}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Data classes
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@dataclass
|
||||
class LineItem:
|
||||
code: str
|
||||
name: str
|
||||
phase: str
|
||||
complexity: str = "standard"
|
||||
base_price: int = 0
|
||||
months: int = 1 # for Growth modules
|
||||
subtotal: int = 0
|
||||
|
||||
|
||||
@dataclass
|
||||
class QuotationDraft:
|
||||
ref: str = ""
|
||||
client_name: str = ""
|
||||
industry: str = ""
|
||||
date_created: date = field(default_factory=date.today)
|
||||
validity_days: int = 30
|
||||
line_items: list[LineItem] = field(default_factory=list)
|
||||
subtotal: int = 0
|
||||
discount_label: str = ""
|
||||
discount_rate: float = 0.0
|
||||
discount_amount: int = 0
|
||||
total_before_vat: int = 0
|
||||
is_renewal: bool = False
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Pricing logic
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def calculate_price(code: str, complexity: str = "standard") -> int:
|
||||
"""Calculate module price based on complexity percentile within range."""
|
||||
module = MODULE_PRICING.get(code)
|
||||
if not module:
|
||||
raise ValueError(f"Unknown module code: {code}")
|
||||
pct = COMPLEXITY_PERCENTILE.get(complexity, 0.30)
|
||||
price_range = module["max"] - module["min"]
|
||||
return int(module["min"] + price_range * pct)
|
||||
|
||||
|
||||
def determine_discount(line_items: list[LineItem], is_renewal: bool = False) -> tuple[str, float]:
|
||||
"""Determine the highest applicable base discount, plus renewal if applicable."""
|
||||
phases = {item.phase for item in line_items}
|
||||
num_modules = len(line_items)
|
||||
has_g4 = any(item.code == "G4" for item in line_items)
|
||||
|
||||
# Determine base discount (highest wins)
|
||||
base_label = ""
|
||||
base_rate = 0.0
|
||||
|
||||
if phases >= {"Analysis", "Treatment", "Growth"}:
|
||||
base_label = DISCOUNT_POLICIES["full_cycle"]["label"]
|
||||
base_rate = DISCOUNT_POLICIES["full_cycle"]["rate"]
|
||||
elif "Analysis" in phases and "Treatment" in phases:
|
||||
base_label = DISCOUNT_POLICIES["analysis_treatment"]["label"]
|
||||
base_rate = DISCOUNT_POLICIES["analysis_treatment"]["rate"]
|
||||
elif has_g4:
|
||||
base_label = DISCOUNT_POLICIES["g4_annual"]["label"]
|
||||
base_rate = DISCOUNT_POLICIES["g4_annual"]["rate"]
|
||||
elif num_modules >= 3:
|
||||
base_label = DISCOUNT_POLICIES["multi_3plus"]["label"]
|
||||
base_rate = DISCOUNT_POLICIES["multi_3plus"]["rate"]
|
||||
|
||||
# Stack renewal discount
|
||||
if is_renewal and base_rate > 0:
|
||||
base_label += " + 재계약"
|
||||
base_rate = min(base_rate + 0.10, 0.35)
|
||||
elif is_renewal:
|
||||
base_label = DISCOUNT_POLICIES["renewal"]["label"]
|
||||
base_rate = 0.10
|
||||
|
||||
return base_label, base_rate
|
||||
|
||||
|
||||
def build_quotation(
|
||||
client_name: str,
|
||||
modules: list[tuple[str, str]], # [(code, complexity), ...]
|
||||
industry: str = "",
|
||||
is_renewal: bool = False,
|
||||
growth_months: int = 3,
|
||||
) -> QuotationDraft:
|
||||
"""Build a complete quotation draft."""
|
||||
today = date.today()
|
||||
ref = f"DI-Q-{today.strftime('%Y%m%d')}-001"
|
||||
|
||||
draft = QuotationDraft(
|
||||
ref=ref,
|
||||
client_name=client_name,
|
||||
industry=industry,
|
||||
date_created=today,
|
||||
is_renewal=is_renewal,
|
||||
)
|
||||
|
||||
for code, complexity in modules:
|
||||
module = MODULE_PRICING[code]
|
||||
price = calculate_price(code, complexity)
|
||||
months = growth_months if module.get("monthly") else 1
|
||||
item = LineItem(
|
||||
code=code,
|
||||
name=module["name"],
|
||||
phase=module["phase"],
|
||||
complexity=complexity,
|
||||
base_price=price,
|
||||
months=months,
|
||||
subtotal=price * months,
|
||||
)
|
||||
draft.line_items.append(item)
|
||||
|
||||
draft.subtotal = sum(item.subtotal for item in draft.line_items)
|
||||
draft.discount_label, draft.discount_rate = determine_discount(draft.line_items, is_renewal)
|
||||
draft.discount_amount = int(draft.subtotal * draft.discount_rate)
|
||||
draft.total_before_vat = draft.subtotal - draft.discount_amount
|
||||
|
||||
return draft
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Excel generation (stub -- requires openpyxl and dintel-shared)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def generate_xlsx(draft: QuotationDraft, output_dir: Path) -> Path:
|
||||
"""Generate branded .xlsx quotation file.
|
||||
|
||||
TODO: Implement full branded workbook using dintel-shared/src/dintel/excel.py.
|
||||
This stub creates a basic workbook structure.
|
||||
"""
|
||||
try:
|
||||
from openpyxl import Workbook
|
||||
from openpyxl.styles import Alignment, Font, PatternFill
|
||||
except ImportError:
|
||||
print("ERROR: openpyxl is required. Install with: pip install openpyxl", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
wb = Workbook()
|
||||
|
||||
# -- Sheet 1: Cover --
|
||||
ws_cover = wb.active
|
||||
ws_cover.title = "표지"
|
||||
ws_cover["B2"] = "D.intelligence :: SMART Marketing Clinic ::"
|
||||
ws_cover["B2"].font = Font(name="Pretendard", size=16, bold=True)
|
||||
ws_cover["B4"] = "견적서 (Quotation)"
|
||||
ws_cover["B4"].font = Font(name="Pretendard", size=24, bold=True)
|
||||
ws_cover["B6"] = f"고객사: {draft.client_name}"
|
||||
ws_cover["B7"] = f"업종: {draft.industry}"
|
||||
ws_cover["B8"] = f"견적번호: {draft.ref}"
|
||||
ws_cover["B9"] = f"작성일: {draft.date_created.isoformat()}"
|
||||
ws_cover["B10"] = f"유효기간: {(draft.date_created + timedelta(days=draft.validity_days)).isoformat()}"
|
||||
ws_cover["B12"] = "DRAFT -- 검토 대기"
|
||||
ws_cover["B12"].font = Font(color="FF0000", bold=True, size=14)
|
||||
|
||||
# -- Sheet 2: Scope --
|
||||
ws_scope = wb.create_sheet("서비스 범위")
|
||||
headers = ["모듈 코드", "모듈명", "Phase", "복잡도", "비고"]
|
||||
for col, header in enumerate(headers, 1):
|
||||
cell = ws_scope.cell(row=1, column=col, value=header)
|
||||
cell.font = Font(bold=True)
|
||||
for row, item in enumerate(draft.line_items, 2):
|
||||
ws_scope.cell(row=row, column=1, value=item.code)
|
||||
ws_scope.cell(row=row, column=2, value=item.name)
|
||||
ws_scope.cell(row=row, column=3, value=item.phase)
|
||||
ws_scope.cell(row=row, column=4, value=item.complexity)
|
||||
|
||||
# -- Sheet 3: Timeline (placeholder) --
|
||||
ws_timeline = wb.create_sheet("일정")
|
||||
ws_timeline["A1"] = "Phase"
|
||||
ws_timeline["B1"] = "Module"
|
||||
ws_timeline["C1"] = "Duration"
|
||||
ws_timeline["A1"].font = Font(bold=True)
|
||||
ws_timeline["B1"].font = Font(bold=True)
|
||||
ws_timeline["C1"].font = Font(bold=True)
|
||||
for row, item in enumerate(draft.line_items, 2):
|
||||
ws_timeline.cell(row=row, column=1, value=item.phase)
|
||||
ws_timeline.cell(row=row, column=2, value=f"{item.code} {item.name}")
|
||||
module = MODULE_PRICING[item.code]
|
||||
ws_timeline.cell(row=row, column=3, value=module["duration"])
|
||||
|
||||
# -- Sheet 4: Pricing --
|
||||
ws_pricing = wb.create_sheet("견적 내역")
|
||||
draft_fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid")
|
||||
price_headers = ["모듈 코드", "모듈명", "단가 (원)", "수량/개월", "소계 (원)"]
|
||||
for col, header in enumerate(price_headers, 1):
|
||||
cell = ws_pricing.cell(row=1, column=col, value=header)
|
||||
cell.font = Font(bold=True)
|
||||
for row, item in enumerate(draft.line_items, 2):
|
||||
ws_pricing.cell(row=row, column=1, value=item.code)
|
||||
ws_pricing.cell(row=row, column=2, value=item.name)
|
||||
price_cell = ws_pricing.cell(row=row, column=3, value=item.base_price)
|
||||
price_cell.fill = draft_fill
|
||||
price_cell.number_format = "#,##0"
|
||||
ws_pricing.cell(row=row, column=4, value=item.months)
|
||||
subtotal_cell = ws_pricing.cell(row=row, column=5, value=item.subtotal)
|
||||
subtotal_cell.fill = draft_fill
|
||||
subtotal_cell.number_format = "#,##0"
|
||||
|
||||
summary_row = len(draft.line_items) + 3
|
||||
ws_pricing.cell(row=summary_row, column=4, value="소계").font = Font(bold=True)
|
||||
ws_pricing.cell(row=summary_row, column=5, value=draft.subtotal).number_format = "#,##0"
|
||||
|
||||
if draft.discount_rate > 0:
|
||||
summary_row += 1
|
||||
ws_pricing.cell(row=summary_row, column=3, value=draft.discount_label)
|
||||
ws_pricing.cell(row=summary_row, column=4, value=f"-{int(draft.discount_rate * 100)}%")
|
||||
disc_cell = ws_pricing.cell(row=summary_row, column=5, value=-draft.discount_amount)
|
||||
disc_cell.number_format = "#,##0"
|
||||
disc_cell.font = Font(color="FF0000")
|
||||
|
||||
summary_row += 1
|
||||
ws_pricing.cell(row=summary_row, column=4, value="합계 (VAT 별도)").font = Font(bold=True, size=12)
|
||||
total_cell = ws_pricing.cell(row=summary_row, column=5, value=draft.total_before_vat)
|
||||
total_cell.font = Font(bold=True, size=12)
|
||||
total_cell.number_format = "#,##0"
|
||||
total_cell.fill = draft_fill
|
||||
|
||||
summary_row += 1
|
||||
ws_pricing.cell(row=summary_row, column=5, value="Andrew 검토 필요").font = Font(color="FF0000", italic=True)
|
||||
|
||||
# -- Sheet 5: Terms --
|
||||
ws_terms = wb.create_sheet("계약 조건")
|
||||
terms = [
|
||||
("결제 조건", "착수금 50% / 완료 후 50%"),
|
||||
("견적 유효기간", "발행일로부터 30일"),
|
||||
("부가세", "별도 (10%)"),
|
||||
("범위 변경", "서면 합의 후 별도 견적"),
|
||||
("계약 해지", "착수 전 전액 환불 / 착수 후 진행분 정산"),
|
||||
("", ""),
|
||||
("D.intelligence", "SMART Marketing Clinic"),
|
||||
("Website", "dintelligence.co.kr"),
|
||||
("담당자", "Andrew Yim"),
|
||||
]
|
||||
for row, (label, value) in enumerate(terms, 1):
|
||||
ws_terms.cell(row=row, column=1, value=label).font = Font(bold=True)
|
||||
ws_terms.cell(row=row, column=2, value=value)
|
||||
|
||||
# Save
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
filename = f"{draft.ref}_{draft.client_name.replace(' ', '_')}_DRAFT.xlsx"
|
||||
filepath = output_dir / filename
|
||||
wb.save(filepath)
|
||||
return filepath
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# CLI entry point
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="D.intelligence Quotation Generator")
|
||||
parser.add_argument("--client", required=True, help="Client name (고객사명)")
|
||||
parser.add_argument("--industry", default="", help="Client industry (업종)")
|
||||
parser.add_argument("--modules", required=True, help="Comma-separated module codes (e.g., A3,T6,G2)")
|
||||
parser.add_argument("--complexity", default="standard", choices=["standard", "complex", "enterprise"],
|
||||
help="Default complexity tier for all modules")
|
||||
parser.add_argument("--renewal", action="store_true", help="Existing client (재계약)")
|
||||
parser.add_argument("--growth-months", type=int, default=3, help="Number of months for Growth modules")
|
||||
parser.add_argument("--output", default="./output", help="Output directory")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
module_list = [(code.strip(), args.complexity) for code in args.modules.split(",")]
|
||||
|
||||
draft = build_quotation(
|
||||
client_name=args.client,
|
||||
modules=module_list,
|
||||
industry=args.industry,
|
||||
is_renewal=args.renewal,
|
||||
growth_months=args.growth_months,
|
||||
)
|
||||
|
||||
filepath = generate_xlsx(draft, Path(args.output))
|
||||
|
||||
print(f"Quotation draft generated: {filepath}")
|
||||
print(f" Reference: {draft.ref}")
|
||||
print(f" Client: {draft.client_name}")
|
||||
print(f" Modules: {', '.join(item.code for item in draft.line_items)}")
|
||||
print(f" Subtotal: {draft.subtotal:,}원")
|
||||
if draft.discount_rate > 0:
|
||||
print(f" Discount: {draft.discount_label} (-{int(draft.discount_rate * 100)}%, -{draft.discount_amount:,}원)")
|
||||
print(f" Total (VAT 별도): {draft.total_before_vat:,}원")
|
||||
print()
|
||||
print("STATUS: DRAFT -- Andrew 검토 대기")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
399
custom-skills/73-dintel-quotation-mgr/desktop/SKILL.md
Normal file
399
custom-skills/73-dintel-quotation-mgr/desktop/SKILL.md
Normal file
@@ -0,0 +1,399 @@
|
||||
---
|
||||
name: dintel-quotation-mgr
|
||||
version: 1.0.0
|
||||
agent-id: "73"
|
||||
agent-corps: D.intelligence Agent Corps
|
||||
description: |
|
||||
Quotation Manager for D.intelligence. Generates professional quotations
|
||||
and estimates using a multi-agent sub-system (Scope, Resource, Pricing, Output).
|
||||
Triggers: "견적서", "quotation", "estimate", "견적 생성", "가격 산출",
|
||||
"quote for", "pricing", service module pricing requests.
|
||||
autonomy: draft-and-wait
|
||||
---
|
||||
|
||||
# D.intelligence Quotation Manager
|
||||
|
||||
> **Agent #73** | `dintel-quotation-mgr` v1.0.0 | D.intelligence Agent Corps
|
||||
|
||||
Generate professional quotations and estimates for D.intelligence service modules using a multi-agent sub-system. Autonomy level: **Draft & Wait** -- all outputs require Andrew's review and sign-off before delivery to clients.
|
||||
|
||||
---
|
||||
|
||||
## Agent Corps Context
|
||||
|
||||
- **Agent #73** -- Quotation Manager (Multi-Agent)
|
||||
- **Collaborates with**: Agent #70 (Brand Guardian) for brand compliance, Agent #71 (Brand Editor) for cover letter copy
|
||||
- **Shared constants**: `dintel-shared/src/dintel/brand.py` (colors, terminology)
|
||||
- **Excel utilities**: `dintel-shared/src/dintel/excel.py` (branded workbook generation)
|
||||
|
||||
---
|
||||
|
||||
## Universal Guardrails
|
||||
|
||||
1. **Never send to clients without Andrew's approval** -- All quotations require Andrew's review.
|
||||
2. **Never delete -- always archive** -- Move outdated quotes to archive; never permanently delete.
|
||||
3. **Never commit pricing without Andrew's sign-off** -- CRITICAL for this agent. All pricing is draft until approved.
|
||||
4. **Korean-first, bilingual notation** -- Korean primary; jargon uses 한글(English) notation on first use.
|
||||
5. **Never cross-reference client data without consent** -- Client data is siloed by account.
|
||||
|
||||
---
|
||||
|
||||
## Multi-Agent Sub-System
|
||||
|
||||
This skill orchestrates 4 sub-agents in sequence. Each sub-agent produces a structured output that feeds the next.
|
||||
|
||||
### Sub-Agent 1: Scope Agent
|
||||
|
||||
**Purpose**: Analyze client requirements and map them to D.intelligence service modules.
|
||||
|
||||
**Inputs**:
|
||||
- Client brief or requirements description (text, email, or meeting notes)
|
||||
- Client industry and company size (if known)
|
||||
- Any specific constraints or preferences
|
||||
|
||||
**Process**:
|
||||
1. Parse the client's needs into discrete workstreams
|
||||
2. Map each workstream to one or more service modules (A1--A6, T1--T7, G1--G4)
|
||||
3. Identify module dependencies (e.g., A3 is prerequisite for T6)
|
||||
4. Flag any ambiguities that need clarification from Andrew
|
||||
5. Check for pre-built package fit (Starter, Standard, Premium, SEO Intensive)
|
||||
|
||||
**Output** (structured):
|
||||
```yaml
|
||||
scope:
|
||||
client_name: "고객사명"
|
||||
industry: "업종"
|
||||
modules:
|
||||
- code: "A3"
|
||||
name: "데이터 분석 (웹·앱)"
|
||||
rationale: "웹사이트 트래픽 및 전환 분석 필요"
|
||||
complexity: "standard | complex | enterprise"
|
||||
- code: "T6"
|
||||
name: "Brand Visibility Treatment"
|
||||
rationale: "검색 노출 최적화 요청"
|
||||
complexity: "complex"
|
||||
dependencies:
|
||||
- from: "A3"
|
||||
to: "T6"
|
||||
type: "prerequisite"
|
||||
package_fit: "SEO Intensive" # or null
|
||||
ambiguities:
|
||||
- "콘텐츠 제작 범위 확인 필요 (블로그만 vs 소셜 포함)"
|
||||
```
|
||||
|
||||
### Sub-Agent 2: Resource Agent
|
||||
|
||||
**Purpose**: Estimate effort hours, project timeline, and team allocation.
|
||||
|
||||
**Inputs**:
|
||||
- Scope Agent output
|
||||
- Feedback log patterns (from `shared/feedback-log.md`)
|
||||
|
||||
**Process**:
|
||||
1. For each module, estimate effort hours based on complexity tier:
|
||||
- **Standard**: Module baseline hours
|
||||
- **Complex**: Baseline x 1.5
|
||||
- **Enterprise**: Baseline x 2.0
|
||||
2. Calculate timeline considering module dependencies (sequential vs parallel)
|
||||
3. Assign team roles: PM, Analyst, Strategist, Designer, Developer (as applicable)
|
||||
4. Apply learned adjustments from feedback log
|
||||
|
||||
**Baseline Effort Hours** (per module):
|
||||
|
||||
| Module | Standard (hours) | Duration |
|
||||
|--------|-----------------|----------|
|
||||
| A1 비즈니스·브랜드 진단 | 40--60 | 2--3주 |
|
||||
| A2 고객·소비자 분석 | 60--80 | 3--4주 |
|
||||
| A3 데이터 분석 (웹·앱) | 60--100 | 3--5주 |
|
||||
| A4 디지털 마케팅 진단 | 40--80 | 2--4주 |
|
||||
| A5 퍼포먼스 마케팅 진단 | 40--60 | 2--3주 |
|
||||
| A6 운영·관리 진단 | 40--60 | 2--3주 |
|
||||
| T1 브랜드 스토리텔링 & 가이드 | 80--160 | 4--8주 |
|
||||
| T2 고객 접점 경험 최적화 | 60--120 | 4--6주 |
|
||||
| T3 디지털 자산 통합관리 | 80--160 | 4--8주 |
|
||||
| T4 콘텐츠 마케팅 | 60--120 | 4--8주 |
|
||||
| T5 광고·전환 최적화 | 60--100 | 3--6주 |
|
||||
| T6 Brand Visibility Treatment | 80--200 | 4--12주 |
|
||||
| T7 운영 시스템·자동화 | 60--120 | 4--8주 |
|
||||
| G1 퍼포먼스 마케팅 | 40--80/월 | 월간 |
|
||||
| G2 콘텐츠 마케팅 대행 | 60--100/월 | 월간 |
|
||||
| G3 모니터링·이슈관리 | 40--60/월 | 월간 |
|
||||
| G4 연간 계약·운영 | 별도 협의 | 12개월 |
|
||||
|
||||
**Output** (structured):
|
||||
```yaml
|
||||
resources:
|
||||
total_hours: 220
|
||||
timeline:
|
||||
total_weeks: 10
|
||||
phases:
|
||||
- phase: "Analysis"
|
||||
weeks: "1--4"
|
||||
modules: ["A3", "A4"]
|
||||
parallel: true
|
||||
- phase: "Treatment"
|
||||
weeks: "5--10"
|
||||
modules: ["T6"]
|
||||
team:
|
||||
- role: "PM"
|
||||
allocation: "20%"
|
||||
- role: "SEO Analyst"
|
||||
allocation: "80%"
|
||||
- role: "Content Strategist"
|
||||
allocation: "40%"
|
||||
```
|
||||
|
||||
### Sub-Agent 3: Pricing Agent
|
||||
|
||||
**Purpose**: Calculate pricing using module rates, apply discount policies, and produce a pricing breakdown.
|
||||
|
||||
**Inputs**:
|
||||
- Scope Agent output (modules, package fit)
|
||||
- Resource Agent output (hours, timeline)
|
||||
- Pricing reference (`shared/pricing-reference.md`)
|
||||
- Feedback log adjustments
|
||||
|
||||
**Process**:
|
||||
1. Look up base price range for each module
|
||||
2. Position within range based on complexity tier:
|
||||
- Standard: 30th percentile of range
|
||||
- Complex: 60th percentile
|
||||
- Enterprise: 90th percentile
|
||||
3. Check discount eligibility (see Discount Policies below)
|
||||
4. Apply highest applicable discount (discounts do NOT stack, except 재계약)
|
||||
5. Calculate subtotal, discount amount, and total (VAT 별도)
|
||||
6. Compare against feedback log for similar scope patterns
|
||||
|
||||
**Module Pricing Table** (VAT 별도):
|
||||
|
||||
| Module | Duration | Price Range |
|
||||
|--------|----------|-------------|
|
||||
| **A1** 비즈니스·브랜드 진단 | 2--3주 | 300--500만원 |
|
||||
| **A2** 고객·소비자 분석 | 3--4주 | 400--700만원 |
|
||||
| **A3** 데이터 분석 (웹·앱) | 3--5주 | 400--800만원 |
|
||||
| **A4** 디지털 마케팅 진단 | 2--4주 | 300--600만원 |
|
||||
| **A5** 퍼포먼스 마케팅 진단 | 2--3주 | 300--500만원 |
|
||||
| **A6** 운영·관리 진단 | 2--3주 | 200--400만원 |
|
||||
| **T1** 브랜드 스토리텔링 & 가이드 | 4--8주 | 500--1,200만원 |
|
||||
| **T2** 고객 접점 경험 최적화 | 4--6주 | 400--800만원 |
|
||||
| **T3** 디지털 자산 통합관리 | 4--8주 | 600--1,500만원 |
|
||||
| **T4** 콘텐츠 마케팅 | 4--8주 | 400--1,000만원 |
|
||||
| **T5** 광고·전환 최적화 | 3--6주 | 400--800만원 |
|
||||
| **T6** Brand Visibility Treatment | 4--12주 | 500--1,500만원 |
|
||||
| **T7** 운영 시스템·자동화 | 4--8주 | 400--1,000만원 |
|
||||
| **G1** 퍼포먼스 마케팅 | 월간 | 200--500만원/월 |
|
||||
| **G2** 콘텐츠 마케팅 대행 | 월간 | 300--600만원/월 |
|
||||
| **G3** 모니터링·이슈관리 | 월간 | 200--400만원/월 |
|
||||
| **G4** 연간 계약·운영 | 12개월 | 별도 협의 |
|
||||
|
||||
**Discount Policies**:
|
||||
|
||||
| Condition | Discount | Stackable |
|
||||
|-----------|----------|-----------|
|
||||
| 3개 모듈 이상 동시 계약 | 15% | No (base) |
|
||||
| Analysis -> Treatment 연계 | 20% | No (base) |
|
||||
| Full cycle (Analysis -> Treatment -> Growth) | 25% | No (base) |
|
||||
| G4 연간 계약 | 월 단가 20% 할인 | No (base) |
|
||||
| 재계약 (기존 고객) | 10% 추가 할인 | Yes (stacks on top of base) |
|
||||
|
||||
> **Rule**: Apply the single highest base discount. If the client is a 재계약 customer, add 10% on top. Discounts never exceed 35% total.
|
||||
|
||||
**Pre-built Packages** (pre-discounted):
|
||||
|
||||
| Package | Modules | Price Range | Discount |
|
||||
|---------|---------|-------------|----------|
|
||||
| **Starter** | A3 + A4 + A5 | 800--1,500만원 | 15% |
|
||||
| **Standard** | Starter + T3/T5/T6 택1 | 1,500--2,800만원 | 20% |
|
||||
| **Premium** | Starter + 2 Treatment + 1 Growth (3개월) | 3,000--5,000만원 | 25% |
|
||||
| **SEO Intensive** | A3 + T6 + G2 (3개월) | 2,000--3,500만원 | 20% |
|
||||
|
||||
**Output** (structured):
|
||||
```yaml
|
||||
pricing:
|
||||
line_items:
|
||||
- module: "A3"
|
||||
name: "데이터 분석 (웹·앱)"
|
||||
base_price: 5600000 # 560만원 (complex, 60th percentile)
|
||||
quantity: 1
|
||||
- module: "T6"
|
||||
name: "Brand Visibility Treatment"
|
||||
base_price: 9000000 # 900만원 (complex)
|
||||
quantity: 1
|
||||
subtotal: 14600000
|
||||
discount:
|
||||
type: "Analysis -> Treatment 연계"
|
||||
rate: 0.20
|
||||
amount: 2920000
|
||||
total_before_vat: 11680000
|
||||
vat_note: "VAT 별도"
|
||||
package_applied: null # or package name
|
||||
```
|
||||
|
||||
### Sub-Agent 4: Output Generator
|
||||
|
||||
**Purpose**: Produce a branded Excel .xlsx file ready for Andrew's review.
|
||||
|
||||
**Inputs**:
|
||||
- All outputs from Sub-Agents 1--3
|
||||
- Brand assets from `dintel-shared/src/dintel/brand.py`
|
||||
- Excel utilities from `dintel-shared/src/dintel/excel.py`
|
||||
|
||||
**Process**:
|
||||
1. Create workbook with branded styling (D.intelligence colors, fonts, logo)
|
||||
2. Generate all sheets (see Output Format below)
|
||||
3. Save as `.xlsx` to the designated output directory
|
||||
4. Notify Andrew that the draft is ready for review
|
||||
|
||||
**Excel Output Format**:
|
||||
|
||||
The generated `.xlsx` file contains the following sheets:
|
||||
|
||||
#### Sheet 1: 표지 (Cover)
|
||||
- D.intelligence logo and brand header
|
||||
- 견적서 (Quotation) title
|
||||
- Client name and date
|
||||
- Quotation reference number: `DI-Q-{YYYYMMDD}-{NNN}`
|
||||
- Validity period: 견적 유효기간 30일
|
||||
|
||||
#### Sheet 2: 서비스 범위 (Scope)
|
||||
- Table of selected modules with:
|
||||
- Module code and name
|
||||
- Description / rationale
|
||||
- Complexity tier
|
||||
- Dependencies noted
|
||||
|
||||
#### Sheet 3: 일정 (Timeline)
|
||||
- Gantt-style timeline with:
|
||||
- Phase breakdown (Analysis / Treatment / Growth)
|
||||
- Module start/end weeks
|
||||
- Milestones and deliverables
|
||||
|
||||
#### Sheet 4: 견적 내역 (Pricing)
|
||||
- Detailed pricing table:
|
||||
- Module code | Module name | Base price | Quantity | Subtotal
|
||||
- Discount row (type, rate, amount)
|
||||
- Total before VAT
|
||||
- VAT note
|
||||
- Grand total placeholder (for Andrew to finalize)
|
||||
- **IMPORTANT**: All price cells must be clearly marked as DRAFT
|
||||
|
||||
#### Sheet 5: 계약 조건 (Terms)
|
||||
- Payment terms: 착수금 50% / 완료 후 50% (standard)
|
||||
- Validity: 견적 유효기간 30일
|
||||
- Scope change policy
|
||||
- Cancellation terms
|
||||
- D.intelligence contact information
|
||||
|
||||
---
|
||||
|
||||
## Workflow: Draft & Wait
|
||||
|
||||
```
|
||||
[1] Client brief received
|
||||
|
|
||||
[2] Scope Agent analyzes requirements
|
||||
|
|
||||
[3] Resource Agent estimates effort & timeline
|
||||
|
|
||||
[4] Pricing Agent calculates costs & discounts
|
||||
|
|
||||
[5] Output Generator creates branded .xlsx
|
||||
|
|
||||
[6] *** STOP -- Draft Ready ***
|
||||
|
|
||||
Andrew reviews in Google Sheets
|
||||
Andrew leaves cell comments (adjustments, notes)
|
||||
|
|
||||
[7] Agent reads feedback -> updates feedback-log.md
|
||||
|
|
||||
[8] If revisions needed -> loop back to relevant sub-agent
|
||||
|
|
||||
[9] Andrew approves -> quote finalized
|
||||
```
|
||||
|
||||
### Draft Markers
|
||||
|
||||
All generated quotations include these markers until Andrew approves:
|
||||
- File name suffix: `_DRAFT`
|
||||
- Watermark text in header: "DRAFT -- 검토 대기"
|
||||
- All price cells highlighted in yellow
|
||||
- Comment on total cell: "Andrew 검토 필요"
|
||||
|
||||
---
|
||||
|
||||
## Feedback Learning Loop
|
||||
|
||||
### How It Works
|
||||
|
||||
1. Andrew opens the `.xlsx` in Google Sheets
|
||||
2. Andrew leaves cell comments with feedback:
|
||||
- Price adjustment: "A3는 이 고객에게 520만원이 적절" (price override)
|
||||
- Scope change: "T4 추가 필요" (add module) or "A6 제외" (remove module)
|
||||
- Timeline note: "T6는 8주 필요" (timeline adjustment)
|
||||
- General note: "이 업종은 보통 Standard 패키지 적용" (pattern note)
|
||||
3. Agent reads comments and logs to `shared/feedback-log.md`:
|
||||
- Date, client industry, original vs adjusted values, reason
|
||||
4. Over time, the feedback log builds a pattern database:
|
||||
- Industry-specific pricing tendencies
|
||||
- Common module combinations
|
||||
- Andrew's preferred discount thresholds
|
||||
|
||||
### Feedback Log Format
|
||||
|
||||
See `shared/feedback-log.md` for the structured format. Each entry records:
|
||||
- Date and quotation reference
|
||||
- Client industry
|
||||
- Adjustment type (price / scope / timeline / discount)
|
||||
- Original value and adjusted value
|
||||
- Andrew's reasoning (from comment text)
|
||||
|
||||
---
|
||||
|
||||
## Invocation
|
||||
|
||||
### Generate a New Quotation
|
||||
|
||||
Provide the client brief and the agent will run all 4 sub-agents:
|
||||
|
||||
```
|
||||
Generate a quotation for [Client Name].
|
||||
|
||||
Requirements:
|
||||
- [Requirement 1]
|
||||
- [Requirement 2]
|
||||
- [Requirement 3]
|
||||
|
||||
Industry: [업종]
|
||||
Company size: [중소/중견/대기업]
|
||||
Existing client: [Yes/No]
|
||||
```
|
||||
|
||||
### Review Feedback
|
||||
|
||||
After Andrew has reviewed in Google Sheets:
|
||||
|
||||
```
|
||||
Review feedback for quotation DI-Q-20260308-001.
|
||||
Update feedback-log.md with Andrew's comments.
|
||||
```
|
||||
|
||||
### Revise a Quotation
|
||||
|
||||
```
|
||||
Revise quotation DI-Q-20260308-001 based on Andrew's feedback.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key References
|
||||
|
||||
| Resource | Path |
|
||||
|----------|------|
|
||||
| Brand constants | `../../dintel-shared/src/dintel/brand.py` |
|
||||
| Excel utilities | `../../dintel-shared/src/dintel/excel.py` |
|
||||
| Pricing reference | `../shared/pricing-reference.md` |
|
||||
| Feedback log | `../shared/feedback-log.md` |
|
||||
| Service Map | `/Users/ourdigital/Documents/D.intelligence Service Package/00_SERVICE-MAP.md` |
|
||||
| Pricing Packages | `/Users/ourdigital/Documents/D.intelligence Service Package/06_PRICING-PACKAGES.md` |
|
||||
| Brand Guide | `/Users/ourdigital/Documents/D.intelligence Service Package/08_BRAND-GUIDE-v1.1.md` |
|
||||
| Generate script | `../code/scripts/generate_quotation.py` |
|
||||
54
custom-skills/73-dintel-quotation-mgr/shared/feedback-log.md
Normal file
54
custom-skills/73-dintel-quotation-mgr/shared/feedback-log.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Feedback Log
|
||||
|
||||
> Quotation Manager learning log -- records Andrew's corrections and adjustments.
|
||||
> Over time, this log builds patterns for more accurate estimates.
|
||||
|
||||
---
|
||||
|
||||
## Log Format
|
||||
|
||||
Each entry follows this structure:
|
||||
|
||||
```yaml
|
||||
- date: "YYYY-MM-DD"
|
||||
quotation_ref: "DI-Q-YYYYMMDD-NNN"
|
||||
client_industry: "업종"
|
||||
adjustments:
|
||||
- type: "price | scope | timeline | discount | terms"
|
||||
module: "A3" # or null for general
|
||||
original: "560만원"
|
||||
adjusted: "520만원"
|
||||
reason: "Andrew's comment text"
|
||||
pattern_note: "Optional generalized learning"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Entries
|
||||
|
||||
_No entries yet. This log will be populated as Andrew reviews quotation drafts._
|
||||
|
||||
<!--
|
||||
Example entry (for reference):
|
||||
|
||||
- date: "2026-03-08"
|
||||
quotation_ref: "DI-Q-20260308-001"
|
||||
client_industry: "이커머스"
|
||||
adjustments:
|
||||
- type: "price"
|
||||
module: "A3"
|
||||
original: "560만원"
|
||||
adjusted: "520만원"
|
||||
reason: "이커머스 업종은 A3 데이터 분석 범위가 표준보다 좁음"
|
||||
- type: "scope"
|
||||
module: "T4"
|
||||
original: null
|
||||
adjusted: "추가"
|
||||
reason: "콘텐츠 마케팅 포함 필요"
|
||||
- type: "discount"
|
||||
module: null
|
||||
original: "20%"
|
||||
adjusted: "25%"
|
||||
reason: "Full cycle 계약 확정으로 할인율 상향"
|
||||
pattern_note: "이커머스 업종은 A3 단가를 range 하단에 가깝게 책정"
|
||||
-->
|
||||
@@ -0,0 +1,82 @@
|
||||
# Pricing Quick Reference
|
||||
|
||||
> D.intelligence Service Module Pricing | VAT 별도
|
||||
|
||||
---
|
||||
|
||||
## Individual Module Pricing
|
||||
|
||||
### Analysis (진단) -- Phase 1
|
||||
|
||||
| Code | Module | Duration | Price Range |
|
||||
|------|--------|----------|-------------|
|
||||
| A1 | 비즈니스·브랜드 진단 | 2--3주 | 300--500만원 |
|
||||
| A2 | 고객·소비자 분석 | 3--4주 | 400--700만원 |
|
||||
| A3 | 데이터 분석 (웹·앱) | 3--5주 | 400--800만원 |
|
||||
| A4 | 디지털 마케팅 진단 | 2--4주 | 300--600만원 |
|
||||
| A5 | 퍼포먼스 마케팅 진단 | 2--3주 | 300--500만원 |
|
||||
| A6 | 운영·관리 진단 | 2--3주 | 200--400만원 |
|
||||
|
||||
### Treatment (처방) -- Phase 2
|
||||
|
||||
| Code | Module | Duration | Price Range |
|
||||
|------|--------|----------|-------------|
|
||||
| T1 | 브랜드 스토리텔링 & 가이드 | 4--8주 | 500--1,200만원 |
|
||||
| T2 | 고객 접점 경험 최적화 | 4--6주 | 400--800만원 |
|
||||
| T3 | 디지털 자산 통합관리 | 4--8주 | 600--1,500만원 |
|
||||
| T4 | 콘텐츠 마케팅 | 4--8주 | 400--1,000만원 |
|
||||
| T5 | 광고·전환 최적화 | 3--6주 | 400--800만원 |
|
||||
| T6 | Brand Visibility Treatment | 4--12주 | 500--1,500만원 |
|
||||
| T7 | 운영 시스템·자동화 | 4--8주 | 400--1,000만원 |
|
||||
|
||||
### Growth (성장) -- Phase 3
|
||||
|
||||
| Code | Module | Duration | Price Range |
|
||||
|------|--------|----------|-------------|
|
||||
| G1 | 퍼포먼스 마케팅 | 월간 | 200--500만원/월 |
|
||||
| G2 | 콘텐츠 마케팅 대행 | 월간 | 300--600만원/월 |
|
||||
| G3 | 모니터링·이슈관리 | 월간 | 200--400만원/월 |
|
||||
| G4 | 연간 계약·운영 | 12개월 | 별도 협의 |
|
||||
|
||||
---
|
||||
|
||||
## Complexity Pricing Position
|
||||
|
||||
| Tier | Percentile in Range | Multiplier (hours) |
|
||||
|------|--------------------|--------------------|
|
||||
| Standard | 30th percentile | 1.0x |
|
||||
| Complex | 60th percentile | 1.5x |
|
||||
| Enterprise | 90th percentile | 2.0x |
|
||||
|
||||
---
|
||||
|
||||
## Discount Policies
|
||||
|
||||
| Condition | Discount | Stackable |
|
||||
|-----------|----------|-----------|
|
||||
| 3개 모듈 이상 동시 계약 | 15% | No (base) |
|
||||
| Analysis -> Treatment 연계 | 20% | No (base) |
|
||||
| Full cycle (Analysis -> Treatment -> Growth) | 25% | No (base) |
|
||||
| G4 연간 계약 | 월 단가 20% 할인 | No (base) |
|
||||
| 재계약 (기존 고객) | 10% 추가 할인 | Yes (stacks on base) |
|
||||
|
||||
**Rule**: Apply the single highest base discount. 재계약 stacks on top. Max total discount: 35%.
|
||||
|
||||
---
|
||||
|
||||
## Pre-built Packages
|
||||
|
||||
| Package | Modules | Price Range | Discount |
|
||||
|---------|---------|-------------|----------|
|
||||
| Starter | A3 + A4 + A5 | 800--1,500만원 | 15% |
|
||||
| Standard | Starter + T3/T5/T6 택1 | 1,500--2,800만원 | 20% |
|
||||
| Premium | Starter + 2 Treatment + 1 Growth (3개월) | 3,000--5,000만원 | 25% |
|
||||
| SEO Intensive | A3 + T6 + G2 (3개월) | 2,000--3,500만원 | 20% |
|
||||
|
||||
---
|
||||
|
||||
## Standard Terms
|
||||
|
||||
- **Payment**: 착수금 50% / 완료 후 50%
|
||||
- **Validity**: 견적 유효기간 30일
|
||||
- **VAT**: 별도 (10%)
|
||||
Reference in New Issue
Block a user