# Technical documentation — ieb

Evidence date: 2026-10-13. Inspected revision: `main` at `193927fc`.

Credential values, SMTP passwords, SMS passwords, connection-string passwords, encryption keys, and the hardcoded sign-in secret are omitted on purpose.

Paths are relative to `Evolution Software Unified Framework/Evolution Software Unified Framework/` unless they start at the repository root.

## What this repository is

`main` of `git@bitbucket.org:overdrive/ieb.git` is the Evolution Software Unified Framework plus 32 tenant websites. History on `main` is 39 commits from 2025-01-21 to 2026-08-04. The source import is `18e2d86` (2025-02-05).

```text
.gitignore
ReadME.txt
bitbucket-pipelines.yml
sonar-project.properties
Evolution Software Unified Framework/
  Evolution Software Unified Framework/
    *.sln
    BuildProcessTemplates/
    SchedulerTool/
    business/  components/  core/  core-dev/  core_custom/
    data/  library/  mobile/  packages/  release/
    service/  tools/
```

The nested folder name is repeated. A checkout into a long Windows path cannot materialise every file: vendored NuGet content under `core_custom/PROP-1/packages` and `packages/Microsoft.CodeDom.Providers.DotNetCompilerPlatform.*` exceeds MAX_PATH. Those blobs are still in git. This document was written from `git show` and `git ls-tree`, not from a complete working tree.

The onboarding scan also named `repos/`, `sonar-project.old`, and `sonarqube_scan.bat`. They are not in this revision.

## Application structure

ASP.NET Web Forms. Pages are `.aspx` with code-behind. Reusable UI is `.ascx` under `controls/`. Canvas and surface layout is data-driven. Tenant-specific behaviour is C# under `core_custom/{code}/App_Code` and `controls/surface_custom`, plus handwritten regions inside generated surface files. The INDE-1 examination form code-behind is on the order of 17,000 lines.

| Area | Path | Notes |
|---|---|---|
| Generic site | `core/` | Solution binds it to `http://localhost:45935` |
| Dev site | `core-dev/` | Second website project |
| Tenant sites | `core_custom/{CODE}/` | 32 codes. Inventory in `project-plan.md` |
| Library | `library/library.csproj` | Assembly `framework_library`, `TargetFrameworkVersion` v4.5 |
| Business | `business/business.csproj` | v4.5. References the library |
| Service | `service/framework_service.svc` | WCF website project |
| SQL project | `data/data.sqlproj` | SSDT. Also `Framework_STUD-1.bak` |
| Email worker | `tools/EmailQueueProcessor/` | Windows service. In `INDE-6.sln` only |
| Mobile | `mobile/mobile.csproj` | Xamarin-related project file `GetXamarin.xambe` is present. The app was not reviewed |
| Unified solution | `EvolutionSoftwareUnifiedFramework.sln` | Shared projects plus a subset of tenants, ending at INDE-1 in the project-name list. Does not reference `INDE-2` |

`App_Code` is compiled by the website, not by the class libraries.

`core/App_Code` contains `DataTableResultSet.cs`, `DataTables.cs`, `Extensions.cs`, `Loyalty.cs`, `MediSwitch.cs`, `jQueryHandler.cs`. Tenant sites add their own `App_Code` classes (for example `examHandler.cs`, `PostboxEmails.cs`).

## Frameworks and languages

- C# and ASP.NET Web Forms. `core` and INDE-1 compilation `targetFramework="4.5"`, `debug="true"`.
- `library` and `business` target .NET Framework 4.5.
- INDE-6 `Web.config` mentions `httpRuntime targetFramework="4.6.2"` inside the stock template comment. The compilation element read on that file is 4.5.
- SQL Server scripts and a SQL Server Data Tools project.
- Telerik.Web.UI, Ajax Control Toolkit, EPPlus, ICSharpCode.SharpZipLib, Newtonsoft.Json, Spire (PDF, XLS, license), PdfMetamorphosis. Prebuilt copies of `framework_business.dll` and `framework_library.dll` are under `components/`.
- `ReadME.txt` says `NReco.VideoConverter.dll` must be re-added. `components/` lists `NReco.VideoConverter.xml` and does not list the dll.
- The readme also says to reinstall `Microsoft.CodeDom.Providers.DotNetCompilerPlatform`. Those packages are vendored under `packages/`.
- Ionic.Zip is called out for INDE-2 only.
- jQuery, DataTables, and related assets live under each site's `css/` and `js/`. They were not inventoried file by file.
- Pipeline image `maven:3.8.3-jdk-11` runs the Sonar scanner only.

`Web.config` `defaultCulture` is `en-ZA` on the files that were read. INDE-6 `DateFormat` is `yyyy-MM-dd hh:mm tt`.

A sibling snapshot document (`silicon_ark/ieb-inde-1`) records `targetFramework="4.8"` for that other repository. This tip's INDE-1 and `core` configs are 4.5.

## Solutions

Per-tenant solution files exist for AFRI-1, ASSE-1, CAPI-1, CHUU-1, CLOS-1, DISA-1, FAST-2, GLOB-1, INDE-1 through INDE-6, JEWE-1, LIGS-1, OLIV-1, PROP-1, REAP-1, SCHO-1, SHEN-1, SHOU-1, SPAC-1, STUD-1, and TVET-3.

No own `.sln` for BASE-1, BASE-2, BLUE-1, DEMO-1, EVOL-1, EVOL-2, or INDE-7. The unified solution does include BASE-1, BASE-2, BLUE-1, DEMO-1, EVOL-1, EVOL-2, and INDE-1 as website projects.

`INDE-6.sln` projects: business, library, service, constructor, scheduler, the INDE-6 website, and EmailQueueProcessor.

`EvolutionSoftwareUnifiedFramework.sln` also lists solution folders for scripts, releases, `1.0.0.1`, archive major 1, components, and custom. The `core` website project uses an IIS URL (`http://localhost:45935`) rather than a folder path.

TFS bindings are still in the tree (`*.vspscc`, `BuildProcessTemplates/*.xaml` for Azure continuous deployment, the default TFS 11 template, the lab template, and the upgrade template). No current Azure or TFS build definition was found outside those templates. Whether anyone still uses them is **Unknown / Requires Confirmation**.

## Data access

Application data access goes through `xData` (`framework_business`) into `dynamicInteraction` / `dataInteraction` (`framework_library`).

- Callers pass a table prefix. Sign-in and the email queue pass `pal_`.
- `dynamicInteraction.ProcessInteraction` takes a connection key (default `conn`), a transactional flag, the prefix, and a collection flag.
- The WCF operation `ProcessInteraction` accepts the same shape as bytes.

Active connection app setting is `conn`. Commented alternatives are often named `connLive`. Catalog names per tenant are in `project-plan.md`. Hosts and passwords are omitted.

INDE-6's active `conn` uses integrated security against a local desktop data source. A commented pair above it contains a SQL login and a remote host. That secret is committed and should be rotated. It is not copied here.

`data/Scripts` holds per-client SQL plus archived framework majors. There is no script folder for INDE-3, INDE-4, INDE-5, or INDE-7. There is a `ROBI-1` script folder and no `core_custom/ROBI-1`.

`Framework_STUD-1.bak` is a SQL Server backup in git. It was not restored.

INDE-1 maintenance scripts that are not under `data/Scripts` live at `core_custom/INDE-1/scripts/sql/` (dedupe, subject-name backfill, AET backup lookups, duplicate listing). Nothing in the website runs them automatically.

## Email queue processor

| Item | Value |
|---|---|
| Project | `tools/EmailQueueProcessor/EmailQueueProcessor.csproj` |
| Service class | `EmailQueueProcessorService` |
| Service name | `IEB Email Queue Processor` |
| Solution | `INDE-6.sln` only |
| Config file in git | None. Defaults are in code |
| Interval | `EmailQueue_ProcessIntervalMinutes`, default 2 |
| Work | `xEmailQueue.ProcessQueueAsync` |

Queue objects are `oEmailQueue` and `oEmailQueueLog` in `library/objects/oEmailQueue.cs`. Persistence prefix `pal_`. No `CREATE TABLE` script is in git. Retry handling does not persist `retryCount` or `scheduledFor`, and the processor never selects status Retry. See `business-rules.md` BR-022 to BR-024.

Postbox call sites are `core_custom/INDE-6/App_Code/classes/PostboxEmails.cs`.

## Authentication

`Admin_SignIn.aspx.cs` (copied per tenant):

1. Hardcoded bypass builds an in-memory AdminUser. Secret omitted. Present in `core`, `core-dev`, and 31 tenant copies. PROP-1 did not match the bypass email.
2. Otherwise the submitted password is encrypted with a hardcoded key (omitted) and matched to `pal_User.password` together with email and `isActive = 1`.
3. `customerCode` must equal setup `code`, or must be `EVOL-1`, which is allowed on every instance.
4. The `oUser` is stored in `Session["user"]`.

There is no ASP.NET `<authentication mode="...">` element in the `Web.config` files that were parsed. Session is the application session, not Forms authentication. A `GoogleLogin` web method exists on the same page and was not traced.

`SessionHeartbeat.ashx` is present. Its timeout rules were not read.

`silicon_ark/SHOU-1` documents BCrypt and lockout on the later `shou-1` repository (tip 2026-09-22). This tree does not contain that design.

INDE-1 adds a second check on the examination form and view: users below SuperUser with subject role 0 are redirected. See `prd.md` FR-005.

## WCF service

`Iframework_service`:

- `ProcessInteraction(byte[] interactionData, string connectionKey, bool isTransactional, string tablePrefix, bool isCollection)`
- `GetVersion(string customerCode, string licenceKey, string versionNo, string file)` returns `byte[]`
- `SaveVersion(byte[] versionData, string versionNo, string file)` returns `bool`

`service/Web.config` catalogs found: `Framework_EVOL-1`, `Framework_REAP-1`. Several tenant configs also contain `service.ieb.co.za`. The client binding was not re-read for this document. Sibling `ieb-inde-*` notes describe `security mode="None"` on that client. **Requires Confirmation** that this tip's bindings are unchanged.

`business/classes/licenceHandler.cs` exists. Licence acceptance rules were not traced.

## Other integrations

| Integration | Where | Notes |
|---|---|---|
| SMTP | `library/classes/communication.cs` | TLS 1.2, TLS 1.1, and TLS are assigned before `Send` (`1ee1420`) |
| SendEasy | `business/Service References/send_easy`, `xSendEasy.cs` | Generated SOAP client. `smsU` / `smsP` app settings |
| Mediswitch | `core/App_Code/MediSwitch.cs`, gateway app settings | INDE-6 QA URLs are active; live URLs are commented |
| Country ASMX | `www.webservicex.net` keys | INDE-6 switch `getCountriesFromWebService` is `0` |
| PayGenius | `library/Payment/*`, `objects/PayGeniusModels/*` | Client types. No call site was traced |
| Google Sheets | `business/handlers/GoogleSheetsHelper.cs`, `SchedulerTool/GoogleSheetImports.cs` | `SchedulerTool/GoogleSheetAPISecretes.json` is committed. Contents omitted. The filename spells "Secretes" |
| Google sign-in | `Admin_SignIn.GoogleLogin` | Not traced |

`business/client_secrets.json` is also in the business project tree. Contents were not opened for this document and must not be copied into tickets.

## File storage

Tenant sites keep an `upload/` tree. GLOB-1's tree in git includes calendar files, invoices, quotes, receipts, statements, and gallery images from 2016. Those binaries are committed. They were not opened.

INDE-1 attachment behaviour in the sibling document maps files under `~/upload/{folder}/file/` and `~/upload/{folder}/image/`. That layout was not re-audited across all 32 tenants.

## Background jobs

| Job | Host | Schedule evidence |
|---|---|---|
| Email queue | Windows service `IEB Email Queue Processor` | Timer, default 2 minutes. No installer project was seen |
| Loyalty email | App settings `loyaltyEmail`, `loyaltyEmailAddy`, `loyaltyEmailHour` | INDE-6 sets the switch to `0` and the hour to `20`. The sender class was not read |
| `tools/scheduler` and `SchedulerTool` | WinForms / console-style tools | Not traced beyond the file list |

There is no web cron, Hangfire, or queue broker in the projects that were listed.

## Pipeline, Sonar, and deployment

`bitbucket-pipelines.yml` runs on branches `main` and `develop`, and on all pull requests. Clone depth 50. One step, size 8x, image `maven:3.8.3-jdk-11`, pipe `sonarsource/sonarqube-scan:3.0.2`.

The step passes `SONAR_HOST_URL` and `SONAR_TOKEN` from repository variables, and extra args that include `-Dsonar.projectKey=my-project` and `-Dsonar.sources=.`. Exclusions: `**/*.test.js`, `**/node_modules/**`, `**/vendor/**`.

`sonar-project.properties` contains only:

```text
sonar.projectKey=overdrive_ieb_8345eef9-efa7-4cfa-bc4a-5a046ec95189
```

The pipeline key `my-project` and the properties-file key disagree. **Requires Confirmation** which one the scanner keeps. There is no `develop` branch on the remote at inspection; the pipeline still names it.

The pipeline does not compile the .NET solution and does not publish a website.

`release/1.0.0.1` and `release/1.0.5` each contain `files.zip` and `scripts.zip`. Not unpacked.

Publish profiles were not enumerated for all tenants. The INDE-1 snapshot document lists Dropbox and `C:\Projects\ieb_publish` profiles in the other repository. Those profiles were not re-opened here.

## Security

Items below are committed on `main`. Values are intentionally absent from this file.

| Issue | Where | Notes |
|---|---|---|
| Hardcoded administrator bypass | `Admin_SignIn.aspx.cs` in `core`, `core-dev`, and 31 tenants | In-memory AdminUser, `recId` -1, no database row. PROP-1 did not match the email literal |
| Hardcoded password encryption key | Same sign-in method | Passed to `encryption` before the `pal_User` lookup |
| Commented SQL login | INDE-6 `Web.config` `conn` comment, and likely the same pattern in other tenants | Includes a password and a host. Rotate |
| SMS, SMTP, and admin mailbox app settings | Tenant `Web.config` `smsU`, `smsP`, `from`, `admin`, `support`, `cc`, `bcc` | Values omitted |
| Google client secrets | `SchedulerTool/GoogleSheetAPISecretes.json`, `business/client_secrets.json` | Not reproduced |
| Mediswitch and other service URLs over HTTP or with `security mode` not re-checked | Tenant configs and WCF clients | Sibling docs report `security mode="None"` for `service.ieb.co.za`. Confirm on this tip |
| `debug="true"` | `core` and INDE-6 compilation | Left on in the committed config |
| EVOL-1 users pass the customer-code check on every instance | `Admin_SignIn.aspx.cs` | Comment in source: "allow on all instances" |
| SQL built by string concatenation | External-moderator picklist query | `customerCode` is concatenated into the SQL text |
| Binaries and uploads in git | `components/*.dll`, `core_custom/*/upload`, `Framework_STUD-1.bak` | Large unreviewed payloads |
| `.gitignore` | Repository root | Bitbucket's default template (Node, Java, Python, logs, media). It does not ignore `.vs`, `obj`, `Bin`, `*.pfx`, `Web.config`, or `*.json` secrets |

No test project and no dependency-audit config were found.

## Development and testing process

`ReadME.txt` is the build note:

1. Library project: re-add EPPlus and NReco.VideoConverter.
2. INDE-1 through INDE-7: re-add AjaxControlToolkit, Telerik.Web.UI, and SharpZipLib.
3. Reinstall `Microsoft.CodeDom.Providers.DotNetCompilerPlatform` from the package manager console.
4. INDE-2: Ionic.Zip NuGet and a dll reference.

There is no solution-level test project, no CI compile, and no seed process in git beyond the SQL scripts. How a developer chooses which `.sln` to open is **Inferred**: open `{CODE}.sln` for a tenant that has one, otherwise the unified solution.

`core` is bound to `http://localhost:45935`. INDE-6 `WebAddy` in the config that was read is `http://localhost:60629`. Other tenants were not collected.

## Monitoring

No application-insights, health-check, or log-shipping project was found. `exception.HandleException` is the in-app error path used by sign-in and the email queue. Where those exceptions are written was not traced. The email service also logs start, stop, and each run by calling `HandleException` with a synthetic `Exception` whose message is a status sentence.

SonarQube is the only external analysis hook, and it scans the whole tree (subject to the key discrepancy above), including generated surface files and vendored packages.

## Related repositories

Do not treat these as the same git tip:

| Repository | Silicon Ark | How it differs |
|---|---|---|
| `ieb-inde-1.git` … `ieb-inde-6.git` | `ieb-inde-1` … `ieb-inde-6` | Snapshots from about July 2025. This `main` has later INDE-1 commits and already contains the Postbox queue |
| `ieb_template.git` | `ieb_template` | Different library (`EvoSoft_Lib`). Not this framework |
| `shou-1.git` | `SHOU-1` | Fork that continued to 2026-09-22 with password hashing and lockout |

## Unknown / requires confirmation

- Which tenant sites are still deployed, and from which repository.
- Whether `pal_EmailQueue` and `pal_EmailQueueLog` exist in the INDE-6 database.
- Which Sonar project key is the one that receives scans.
- The `feature/ieb-client-proposals` diff (parent `7c05b557` is outside the inspected `main` history).
- Full canvas permission model, Google login, PayGenius call sites, scheduler behaviour, and mobile app status.
- Whether PROP-1 sign-in removed the hardcoded bypass or never had it.
