# Project plan — forecast (RGBC Forecast Control)

Evidence date: 2026-10-14.

Source repository: `git@bitbucket.org:overdrive/forecast.git`.

Inspected revision: `master` at `6aac1d2` (2026-09-01, "Merged in feature/customer-group-forecast-model (pull request #1)").

There is no prior Silicon Ark folder for this project. The source repository has no README, project plan, or requirements document. This plan describes what the repository contains. It does not decide what the product should become.

The onboarding issue recorded last commit `072a6da` (2026-02-05). That commit is an ancestor of current `master`. Two later commits and a merge moved region grouping from `strRegionDesc2` to customer group. See [Branch reality](#branch-reality).

## Product

The Visual Studio solution is **RGBC Forecast** (`RGBC Forecast.sln`). The master page title is **RGBC Forecast Control**. The assembly title is `RGBC_Forecast`. The footer version string is `1.0.3` with date `4 April 2012`, plus `[Dev]` or `[Live]` from the compile configuration.

The application is an ASP.NET Web Forms site used to plan and adjust brand forecasts by customer group, then queue generation of quantity forecasts (QF) down to product and customer. Volumes in the grids and reports are labelled 9L (`dbl9lTotal`, `dblBudget9l`, report captions "9L").

What the letters RGBC expand to is **Unknown / Requires Confirmation**. The connection-string name `SuperbowlConnectionString` and the legacy environment variable `SUPERBOWL_CONNECTION_STRING` are **Implemented**. What "Superbowl" refers to is **Unknown / Requires Confirmation**.

Provenance: product name is **Implemented** in `Admin.Master`, `Index.aspx`, and `AssemblyInfo.vb`. Forecast behaviour is **Implemented** in `Planning.aspx.vb`, `Adjustments.aspx.vb`, `Branding.vb`, and `QFGenerator.vb`. The phase comments at the top of `Admin.Master.vb` are **Documented** inside source comments, not in a separate specification.

## Branch reality

Default branch is `master`. `origin/HEAD` points at `master`. One other remote branch remains: `origin/feature/customer-group-forecast-model`. That branch was merged by pull request #1.

| Commit | Date | Subject |
|---|---|---|
| `e13eb5e` | 2023-01-23 | init |
| `83ed5c6` | 2026-01-19 | bitbucket-pipelines.yml created online with Bitbucket |
| `5a6b3fd` | 2026-01-19 | sonar-project.properties created online with Bitbucket |
| `b8d6322`, `905cfea`, `ddfb17d`, `7570f0f` | 2026-01-19 | bitbucket-pipelines.yml edited online with Bitbucket |
| `f95e71a` | 2026-02-03 | Security Enhancements |
| `072a6da` | 2026-02-05 | Security Enhancements env config updates and bug fix. |
| `b4c83ce` | 2026-08-28 | feat: Switch Forecast model region grouping from strRegionDesc2 to Customer Group |
| `fb64e84` | 2026-08-31 | fix: Resolve namespace resolution for SecureConfig in expression builder and db helper |
| `6aac1d2` | 2026-09-01 | Merged in feature/customer-group-forecast-model (pull request #1) |

The 2023 init commit is the first commit in this clone. Whether the 2010–2015 application history lived in Team Foundation Server before that is **Inferred** from the solution's `TeamFoundationVersionControl` section (`http://tfs01:8080/tfs/vs_projects_2018`) and from dated comments in `Admin.Master.vb` starting `20100903`. That earlier host is **Unknown / Requires Confirmation**.

## Scope in the repository

In scope, because the code implements it:

- Windows-identity login against `mstUser` / `mstUserGroupForecast`, with session flags for view, edit, and special rights.
- Planning a future fiscal year's forecast by customer group, including sales rhythm, growth, and a copy-from-brand option.
- Adjusting the current model by customer group while an open season is active.
- Queueing a `BrandQF` row in `sysCronJob` when a plan is saved or adjustments are applied.
- In-process QF generation and stock-period update classes (`QFGen`), callable from the sandbox page. The Planning and Adjustments buttons do not call `QFGen` directly; they insert the cron row.
- Forecast report and RSM report, with HTML-as-Excel export.
- Open-season date windows, user-to-brand assignment, and adjustment notes.
- SQL Server access through an environment variable or `.env` file. Credentials are not stored in `Web.config`.

Out of scope for this repository, because no implementation was found:

- A worker that reads `sysCronJob` and runs `QFGen`. The UI tells the user the brand "will be processed shortly."
- User administration screens. Users, groups, and brands are read from SQL Server.
- A public API, mobile client, message queue, or cloud deploy manifest.
- Automated tests.

## System architecture

One IIS-hosted ASP.NET Web Forms application. Language is Visual Basic. Target framework in the project file is .NET Framework 4.6.2. `Web.config` sets `compilation targetFramework="4.6.1"`. That mismatch is **Implemented** and **Requires Confirmation** as to which framework the live site actually runs.

```text
Browser
  → Index.aspx (Windows logon name)
  → Admin.Master (session gate, menu)
  → Planning / Adjustments / Reports / Open Season / My Brands
  → Branding, BrandReport, QFGen
  → db (shared SqlConnection)
  → SQL Server (Superbowl connection string)
```

`Application_Start` loads `.env` from the parent of the application folder, then system environment variables override those values. Pages and `SqlDataSource` controls resolve `<%$ EnvConnectionStrings:SuperbowlConnectionString %>` through `EnvConnectionStringsExpressionBuilder`.

There is no separate service project. `QFGen` lives in the web project. Generation that the user starts from Planning or Adjustments is a database job, not an in-request call. `zSandbox.aspx` can construct `QFGen` for a hardcoded year and brand, and the generate path is behind `If False`.

## Major components

| Component | Role | Evidence |
|---|---|---|
| `Index.aspx` | Login button. Clears session, then looks up `Request.LogonUserIdentity.Name` | `Index.aspx.vb` |
| `Admin.Master` | Menu, version label, session required, Dev-only Sandbox item, view-right content gate | `Admin.Master`, `Admin.Master.vb` |
| `Branding` | Fiscal dates, customer-group sync, grids for actual / planned / adjusted, period map | `Branding.vb` |
| `Planning` | Future-year plan, sales rhythm, save into `dwfQFPlan` and `dwfQFAdjustment` | `Planning.aspx.vb` |
| `Adjestments` | Class name is spelled this way. Open-season edit, save, recalc, apply | `Adjustments.aspx.vb` |
| `QFGen` | Split a group-level QF into product/customer 9L rows and update `stkProductPeriod` | `QFGenerator.vb` |
| `BrandReport` | Forecast report and RSM report | `brand.reports.vb` |
| `db` | Shared SQL connection and string-built commands | `db.generic.vb` |
| `SecureConfig` | `.env` and environment-variable connection strings | `App_Code\VB\SecureConfig.vb` |
| `sysCronJob` | Queue table written by this app. Reader is not in this repo | `ProjectFunctions.vb` |

## Milestones recorded in source comments

These are historical notes in code, not a forward plan. Provenance: **Documented** as comments. Whether each note matches production history is **Unknown / Requires Confirmation**.

| Comment date | Note in `Admin.Master.vb` or nearby |
|---|---|
| 2010-09-03 | Project start, version `0.0.0` |
| 2010-09-30 | Apply adjusted figures; Dev group only until QF generation sorted |
| 2010-10-08 | `Apply()` complete, using a dummy `dwfQF2` table |
| 2010-10-13 to 2010-10-25 | Planning interface built; stock-control update still disabled |
| 2011-06-28 | Version `1.0.2`. Recalc regions. `stkProductPeriod` update marked active. Comment says "LIVE!" |
| 2012-04-04 | Version `1.0.3`. Customer region data fix in `Branding.New` |
| 2015-02-16 | Temporary workaround comment: "remove FALSE later" |
| 2015-05-29 | "unlocked all QFs" |
| 2026-02-03 to 2026-02-05 | Connection strings moved to environment variables. `TestDbConnection.aspx` added |
| 2026-08-28 | Region grouping switched from `dwdCustomer.strRegionDesc2` to customer group (`strGroupName` synced from `mstCustomer.strCustomerGroup`) |

The footer still shows version `1.0.3` and date `4 April 2012`. `AssemblyInfo.vb` is `1.0.0.0` / `1.0.0.1` with description `3 Sep 2010`. Those strings were not updated for the 2015 or 2026 changes.

## Implementation plan as the code stands

There is no written forward plan in the repository. The implemented operating loop is:

1. Company fiscal calendar comes from `mstCompany` where `CompanyID = 1`.
2. A user with special rights builds a plan for a fiscal year after the current one.
3. Saving the plan replaces `dwfQFPlan` and `dwfQFAdjustment` for that brand and year, deletes matching rows from the QF fact table named by `dwfQFTable` (setting value `dwfQF`), and inserts a `BrandQF` cron job.
4. During an open season, a user with edit rights changes group-level adjustments. A user with special rights can queue apply.
5. `QFGen`, when something runs it, spreads the adjustment using last completed fiscal sales shares and writes `stkProductPeriod.dblQF`.

Who or what polls `sysCronJob` is **Unknown / Requires Confirmation**.

## Known dependencies

| Dependency | Evidence |
|---|---|
| .NET Framework 4.6.2 project, 4.6.1 compilation attribute | `RGBC Forecast.vbproj`, `Web.config` |
| ASP.NET Web Forms, IIS, Windows authentication mode | `Web.config` `authentication mode="Windows"` |
| SQL Server (`System.Data.SqlClient`) | `db.generic.vb` |
| Environment variable `RGBC_FORECAST_CONNECTION_STRING`, with fallback `SUPERBOWL_CONNECTION_STRING` | `.env.example`, `SecureConfig.vb` |
| Optional `SQL_CONNECTION_DEBUG` and `SQL_CONNECTION_RELEASE` | `SecureConfig.vb`. No caller of `GetSQLConnectionDebug` / `GetSQLConnectionRelease` was found outside that class |
| Bitbucket Pipelines SonarQube scan on `master` | `bitbucket-pipelines.yml` |
| Sonar project key `overdrive_forecast` | `sonar-project.properties` |
| Visual Studio 2017 solution format (`VisualStudioVersion = 15.0`) | `RGBC Forecast.sln` |

No NuGet `packages.config` and no third-party assembly references were found. References are framework assemblies only.

## Current project status

**Implemented and on `master`:** the Web Forms forecast console described above, environment-based connection strings, and customer-group rollups.

**Partial:**

- Home page prepares a "Forecast Report by Focus Brands" and then does not run it. The `BrandReport` construction is commented out (`Home.aspx.vb`).
- `Help.aspx` and `AdjustmentsComments.aspx` are empty pages. Planning help is a spreadsheet link and a screenshot (`HelpPlanning.aspx`).
- Open Season always inserts `refBrandID = 0`. The grid can display a brand name when `refBrandID` is not 0, so older per-brand rows can exist in data. The uniqueness check is `If False`.
- Past-period cells were meant to lock. The condition is `period < today And False`, so the lock branch does not run (`Branding.colourDataRow`).
- `QFGen.GenerateBrand` is not called from Planning or Adjustments. Sandbox generation is compiled behind `If False`.

**Not in this repository:** deployment site, production URL, database schema scripts, the cron worker, and tests.

**CI:** SonarQube analysis on `master` only. Pipeline step size is `4x`. No build, test, or deploy step.

## Human confirmation

- Expansion of RGBC, and whether Superbowl is the shared commercial database.
- Where the site is hosted and which connection string production uses.
- The process that consumes `sysCronJob` rows of type `BrandQF`.
- Whether July–June column headings match `mstCompany.strFYStart` / `strFYEnd` for company 1.
- Whether leaving past periods editable (`And False`) is still the approved rule.
- Whether `refBrandID = 0` for every new open season is still the approved rule.
- Live user-group names besides the strings `Dev` and `RSM`.
- Which table owns `blnView`, `blnEdit`, and `blnSpecial`.
