## [What-If Scenario Webapp](web_app:VjedpBD)

A standard Dataiku webapp that allows commercial excellence teams to test alternative budget and channel constraint configurations and immediately compare results against the baseline recommendation output. Parameters are entered via a simple form, saved as Dataiku project variables, and a single button triggers the what-if optimization scenario.

For guidance on building standard webapps in Dataiku, refer to the [Dataiku Standard Webapp Documentation](https://doc.dataiku.com/dss/latest/webapps/standard.html).

### How It Works

1. The user adjusts budget and channel cap parameters in the form
2. Clicking **Save & Run What-If Scenario** posts the values to the Python backend via `/set_variables`
3. The backend saves the values as `_whatif` project variables and immediately triggers the [whatifoptimization](scenario:WHATIFOPTIMIZATION) scenario
4. The scenario re-runs the MILP optimizer with the new parameters and writes results to the what-if outputndataset
5. A stacking recipe produces `solver_metadata_scenarios` combining baseline and what-if results with a `scenario` label column
6. The comparison charts in the Commercial Monitoring dashboard refresh from the updated dataset


### Parameters

The form is organised into three sections:

**Budget Controls**

| Parameter | Min | Max | Default |
|---|---|---|---|
| Field Budget (rep visits + phone calls) $ | 5,000 | 25,000 | 17,000 |
| Media Budget (webinar + digital + email) $ | 1,000 | 10,000 | 3,000 |

**Channel Caps**

| Parameter | Min | Max | Default |
|---|---|---|---|
| Max Rep Visits / week | 20 | 160 | 80 |
| Max Phone Calls / week | 20 | 200 | 100 |
| Max Webinars / week | 10 | 80 | 40 |
| Max Digital Ads / week | 10 | 120 | 60 |
| Max Emails / week | 50 | 500 | 300 |
| Min Digital Ads / week (floor) | 0 | 60 | 15 |

**Fixed Constraints**

| Parameter | Min | Max | Default |
|---|---|---|---|
| Max Total Actions / week | 100 | 500 | 420 |
| Max Contacts per HCP / week | 1 | 3 | 1 |


### Variables Written

On save the webapp writes the following project variables:
```
budget_field_per_period_whatif
budget_media_per_period_whatif
max_total_actions_per_period_whatif
max_contacts_per_hcp_per_period_whatif
max_rep_visits_per_period_whatif
max_phone_calls_per_period_whatif
max_webinars_per_period_whatif
max_digital_ads_per_period_whatif
max_emails_per_period_whatif
min_digital_ads_per_period_whatif
```

See the [Project Variables](article:27) article for the full variable reference.

### Backend Routes

| Route | Method | Purpose |
|---|---|---|
| `/set_variables` | POST | Saves `_whatif` variables and triggers `WHATIFOPTIMIZATION` scenario |
| `/get_variables` | GET | Returns current values of all `_whatif` variables - used to pre-populate the form on load |

### Implementation Notes

- The Python backend uses `dataiku.default_project_key()` to resolve the project - do not rely on `dataiku.get_custom_variables()["projectKey"]` as this can return `None` in some Dataiku versions
- Variable saving and scenario triggering happen in a single `/set_variables` call - variables are committed before the scenario runs to ensure the optimizer reads the updated values
- `scenario.run()` triggers asynchronously and returns immediately. The button re-enables once the trigger call returns, not when the scenario completes. Users should allow 20–30 seconds before refreshing the comparison dashboard
- On page load call `/get_variables` via `$.getJSON` to pre-populate the form with the current saved values so users always see the last configuration that was run