# Technical documentation — ieb-inde-6

Evidence date: 2026-10-12. Inspected revision: `main` at `d9e4836`.

Credential values, SMTP passwords, SMS passwords, and encryption passphrases are omitted on purpose.

## What this repository is

Two commits on `main` (both 2025-07-09) add a working copy of **Evolution Software Unified Framework** customised as **INDE-6 / Postbox**.

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

`sonarqube_scan.bat` was named by the onboarding scan and is not in this revision.

The nested folder name is repeated: `INDE-6/Evolution Software Unified Framework/Evolution Software Unified Framework/`. Paths below are relative to that inner folder unless they start with `INDE-6/`.

## Application structure

ASP.NET Web Forms site. Pages are `.aspx` with code-behind. Reusable UI is `.ascx` under `controls/`. Much of the screen layout is not hardcoded: a canvas points at a module, and a surface's fields are rows the generic renderer draws. Postbox adds hand-written behaviour beside that generator output.

| Area | Path | Notes |
|---|---|---|
| INDE-6 site | `core_custom/INDE-6/` | Website project in the solution. Publish profile `App_Data/PublishProfiles/INDE-6.pubxml`. |
| Generic site | `core/` | Solution binds it to `http://localhost:45935`. |
| Dev site | `core-dev/` | Second website project. |
| Postbox classes | `core_custom/INDE-6/App_Code/classes/PostboxHelper.cs`, `PostboxEmails.cs`, `PostboxDownloadTracking.cs`, `PostboxCanvasNums.cs` | The behaviour described in the PRD. |
| Exam classes | `App_Code/classes/examHandler.cs`, `examNums.cs` | Examination authoring and compliance. |
| Generated surfaces | `controls/surface_custom/*_{form,grid,view}.ascx` | Form code-behind files are about 22,000 lines. They are generator output plus a custom-include region. |
| File explorer | `controls/module/fileExplorer.ascx.cs` | Telerik provider. Postbox upload, mail, and download hooks live here. |
| Shared surface save | `controls/surface/surface_form.ascx.cs` | INDE-6 regional-moderator block. |
| Library | `library/library.csproj` | Assembly `framework_library`, namespace `framework_library`, target v4.5, output `..\components\`. |
| Business | `business/business.csproj` | Enums in `business/enums/pNums.cs`. |
| Service | `service/framework_service.svc` | WCF service host, `Debug="true"`. |
| SQL project | `data/data.sqlproj` | Scripts grouped by client code. |

`App_Code` is compiled by the website, not by the class-library projects.

## Frameworks and languages

- C# and ASP.NET Web Forms on .NET Framework 4.5 (`library` `TargetFrameworkVersion`). `Web.config` compilation `targetFramework="4.5"`. A commented `httpRuntime` mentions 4.6.2.
- SQL Server scripts and a SQL Server Data Tools project (`data.sqlproj`).
- Telerik.Web.UI (file explorer, upload progress, dialogs, spell check).
- Ajax Control Toolkit, EPPlus, NReco.VideoConverter, ICSharpCode.SharpZipLib, Ionic.Zip. The readme says several of these DLLs must be re-added from `components` or `packages` before a build.
- jQuery UI, DataTables, and date-picker assets under `css/` and `js/`.
- Pipeline image `maven:3.8.3-jdk-11` is only there to run the Sonar scanner. The application is not a Maven build.

`Web.config` sets `globalization` culture `en-US` and app setting `defaultCulture` `en-ZA` (key duplicated). `DateFormat` app setting is `yyyy-MM-dd hh:mm tt`.

## Solutions and build outputs

`EvolutionSoftwareUnifiedFramework.sln` includes library, business, service, mobile, constructor, exporter, scheduler, data, core, core-dev, and `core_custom\INDE-6`.

`INDE-6.sln` sits beside it. It was not diffed project-by-project. The solution that names the INDE-6 website is the large framework solution (project name `INDE-6`, path `core_custom\INDE-6\`).

Publish profile:

- Method: file system.
- Configuration: Release.
- URL: `D:\Blue Sky\Publish`.
- Precompile, updateable, merge each folder, delete existing files.
- Excludes `App_Data`, and folders `images` and `upload`.

No Bitbucket step builds or publishes this profile.

`release/1.0.0.1` and `release/1.0.5` each contain `files.zip` and `scripts.zip`. They were not unpacked.

`library/obj` absolute path lists point at `C:\DEV work\NEW_IEB\INDE-2\...`. Those files are build leftovers from another working copy, checked in.

## Data access

Active connection app setting `conn` uses catalog `Framework_INDE-6_Demo` on a remote SQL host. Commented alternatives use catalog `Framework_INDE-6` (integrated security and a SQL login). The host address and passwords are in `Web.config` and are omitted here.

Application data access goes through `xData` / `xDataHelper` (`framework_library` and local helpers):

- `pal_` prefix for configuration objects (users, canvases, surfaces, templates, setup).
- `publ_` prefix for published surface tables (`publ_GroupPostbox`, `publ_SchoolContacts`, `publ_FileExplorerDownloads`, `publ_SubjectManagement`).
- `qt_` prefix appears in the subject-management rename script (query table).

INDE-6 scripts in `data/Scripts/INDE-6`, in version order:

| Script | Effect evidenced by the SQL text |
|---|---|
| 1.0.0 | Insert Postbox template type and school-contacts email template. |
| 1.0.1 | Set `emailSubjectToSchoolContacts`. |
| 1.0.2 | Insert IEB-contacts email template. |
| 1.0.3 | Set `emailSubjectToIEBContacts`. |
| 1.0.4 | Set `submissionsEmail`. |
| 1.0.5 | Publish `FileExplorerDownloads` and create `publ_FileExplorerDownloads`. |
| 1.0.6 | Correct school contacts table. |
| 1.0.7 | Publish `GroupPostboxSchools` and create `publ_GroupPostboxSchools`. |
| 1.0.8 | Publish `GroupPostbox` and create `publ_GroupPostbox`. |
| 1.0.9 | Create `sp_INDE-6_GetSurfaceModulePicklist`. |
| 1.0.10 | Update a `pal_SurfaceField` row. |
| 1.0.11 | Add a column on file metadata. |
| 1.0.12 | Update group-postbox-schools fields. |
| 1.0.13 | Insert group-postbox surface fields (assessment materials, records, correspondence, linked schools, and school canvas name fields). |
| 1.0.14 | Create `sp_INDE-6_GetChildPublishedSurfaceDataCount`. |
| 1.0.15 | Add unique subject name, rename cluster level to level. |
| 1.0.16 | Create `sp_INDE6_GetSurfaceQueryDataPaged`. |
| 1.0.17 | Update a `pal_SurfaceField` row. |
| 1.0.18 | Insert regional-moderation subject email templates. |
| 1.0.19 | Alter those templates. |

`PostboxHelper` calls `xDataHelper.GetSurfaceQueryDataPaged`. Whether that method executes `sp_INDE6_GetSurfaceQueryDataPaged` was not confirmed by reading the library body. **Requires Confirmation.**

Other script folders in `data/Scripts` belong to other client codes (CAPI, CHUU, CLOS, INDE-1, INDE-2, OLIV, REAP, ROBI, SCHO, SHEN, SHOU, STUD) plus archived framework majors. They are in this repository because the SQL project is shared. They are not INDE-6 migrations.

## File storage

Explorer files live under the site path `~/upload/explorer/{folder}`.

`FileProtectionHandler` (`App_Code/FileProtectionHandler.cs`) is an `IHttpHandler` and `IReadOnlySessionState`, registered in `system.webServer/handlers` as:

```text
name=FileProtectionHandler  verb=*  path=upload  type=Handler.FileProtectionHandler
```

GET without a session user redirects to `{WebAddy}/admin`, except the root URL and the admin URL. The handler then transmits the mapped file and sets a content type from the extension (method `GetContentType`, not reproduced here).

`maxRequestLength` is `10048` KB. JSON max length is `50000000`. Anonymous identification is enabled. Session timeout is 60 minutes. `runAllManagedModulesForAllRequests` is true.

Upload folders also exist for banner, file, gallery, image, products, and temp. The publish profile excludes `upload`, so published output does not replace server uploads.

## Mail, SMS, and service endpoints

`system.net/mailSettings` SMTP host `smtp.evolutionsoftware.co.za`, port 25, from `mailer@evolutionsoftware.co.za`. Password omitted.

App settings used by Postbox mail:

| Key | Role |
|---|---|
| `WebAddy` | `http://localhost:60629`. Logo and welcome links. |
| `from`, `support`, `admin`, `cc`, `bcc` | Evolution Software mailboxes. |
| `subject` | `IEB (INDE-6 Local) - {content}` |
| `website` | Stored twice: `IEB (INDE-6 Local)` and `IEB CRM`. |
| `conn` | Demo catalog. See data access. |

Setup columns read at runtime (not app settings): `communicationEmail`, `submissionsEmail`, `emailSubjectToSchoolContacts`, `emailSubjectToIEBContacts`, `sendingEmailName`, `code`.

WCF client endpoints in the INDE-6 `Web.config`:

- `http://localhost:58913/framework_service.svc` — name `Iframework_service`.
- `http://service.ieb.co.za/framework_service.svc` — name `Iframework_serviceLive`.
- Binding `wsHttpBinding`, security mode `None`, large reader quotas, send timeout 10 minutes.

SMS client: `http://sms.netgen.co.za/SMS_V2.asmx`. App settings `smsU` and `smsP` hold the gateway user and password. Values omitted.

MediSwitch QA gateway URLs are present. `MediSwitchResponses` is `0`. A web reference folder `App_WebReferences/MediswitchWebService` exists. `App_Code/MediSwitch.cs` is about 2,300 lines and was not treated as Postbox behaviour.

`loyaltyEmail` is `0`. `getCountriesFromWebService` is `0`.

## Authentication

No ASP.NET `<authentication>` mode element was found in the INDE-6 `Web.config` section that was read. Sign-in UI is the framework page `Admin_SignIn.aspx`. The session key used by the file handler and the explorer is `user` (`oUser`).

Moderator creation (`PostboxHelper.CreateUserForModerator`) writes `pal_` `oUser` through `xData.SaveTyped`, encrypts the password and later the welcome reset code with passphrases compiled into the source, and sets `isReset` so the welcome link can complete a reset. The passphrases are omitted.

`encryption` is a framework type. The algorithm was not re-derived.

## Background work, queues, storage, monitoring

- Postbox school and IEB notification mail is fired with `Task.Run`. There is no queue, retry table, or worker service for that task. A process recycle can drop it. **Inferred** from `Task.Run` with no persist step.
- Welcome mail and regional-moderation mail call `communication.SendAnEmail` on the request thread.
- `tools/scheduler` is a project with a service reference to `framework_service` and a MediSwitch web reference. Its schedule was not traced.
- `SchedulerTool` at the inner solution root is a separate folder. Its role was not traced.
- No application log sink, APM, or health endpoint was identified beyond `exception.HandleException` calls.
- SonarQube is the only monitoring artefact in git. See below.

## Security notes from the tree

These are observations, not a penetration test.

- SQL, SMTP, and SMS credentials are stored in plaintext in `core_custom/INDE-6/Web.config`. Commented connection strings in the same file also contain a SQL password.
- Encryption passphrases for new moderator passwords and welcome links are string literals in `PostboxHelper.cs` and `PostboxEmails.cs`.
- The WCF client binding uses `security mode="None"` for both the localhost and `service.ieb.co.za` endpoints (HTTP, not HTTPS).
- `compilation debug="true"` is checked in.
- `FileProtectionHandler` path is `upload` without a `*` wildcard. Coverage of files under `/upload/explorer/` needs a runtime check.
- Surface filters in `PostboxHelper` concatenate unique subject names and school postbox names into SQL filter text. Quotes in the school postbox name are doubled. Other characters are not parameterised in the filter string that was read.
- `CopyDirectory` and file replication use paths from canvas names that were stripped of a fixed character set, not from a free-form upload path, for the create-canvas case. Upload replication uses stored canvas names and the uploaded file name.

## Development and testing

Readme setup (written for INDE-1 and then "all projects"):

1. Re-add `EPPlus.dll` and `NReco.VideoConverter.dll` on the library project.
2. On each web project, add AjaxControlToolkit, Telerik.Web.UI, and SharpZipLib from `components`.
3. Reinstall NuGet package `Microsoft.CodeDom.Providers.DotNetCompilerPlatform`.
4. INDE-2 additionally needs Ionic.Zip. The INDE-6 explorer uses `Ionic.Zip`, so that reference matters for this site even though the readme labels the step INDE-2.

Local URLs that appear in the tree, which are not necessarily all in use:

| URL | Where |
|---|---|
| `http://localhost:60629` | `WebAddy` |
| `http://localhost:45935` | `core` project in the solution |
| `http://localhost:58913/framework_service.svc` | WCF client endpoint |

No PHPUnit, NUnit, or MSTest `[TestMethod]` was found. `Test.aspx` is a page, not an automated test. `tools/CEP/CEP.ConsoleTests` is a console project about quotes, not an INDE-6 test suite.

`Web.Debug.config` exists next to `Web.config`. Transform contents were not compared line by line.

## Sonar and pipeline

`INDE-6/bitbucket-pipelines.yml`:

- Clone depth 50.
- Branches `main` and `develop`, and every pull request.
- One step, "SonarQube analysis", image `maven:3.8.3-jdk-11`, size `8x`.
- Pipe `sonarsource/sonarqube-scan:3.0.2` with `SONAR_HOST_URL` and `SONAR_TOKEN`.
- Extra args force embedded Java, a 4 GB heap, exclusions for `*.test.js`, `node_modules`, and `vendor`, sources `.`, and `sonar.projectKey=my-project`.

`INDE-6/sonar-project.properties` contains only:

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

The pipeline key overrides the properties file when both are passed as scanner arguments. **Requires Confirmation** of which project actually receives scans.

There is no `develop` branch in the remote that was fetched. The pipeline is still configured to scan it.

## Source layout note for agents

Generated `*_form.ascx.cs` files are too large to treat as the specification. Postbox rules that are safe to trace are concentrated in:

- `App_Code/classes/Postbox*.cs`
- `App_Code/classes/examHandler.cs` and `examNums.cs` (examination module)
- `controls/module/fileExplorer.ascx.cs` (upload, download, mail)
- `controls/surface/surface_form.ascx.cs` around the `INDE-6` / `RegionalModerators` condition
- `controls/surface_custom/GroupPostbox_form.ascx.cs` method `SaveSurfaceFormCustom`
- `data/Scripts/INDE-6/*.sql`
- `core_custom/INDE-6/Web.config` and `INDE-6/ReadME.txt`
