---
description: Automated opp hygiene audit from CSV snapshots — all EMEA segments
inclusion: manual
---

# Opp Hygiene Audit

## Scope

This steering doc is designed for **all DGs across all EMEA segments** (SUP, ENT, SMB, ISV, STRAT, MMT, etc.). Configuration is per-user so each DG gets their own alias, campaign, and preferences stored locally.

## When to Use

When the user drops an opp hygiene CSV (from MR Clean, IQS dashboard, or similar export) and asks to check/fix opps.

## Step 0: Welcome & Configuration

All opp hygiene files (config, generated Excel checklists, logs) are stored in the `opp-hygiene/` folder in the workspace root. This keeps them organized and out of the way.

Configuration is stored per-user in `opp-hygiene/config.json`.
This file is user-specific and should be added to `.gitignore` so each DG keeps their own settings when sharing the steering doc.

On first run, create the `opp-hygiene/` folder if it doesn't exist. Also generate a `opp-hygiene/README.md` with a quick start guide covering setup steps, how to run the workflow, what Kiro can fix vs. what needs manual SFDC work, and tips (reconfig, config location, Excel output). Then check for the config file.

### First Run (config file does NOT exist)

Greet the user and collect configuration. If a CSV has already been provided, try to auto-detect the alias from the `alias` column and pre-fill it in the prompt.

Display this welcome message:

```
🧹 Opp Hygiene Audit — First-time setup!

I need a few things before I can run audits for you. You'll only need to do this once — I'll remember your answers for next time.

1. **Your alias** — Who are we running this for?
   {If alias detected from CSV: `Detected from CSV: <alias> — press Enter to confirm, or type a different one.`}
   {If no CSV yet: `e.g. your Amazon login alias`}
2. **Your segment** — Which segment are you in?
   Options: SUP, ENT, SMB, ISV, STRAT, MMT
   {If detectable from opp names in CSV (e.g. "DE - SUP - DG"): `Detected: <segment> — press Enter to confirm.`}
3. **Default campaign** — Which campaign should I attach to opps missing one?
   {Show segment-appropriate suggestion — see Campaign Defaults by Segment below}
   → Press Enter to keep the suggestion, or paste a different campaign name/ID.
4. **Point of Entry preferences** — Any default PoE I should use when I can't infer one from context?
   Common options: IT Optimization, Cloud Strategy/ Compete, Data on AWS, Analytics and AI/ML, Modern Application Development, Other Migration
   → Or type "infer" and I'll guess from opp name/context each time.
5. **Auto-fix permission** — Should I:
   a) 🟢 Fix everything I can automatically, then show you what I did
   b) 🟡 Show me a plan first, then fix after your OK
   c) 🔴 Read-only mode — just generate the checklist, don't touch any opps

Drop your CSV anytime — I'll wait for your config answers before making any changes.
```

#### Campaign & PoE Configuration

During first-run setup, ask the user to provide their team's campaign lookup table. This gets stored in the per-user config file — NOT in this steering doc.

**For campaigns:** Ask the user to paste or describe their team's campaign tags and IDs. Store them as a `campaigns` array in the config file. Each entry has: `category`, `tag`, `when_to_use`, `id`, and `signal_keywords` (opp name patterns that should trigger this campaign).

**For PoE:** The PoE inference rules are universal across EMEA (same SFDC picklist values). The keyword-to-PoE mapping is defined in the "PoE Inference Rules" section under Step 3 and does NOT need per-user config.

If the user doesn't have a campaign list handy, ask them to provide just a single `default_campaign_id` as fallback — they can add the full table later via "reconfig".

After the user answers, save their config to `opp-hygiene/config.json`:
```json
{
  "user_alias": "<alias>",
  "segment": "<SUP|ENT|SMB|ISV|STRAT|MMT>",
  "default_campaign_id": "<campaign_id>",
  "default_poe": "<poe_or_infer>",
  "fix_mode": "<auto|plan_first|read_only>"
}
```

If the user says "just use defaults" or "skip", use these fallbacks:
- alias: auto-detect from CSV `alias` column (if available), otherwise **ask — do not assume**
- segment: auto-detect from opp names in CSV (if available), otherwise **ask — do not assume**
- campaign: use segment default if known, otherwise **ask — do not assume**
- PoE: `infer`
- fix_mode: `plan_first`

### Subsequent Runs (config file EXISTS)

Read `opp-hygiene/config.json` and load the saved config. Display a short confirmation:

```
🧹 Opp Hygiene Audit — Using your saved config:
- Alias: `<alias>`
- Segment: `<segment>`
- Campaign: `<campaign_id>`
- PoE: `<poe>`
- Fix mode: `<fix_mode>`

→ Type "reconfig" to change settings, or just drop your CSV and I'll start.
```

If the user says "reconfig", re-run the full first-run prompt and overwrite the config file.
Otherwise, proceed directly to Step 1 with the loaded config.

### Session Config Values
- `user_alias` — used for filtering and meeting checks
- `segment` — user's EMEA segment (SUP, ENT, SMB, ISV, STRAT, MMT)
- `default_campaign_id` — campaign ID to use for missing campaigns
- `default_poe` — default Point of Entry or "infer"
- `fix_mode` — one of `auto`, `plan_first`, `read_only`

## CSV Format Expected

CSV with columns including: `alias`, `link`, `opp_name`, and boolean (0/1) columns for hygiene fields like `has description`, `has campaign`, `has customer name in opp name`, `has economic buyer`, `has products`, etc.

## Automated Workflow

### Step 1: Read the CSV and identify all opps with at least one `0` field

**Important:** Always parse the CSV using Python's `csv.DictReader` (or pandas `read_csv`). This ensures columns are accessed by header name, not by position — opp names contain commas inside quotes which will break naive splitting. Never try to parse CSV by splitting on commas manually.

Parse the CSV. For each opp, collect which fields are `0`. Group by issue type.

### Step 2: Plan & Permission

**If fix_mode is `plan_first` (default):**

Before making ANY changes, present a summary table:

```
📋 Hygiene Fix Plan

Found X opps with issues. Here's what I'd fix:

| Fix Type | # Opps | Example |
|----------|--------|---------|
| Add campaign | 5 | Opp "DE-SUP-DG-Acme-Migration" |
| Generate description | 3 | Opp "FR-ENT-DG-Beta-DataLake" |
| Add products | 2 | Opp "UKI-SMB-DG-Gamma-Compute" |
| Set Point of Entry | 4 | Opp "DE-SUP-DG-Delta-AI" |
| Fix opp name | 1 | Opp "Migration Project" → "DE-SUP-DG-Delta-Migration" |
| Generate details | 3 | Opp "NL-ISV-DG-Epsilon-Storage" |

⚠️ These X items need manual SFDC work (I can't fix them):
- 2 opps missing economic buyer
- 1 opp missing acceptance status
- 3 opps missing primary contact

→ Type "go" to execute all fixes, "skip [type]" to skip a category, or "read-only" to just get the checklist.
```

Wait for explicit user confirmation before proceeding.

**If fix_mode is `auto`:**
Execute fixes immediately, then report what was done.

**If fix_mode is `read_only`:**
Skip Step 3 entirely, go straight to Excel generation.

### Step 3: Fix what can be fixed via MCP

Only execute if user has given permission (auto mode or explicit "go").

**Fixable fields:**

| Issue | Fix |
|-------|-----|
| Missing campaign (`has campaign = 0`) | Add the configured `default_campaign_id` via `update_opportunity` with `campaignId` |
| Missing description (`has description = 0`) | Pull context from the CSV description column, opp name, next steps, and account details. Generate a 3-5 sentence description via `update_opportunity` |
| Missing products (`has products = 0`) | Search for the relevant AWS product and add a line item with estimated MRR |
| Missing details (`has details = 0`) | Generate an Opportunity Details paragraph from available context via `update_opportunity` |
| Missing PoE (`has PoE = 0`) | Use configured `default_poe` or infer from opp name/context using the PoE Inference Rules below. Set via `update_opportunity` with `pointOfEntryName` |
| Missing customer name in opp name (`has customer name in opp name = 0`) | Look up the official SFDC account name via `search_accounts` or opp details, then update the opp name to include it via `update_opportunity` with `name` |

#### PoE Inference Rules

When `default_poe` is `infer`, scan the opp name, tags, and description for keywords and map to the correct SFDC `pointOfEntryName` value:

| PoE (SFDC value) | Trigger Keywords / Signals | Description |
|-------------------|---------------------------|-------------|
| `AWS Account Trigger` | "onboarding", "activate", "new account", first-time AWS usage | Initial onboarding or enablement to start using AWS services |
| `Innovation` | "IoT", "digital twin", "smart", "emerging", "new technology", "innovation" | Customer interested in emerging technologies or new technology adoption |
| `Analytics and AI/ML` | "AI", "ML", "machine learning", "Bedrock", "SageMaker", "GenAI", "LLM", "#GENAI", "fraud detection", "NLP" | Customer specifically interested in AI/Machine Learning solutions |
| `Marketplace` | "Marketplace", "SaaS Listing", "#PI", "go-to-market" | Customer exploring AWS Marketplace solutions or GTM support |
| `Other Migration` | "migration", "migrate", "#EXTMIG", "from Azure", "from GCP", "from on-prem", "lift and shift" | Customer planning to move workloads to AWS |
| `Technical Consultation` | "architecture review", "best practices", "optimization", "scaling", "DevOps", "cost optimization", "performance" | Customer seeks guidance on architecture, deployment, or best practices |
| `Security` | "security", "compliance", "WAF", "GuardDuty", "IAM", "encryption", "HIPAA", "SOC", "PCI" | Customer seeking guidance on security and compliance |

**Inference priority:** If multiple keywords match, use this priority order:
1. `Other Migration` (if any migration signal is present, migration takes precedence)
2. `Analytics and AI/ML` (if AI/ML is the primary workload)
3. `Marketplace` (if Marketplace listing is the project)
4. `Security` (if security is the primary focus)
5. `Technical Consultation` (general architecture/optimization)
6. `Innovation` (emerging tech)
7. `AWS Account Trigger` (new accounts only)

If no keywords match, fall back to `Technical Consultation` as the safest default.

After each batch of fixes, report what was changed:
```
✅ Fixed 5 opps:
- Added campaign to: Opp1, Opp2, Opp3, Opp4, Opp5
- Generated description for: Opp1, Opp3
- Set PoE for: Opp2, Opp4, Opp5
```

**Fixable with contact lookup:**

| Issue | Fix |
|-------|-----|
| Missing contact role (`has contact role = 0`) | Search for contacts on the account via `search_contacts` with `accountId` filter. If contacts exist, add the best match (prioritize senior titles: CEO, CTO, Founder, Head of, VP, Director) as a contact role with role `Decision Maker` using `add_opportunity_contact_role`. If no contacts exist, flag for manual SFDC work. |
| Missing primary contact (`has primary contact = 0`) | Same as contact role — add the contact via `add_opportunity_contact_role` with `isPrimary: true`. Note: the "Primary" flag on the contact role IS settable via MCP using the `isPrimary` parameter. |

**NOT fixable via MCP (always flag for manual SFDC work):**

| Issue | Why |
|-------|-----|
| Missing economic buyer | Requires contact selection |
| Missing acceptance status | Not updatable via MCP |
| Missing partner flag | Not updatable via MCP |

### Step 4: Generate Excel checklist

After fixing (or skipping fixes), generate an Excel (`opp-hygiene/Opp_Hygiene_Checklist_CW{week}.xlsx`) with 3 sheets:

1. **Full Hygiene Matrix** — all opps with ✅/❌ per field, color-coded, filterable, with issue count and hygiene score
2. **Action Items** — only opps with remaining issues, listing missing fields and SFDC links, sorted by lowest score
3. **Summary** — field-level counts of missing items, whether MCP-fixable or manual, score distribution

Use `openpyxl` with:
- AWS dark header (`#232F3E`)
- Red fill for ❌, green fill for ✅
- Hyperlinks to SFDC opp pages
- Auto-filters on all sheets

### Step 5: Report summary

After all fixes, report:
- Config used (alias, campaign, PoE, fix mode)
- How many opps were fixed (and what was fixed)
- How many issues remain for manual SFDC work
- Link to the Excel file

## Key Business Rules

- Default campaign: configurable per-user and per-segment (see Step 0 and Campaign Defaults by Segment table)
- Opp names must contain the official SFDC account name (verify via `search_accounts`)
- Opp naming convention varies by segment — detect the pattern from existing opp names in the CSV (e.g. `DE - SUP - DG - Customer - Project`) and follow it when fixing names
- Every opp needs a meeting logged by the configured `user_alias` within 30 days before opp creation
- All 6 MEDDPICC fields must be set at creation (metrics, decisionCriteria, decisionProcess, paperProcess, primaryCompetitor, implicateThePain)
- Products use MRR as unitPrice (Amount = MRR × 12 = ARR)
- Acceptance status, economic buyer, and opp name changes are always manual SFDC work

## Hygiene Score Requirements (100%)

When generating the Excel checklist, calculate and display the hygiene score per opp based on these weighted categories:

### Opportunity Naming — 15%
| Criterion | Weight |
|-----------|--------|
| Region in name | 3.75% |
| Tag in name | 3.75% |
| Customer name in name | 3.75% |
| Project info in name | 3.75% |

### Qualification — 15%
**Pre-May 2025 opps: BANT framework**
| Criterion | Weight |
|-----------|--------|
| Budget | 3.75% |
| Authority | 3.75% |
| Need | 3.75% |
| Timeline | 3.75% |

**Post-May 2025 opps: MEDPIC framework**
| Criterion | Weight |
|-----------|--------|
| Metrics | 2% |
| Economic Buyer | 2% |
| Decision Criteria | 3% |
| Decision Process | 2% |
| Paper Process | 2% |
| Implicate Pain | 2% |
| Champions | 2% |

### Next Steps — 15%
| Criterion | Weight |
|-----------|--------|
| Entry date present | 3.75% |
| Tag presence | 3.75% |
| Alias included | 3.75% |
| ETA specified | 3.75% |

### Partner Information — 10%
| Criterion | Weight |
|-----------|--------|
| Partner involvement flagged | 2.5% |
| Stage alignment | 2.5% |
| Project sharing | 2.5% |
| Rejection reasons | 2.5% |

### Sales Details — 21%
| Criterion | Weight |
|-----------|--------|
| Close date set | 5% |
| Acceptance status set | 5% |
| Campaign source attached | 5% |
| Competitor info populated | 3% |
| Primary contact assigned | 3% |

### Basic Details — 21%
| Criterion | Weight |
|-----------|--------|
| Point of Entry set | 5% |
| Description populated | 3% |
| Details populated | 3% |
| Products / ARR attached | 4% |
| Non-stalled status | 6% |

### Score in Excel Output
- Add a **Hygiene Score** column to the Full Hygiene Matrix sheet showing the % score per opp
- Color-code: 🟢 ≥80%, 🟡 60-79%, 🔴 <60%
- Include score distribution in the Summary sheet
- Sort Action Items by lowest score first (worst opps at top)
