# PRD — ieb_template (Evolution Software Library)

Evidence date: 2026-10-12. Source: `git@bitbucket.org:overdrive/ieb_template.git`, `main` `493c34f` (2025-02-05).

Provenance labels: **Documented**, **Implemented**, **Inferred**, **Planned**, **Unknown**.

No formal PRD existed in the repository or in `silicon_ark/ieb_template/` before this file. Requirements below are recovered from the sample page, `xData`, and `EvoSoft_Lib`. They are not a new product decision.

Mailbox addresses in config files are omitted. The files that hold them are named.

## Product purpose

A developer opens a Visual Studio 2015 solution named EvolutionSoftwareLibrary. The shared library maps a C# type to a SQL Server table, sends mail, and offers file and ID helpers. The sample website lets someone maintain rows in `evo_User` with no sign-in. Two desktop tools read a local SQL catalog named `EvolutionFramework`: one writes a C# class file, the other writes an XML export of one table.

**Implemented** in `EvolutionSoftwareLibrary.sln`, `SampleWebsite/Default.aspx`, `Sample_Business/classes/xData.cs`, `BaseTools/EvoSoft_Constructor/frmConstructer.cs`, and `BaseTools/EvoSoft_DataExporter/ExportData/ExportData.cs`.

There is no README. A written product purpose is **Unknown**. The assembly product string is "Evolution SoftWare Global Library" (**Documented** in `BaseLibrary/Properties/AssemblyInfo.cs`). The Bitbucket project name `ieb_template` does not appear in the source.

## Users and roles

| Actor | What the code distinguishes | Provenance |
|---|---|---|
| Anonymous web visitor | `Web.config` sets `anonymousIdentification enabled="true"`. `Default.aspx` has no login, role check, or session user | **Implemented** |
| Desktop operator | Constructor and exporter start a WinForms window and use Windows integrated security against catalog `EvolutionFramework` | **Implemented** |
| Library caller | Any code that references `EvoSoft_Lib` or `Sample_Business`. The sample page is the only caller in this tree | **Implemented** |
| `oUser.userType` | Integer on the user row. The page writes `1` on add and on update. `oUserType` exists and is not loaded by the page | **Implemented**. What `1` means is **Unknown / Requires Confirmation** |
| Support mailbox | `exception.EmailException` reads appSettings `support`, `from`, `subject`, and `website` | **Implemented**. The sample config supplies those keys. Personal mailbox values are omitted |

No role table is enforced on the website. `oUser` has `password`, `isActive`, `cookieId`, and `resetCode`. The page does not read or write them.

## Major workflows

### 1. Open the sample site and list users

Trigger: browser loads `Default.aspx` on a non-postback request.

Inputs: none from the user. Connection key `conn` from `Web.config`.

Behaviour:

- `lblMessage` is cleared.
- `xData.GetCustomTypedTable` runs `SELECT recId, name, surname, email, userType FROM evo_User;`.
- The `GridView` `gvUsers` binds that table with auto-generated columns, an edit button, and a delete button.

Output: a grid, empty name/surname/email boxes, and an Add button. The page title in `Default.aspx` is empty.

Error: exceptions from `xData` are rethrown. The page has no try/catch. What the visitor sees is **Unknown / Requires Confirmation** (the page was not executed).

Commented samples in `Page_Load` (update a collection, insert Joe Soap, contains-search) are not called. Provenance: **Implemented** as comments only.

### 2. Add a user

Trigger: Add button (`btnAdd_Click`).

Inputs: `txtName`, `txtSurname`, `txtEmail`. `userType` is set to `1` in code. Password, addresses, and flags stay at the `oUser` field defaults (empty strings, `0`, `DateTime.MinValue`, `false`).

Validation:

- If `xData.VerifyExists("recId", typeof(oUser), "email", email)` is true, the label reads `A user with the email address {email} already exists. No user added.`
- Otherwise `xData.SaveTyped("recId", typeof(oUser), usr)`.
- If the returned id is greater than 0, the label reads `New user added.` and the three text boxes are cleared.
- If the id is not greater than 0, the label stays empty. No other failure message is set.

The page does not call `utils.validateEmail`. An empty email is still sent to `VerifyExists` and, when no row matches, to `SaveTyped`.

Output: label text, and the grid reloads.

### 3. Edit a user

Trigger: the grid edit button, then update (`gvUsers_RowUpdating`).

Behaviour:

- Edit sets `EditIndex` and rebinds.
- Cancel clears `EditIndex` and rebinds.
- Update reads `recId`, `name`, `surname`, and `email` from grid cells 1 through 4, sets `userType` to `1`, and calls `xData.UpdateTyped`.
- There is no duplicate-email check on update.

The grid also auto-generates edit and delete command columns, which occupy cells before the data columns. The handler assumes cell 1 is `recId`. Whether that index matches the rendered grid was not executed. **Unknown / Requires Confirmation**.

### 4. Delete a user

Trigger: the grid delete button (`gvUsers_RowDeleting`).

Behaviour:

- `recId` is parsed from cell 1 text.
- `xData.DeleteTyped("recId", recId, typeof(oUser))`.
- Success label: `User deleted.`
- Failure label: `The user {recId} could not be found.`

Same cell-index uncertainty as edit.

### 5. Construct a C# object from a table

Trigger: constructor window load, then "create object" (`btnCreateObject_Click`) or "create custom" (`btnCreateCustom_Click`).

Behaviour:

- On load, a combo binds `Constructor.GetTables()`: `sysobjects` rows of type `U` or `V`, ordered by name.
- Standard create reads fields for the selected table from `sysColumns` / `sysObjects` / `sysTypes`, excluding type names `sysname` and `tAppName`.
- Custom create calls stored procedure `ObjectCreatorProc` with `@Query` set to the text box.
- The tool writes `{startup}\output\{txtObjectName}.cs`: a `[Serializable]` class whose properties follow the SQL types (`int`, `bit` to `bool`, `money`/`decimal`/`float`/`numeric` to `decimal`, `real` to `double`, date types to `DateTime`, `image` to `Byte[]`, `uniqueidentifier` to `Guid`, anything else to `string`).
- Success dialog: `Object Constructed Sucessfully`. Exceptions are rethrown.

The class name is whatever was typed. No check for an empty name was found.

### 6. Export a table to XML

Trigger: exporter load, then export (`btnExport_Click`).

Behaviour:

- Combo lists the same user-table and view query shape via the exporter's own `Constructor.GetTables`.
- The click runs `SELECT * FROM {combo text}` inside a SQL transaction and writes `{application path}\export\{tableName}.xml` through `utils.ExportDataSetToXML`.
- Success dialog: `Data Exported successfully.`
- On exception the transaction is rolled back and the exception is rethrown. `finally` still calls `CompleteSQLTransaction`.

## Integrations

| Integration | Purpose | Trigger | Direction | Auth | Provenance |
|---|---|---|---|---|---|
| SQL Server | Typed CRUD, custom SQL, exception log, constructor metadata, XML export | Library and tool calls | Outbound | Sample site: `conn` with empty SQL login. Tools: integrated security | **Implemented** |
| SMTP | `communication.SendAnEmail` and exception mail | Caller, or `exception.HandleException` when a debugger is not attached | Outbound | Sample `Web.config` `system.net/mailSettings`: host `smtp.wa.co.za`, port 25, default credentials | **Implemented**. Live server behaviour **Unknown** |
| SMS HTTP gateway | `communication.SendSMSMessage` posts `xmldata` | Caller, and only when appSetting `SendingActive` parses as true | Outbound POST to `GatewayAddress` | `GatewayUser`, `GatewayPassword`, and related keys | **Implemented** in the library. Those keys are absent from `SampleWebsite/Web.config`. The sample page does not call SMS |
| Google geocode (legacy URL) | `utils.AddGeoCoordinates` | Caller | GET `http://maps.google.com/maps/api/geocode/xml` | No key in the URL (`sensor=false` only) | **Implemented**. Not called by the sample page |
| OAuth 1.0 helper | `OAuth.Manager` request-token and access-token headers | Caller | Caller-supplied URIs | Consumer key and secret passed into the constructor | **Implemented** in `business/classes/oAuth.cs`. The file header attributes the snippet to Dino Chiesa (2010, last saved 2011-April-20) and names Twitter and TwitPic as the services it was tested with. Not called by the sample page |
| Microsoft Word | `utils.MergeWordDoc` | Caller | Local Word interop | None in code | **Implemented**. Word 12 interop DLL is vendored |
| PDF | HTML-to-PDF (`PdfMetamorphosis` / `ephtmltopdf`) and `utils.EncryptPDF` (`SecureBlackbox`) | Caller | Local files | Encrypt key argument | **Implemented**. Not called by the sample page |

Facebook, Instagram, and YouTube types under `BaseLibrary/business/objects/` are property bags. No call into the Facebook 6.4.2 assembly was found in the library source. The package is vendored and listed in `packages.config`, and it is not a project reference. Whether a product outside this repo fills those objects is **Unknown / Requires Confirmation**.

## Functional requirements

### FR-001 — List users

The sample home page shows `recId`, `name`, `surname`, `email`, and `userType` from `evo_User`.

Evidence: `Default.aspx.cs` `LoadGrid`. Implementation: **Implemented**. Confidence: high for the SQL text. The page was not run.

### FR-002 — Add a user when the email is new

Add persists `name`, `surname`, `email`, and `userType = 1` through `SaveTyped`, which inserts into `evo_` plus the type name minus its first character (`evo_User`) and returns `Ident_Current` for that table.

Evidence: `btnAdd_Click`, `xData.SaveTyped`, `dynamicInteraction` insert path (same table rule as `dataInteraction.buildInsertInteraction`). Implementation: **Implemented**.

### FR-003 — Refuse a duplicate email on add

Add checks `VerifyExists` on column `email` before insert. The visitor message includes the typed address.

Evidence: `btnAdd_Click`. Implementation: **Implemented**. The check is not applied on update.

### FR-004 — Update and delete from the grid

Edit, cancel, update, and delete are wired on `gvUsers`. Update writes the four edited values and forces `userType` to 1. Delete removes the row whose identity equals the parsed cell value.

Evidence: `Default.aspx`, `Default.aspx.cs`. Implementation: **Implemented**. Cell indexes require confirmation (see workflow 3).

### FR-005 — Typed data API for other objects

`xData` exposes select, insert, update, verify, and delete for any type, plus stored-procedure variants and `GetCustomData` against `sp_GetCustomData` with parameter `EntityID`. The sample page uses only `GetCustomTypedTable`, `VerifyExists`, `SaveTyped`, `UpdateTyped`, and `DeleteTyped`.

Evidence: `Sample_Business/classes/xData.cs`. Implementation: **Implemented**. Whether `sp_GetCustomData` exists in `Sample.bak` was not checked. **Unknown / Requires Confirmation**.

### FR-006 — Generate a class file

The constructor writes a serializable class under `output\` from a table, a view, or `ObjectCreatorProc`.

Evidence: `frmConstructer.cs`, `EvoSoft_Constructor/classes/Constructor.cs`. Implementation: **Implemented**.

### FR-007 — Export a table

The exporter writes `SELECT *` for the chosen table or view to an XML file under `export\`.

Evidence: `ExportData.cs`. Implementation: **Implemented**.

### FR-008 — Log a library exception to SQL and email

`exception.HandleException` inserts into `evo_Exceptions` (`ClassName`, `FunctionName`, `Exception`, `UserID`, `DateLogged`) and, when no debugger is attached, emails the support address. The subject is appSetting `subject` with `{content}` replaced by `Exception`.

Evidence: `BaseLibrary/business/classes/exception.cs`. Implementation: **Implemented**. The sample page does not call it. Many library catches do.

## Constraints

- Connection strings and mailboxes are committed in config. This PRD does not copy mailbox values.
- `Web.config` `compilation debug` is `true`. `httpRuntime maxRequestLength` is `10048`.
- Culture is `en` / `en-US`.
- The website Release configuration in the solution builds the Debug configuration (`EvolutionSoftwareLibrary.sln` project `SampleWebsite`).
- No authentication module, captcha, or authorisation attribute was found on the sample page.
- No test project was found.

## Planned behaviour

No roadmap, TODO issue list, or feature flag marks future work. Commented samples in `Page_Load` are examples, not a stated plan. **Planned: none found.**

## Unknown / requires confirmation

- The meaning of the repository name `ieb_template`.
- Whether `userType` 1 is a real type row in `evo_UserType`.
- Whether grid cell 1 is `recId` once both command buttons render.
- The restored contents of `Sample.bak`, including `evo_User`, `evo_Exceptions`, and `ObjectCreatorProc`.
- Whether SMS gateway settings are supplied by a host config outside this repo.
- Whether the Google geocode URL, Word merge, or PDF helpers are still used by any product.
- Relationship to the Evolution framework documented under `silicon_ark/SHOU-1/`.
