# Technical documentation — lifechoiceMVC_net

Evidence date: 2026-10-10.

Source: `git@bitbucket.org:overdrive/lifechoicemvc_net.git`, `master` at `69783e2` (2019-12-03 10:13:40 +0200). The clone contains one commit. Earlier Visual Studio Team Services history is referenced by the solution and is not in this git repository.

Secrets are named by file. Values are not copied.

## Repository layout

```text
HealthchoiceMVC v2.0.sln
HealthchoiceMVC/          ASP.NET MVC 5 web application
HCDB/                     SQL Server Database project (in the solution)
HCUserDB/                 SQL Server Database project (in the solution)
HCLogDB/                  SQL Server Database project (not in the solution)
packages/                 committed NuGet packages
UpgradeLog.htm            Visual Studio project-type report
```

Solution configurations: Debug, Release, and Test, all Any CPU. The Test configuration builds the web project with its Release settings. SQL projects have a real Test configuration.

Source control block inside the solution:

- Provider `{4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}` (Team Foundation Version Control).
- Server `https://lifechoice.visualstudio.com/defaultcollection`.
- Projects bound: `HCDB`, `HCUserDB`, `HealthchoiceMVC`. `HCLogDB` is not in that binding list.

## Application structure

`HealthchoiceMVC.csproj`, target `v4.5`, output type library (web application), assembly `HealthchoiceMVC` version `1.0.0.0`, copyright 2016, root namespace `HealthchoiceMVC`.

| Folder | Contents |
|---|---|
| `App_Start` | `RouteConfig`, `FilterConfig`, `BundleConfig`, `IdentityConfig`, `Startup.Auth` |
| `Controllers` | Account, Common, Home, Manage, NetworkAffiliations, People, Provider, ProviderRegistration, SiteAdmin, UserRole, UserType |
| `Models` | EF entities for the 2019 practice/person model, plus `provider`, lookups, and user type/role tables |
| `NonDbModels` | `ApplicationUser`, `ApplicationDbContext`, account view models, short provider and discipline DTOs |
| `ViewModels` | Practitioner and provider view models |
| `DBContext` | `HCDBEntities` (also under namespace `HealthchoiceMVC.Models`) |
| `Services` | `HCLocalService`, `HCWebService` |
| `Migrations` | EF6 migrations from 2019-09-01 through 2019-10-30, plus `Configuration` |
| `Views` | Razor views per controller, `Shared/_Layout.cshtml`, `_LoginPartial.cshtml` |
| `Enums` | `ServiceMode` `LOCAL` or `WEB` |

Startup: `Startup.Configuration` calls `ConfigureAuth`. `Global.asax` `Application_Start` sets JSON to ISO dates and `en-ZA`, registers areas, filters, routes, and bundles. It does not call `Database.SetInitializer`. EF migrations run when the tooling or an initializer is invoked. No initializer was found in `Global.asax.cs`. Whether the site migrates on startup is **Unknown**.

`Migrations/Configuration.cs` sets `AutomaticMigrationsEnabled = true` and seeds contact types, contact classes, and person types.

## Frameworks and libraries

From `HealthchoiceMVC/packages.config`:

| Package | Version |
|---|---|
| Microsoft.AspNet.Mvc | 5.2.3 |
| Microsoft.AspNet.WebApi | 5.2.7 |
| Microsoft.AspNet.Identity.Core / EntityFramework / Owin | 2.2.1 |
| Microsoft.Owin | 4.0.1 |
| Microsoft.Owin.Security.Facebook | 4.0.1 |
| Microsoft.Owin.Host.SystemWeb | 3.0.1 |
| EntityFramework | 6.1.3 |
| Newtonsoft.Json | 12.0.2 |
| bootstrap | 3.3.6 |
| jQuery | 2.2.1 |
| jQuery.UI.Combined | 1.12.1 |
| jQuery.Validation | 1.14.0 |
| jQuery.InputMask | 4.0.9 |
| Microsoft.jQuery.Unobtrusive.Validation | 3.2.3 |
| Modernizr | 2.8.3 |
| Respond | 1.4.2 |
| Sendgrid | 6.3.4 |
| SendGrid.SmtpApi | 1.3.1 |
| Antlr | 3.5.0.2 |
| WebGrease | 1.6.0 |
| Microsoft.AspNet.Providers | 2.0.0 |

OWIN binding redirects in `Web.config` send `Microsoft.Owin` and `Microsoft.Owin.Security` to 4.0.1, while several other OWIN security assemblies stay on 3.0.1. That mix is what the config file says. Whether it loads cleanly was not executed.

`Sendgrid` is referenced. The mail path that runs uses `System.Net.Mail.SmtpClient`, not the SendGrid SDK.

## Databases

### Connection strings

`Web.config` active names:

| Name | Catalog | Server in the active string |
|---|---|---|
| `HCDBConnectionString` | `HCDB` | `tcp:hcdev1.database.windows.net,1433` |
| `HCUserDBConnectionString` | `HCUserDB` | same host |

Both use SQL authentication. User name and password are in the file and are not repeated here. A comment says "NEW - ADDED BY AG".

Commented alternatives: LocalDB attach of `aspnet-HealthchoiceMVC-20160219124408`, LocalDB `(localdb)\Projects` for both catalogs, and `.\SQLEXPRESS`.

`ApplicationDbContext` uses `HCUserDBConnectionString` with `throwIfV1Schema: false`.

`HCDBEntities` uses `HCDBConnectionString` and removes the pluralizing table-name convention, so entity class names are table names (`Practice`, `Person`, `provider`, `lookup_table`).

There is no `HCLogDB` connection string in `Web.config`.

### Two shapes of HCDB

**SSDT project** (`HCDB/HCDB.sqlproj`) defines the provider, patient, authorisation, treatment, process, lookup, geo, and bank tables listed in `features.md`. `Script.PostDeployment.sql` includes, in order: lookup data, `Script.ClearProviderData.sql`, process types, and process steps. Every `DELETE` in `Script.ClearProviderData.sql` is commented out, so a post-deploy does not clear provider rows.

**EF model** used by the website adds `Practice`, `PracticeInvite`, `PracticeLocation`, `PracticePerson`, `Person`, `PersonAddress`, `PersonAddressType`, `PersonContact`, `PersonRelationship`, `PersonType`, `PersonField`, `ContactClass`, `ContactType`, `NetworkAffiliation`. Migrations from September and October 2019 create and alter those tables inside the same `HCDB` catalog name.

The SSDT project does not contain those EF tables. Deploying only the SSDT project would not create the tables the 2019 screens use. Deploying EF migrations would not, by itself, create the clinical tables. **Unknown / Requires Confirmation** which one was applied to `hcdev1`.

`HCDB/Security/Healthchoice_Website.sql` and the same role in the other SQL projects create a database role with no `GRANT` statements in the files that were read.

### HCUserDB

Tables: `AspNetUsers`, `AspNetRoles`, `AspNetUserRoles`, `AspNetUserClaims`, `AspNetUserLogins`.

`HCUserDB/dbo/Tables/AspNetUsers.sql` includes the Identity columns plus `FirstName`, `LastName`, `ContactNumber`, and `AccountType`, all `NOT NULL`. That matches `ApplicationUser`. A unique index `UserNameIndex` is on `UserName`. There is no unique index on `Email` in that script. Email uniqueness is enforced by ASP.NET Identity in the application (`RequireUniqueEmail`).

### HCLogDB

Enterprise Library style `Log`, `Category`, `CategoryLog`, and ELMAH `ELMAH_Error`, plus procedures `WriteLog`, `AddCategory`, `InsertCategoryLog`, `ClearLogs`, `usp_log_get`, `usp_log_get_details_by_id`, `usp_log_list_by_id`, `ELMAH_LogError`, `ELMAH_GetErrorsXml`, `ELMAH_GetErrorXml`. Not a solution member. No C# caller was found.

## Authentication

OWIN cookie authentication.

| Setting | Value |
|---|---|
| Login path | `/Account/Login` |
| Security stamp validation | every 30 minutes |
| Two-factor sign-in cookie | 5 minutes |
| ASP.NET `authentication mode` | `None` (forms module removed) so OWIN owns the cookie |
| Role manager | enabled, `DefaultRoleProvider`, connection `HCUserDBConnectionString` |
| Membership provider | `DefaultMembershipProvider` with `connectionStringName="hidden"` |

`ApplicationUser.GenerateUserIdentityAsync` adds claims `FirstName` and `LastName`. The layout reads those claims for the welcome text.

Facebook is registered in `Startup.Auth.cs` (`AppId`, `AppSecret`, scope `email`, claim `FacebookAccessToken`). Microsoft, Twitter, and Google blocks are commented and have empty client fields.

External API calls use HTTP Basic. The user and password are literals in `HCWebService.SetServiceParameters`. TLS is set to TLS 1.2, 1.1, TLS, and SSL 3 before the call.

## Email

`EmailService.SendAsync` builds a `MailMessage` from `appSettings` `EmailFromAddress` (`info@healthchoice.co.za`) and sends it with the default `SmtpClient`, which reads `system.net/mailSettings`.

That SMTP block points at `smtp.sendgrid.net` port 587. User name and password are in `Web.config`. `appSettings` also has `mailAccount` and `mailPassword`. The `EmailService` that was read does not pass those appSettings into `SmtpClient.Credentials`; it relies on the mailSettings network element. `EnableSsl` is set true in code.

`SmsService.SendAsync` returns a completed task and does not call a provider.

## External HTTP API

`HCWebService.serviceMode` is the string `WEB`.

| Mode | Base address |
|---|---|
| `LOCAL` | `https://localhost:44300/api/` |
| `WEB` | `https://lcservices20190802115129.azurewebsites.net/api/` |

Live methods: `GetDisciplines`, `GetDisciplineByCode`, `GetSubDisciplinesByDisciplineCode`, `GetSubDisciplineByKey`. They accept JSON. The rest of the class (geo, banks, diagnosis, ICD, NAPPI) is commented out.

`HCLocalService.GetDisciplines` keeps codes that appear in lookup type `alloweddisciplines`.

The API implementation is not in this repository.

## Request pipeline

- Route: `{controller}/{action}/{id}`, default Home/Index. `*.axd` ignored.
- Global filter: `HandleErrorAttribute` only.
- Anti-forgery: present on the login, register, register-practice, and site-admin register posts that were read. `RegisterPractitioner` POST takes `FormCollection` and the attribute was not on that action.
- Session: `mode="InProc"`. The custom provider is configured with connection string `DefaultConnection`, which is commented out. InProc does not use that provider until the mode changes.
- Globalization in `Web.config`: `uiCulture="en"` `culture="en-GB"`. `Application_Start` also assigns `en-ZA` to the current thread. These disagree.
- `compilation debug="true"`. `Web.Release.config` removes the `debug` attribute and does not transform connection strings or the environment name.
- `appSettings` `EnvironmentSetting` = `TEST`.
- `ClientValidationEnabled` and `UnobtrusiveJavaScriptEnabled` are true.

## Environment and deployment

No publish profile, Dockerfile, Azure Resource Manager template, Web Deploy script, or pipeline file was found.

`UpgradeLog.htm` records that opening the solution failed to find the web application project type and the SSDT project type (`00D1A9C2-B5F0-4AF3-8072-F6C62B433612`). The solution file itself was reported as not needing migration. That report is an environment note, not a product feature.

Hosting of the MVC site (IIS, Azure App Service, or otherwise) is **Unknown / Requires Confirmation**. The only Azure names in source are the SQL server `hcdev1` and the API site `lcservices20190802115129`.

## Background work

No `Hangfire`, Windows service, queue, or scheduled job project is in the solution. Process steps in SQL describe "send registration" and "send auth request" as data, not as workers.

## Storage

Uploaded diagnosis documents are a column concern of `patient_diagnosis_attribute_docs` in the SSDT schema. No blob client, file upload action, or storage connection string was found in the MVC project.

## Monitoring

`HCLogDB` is an unused logging schema (Enterprise Library plus ELMAH). The web application does not reference it. `FilterConfig` does not register ELMAH. No Application Insights package is in `packages.config`.

## Security notes for reviewers

These are facts about the tree. Credentials are not reproduced.

| Item | Where |
|---|---|
| Azure SQL user and password | `HealthchoiceMVC/Web.config` connection strings |
| SendGrid SMTP user and password, and `mailAccount` / `mailPassword` | `Web.config` |
| Facebook application id and secret | `App_Start/Startup.Auth.cs` |
| API basic-auth user and password | `Services/HCWebService.cs` |
| `debug="true"` on the config that is checked in | `Web.config` |
| Anonymous POST that creates a support user and assigns a role | `SiteAdminController.Register` |
| Activate and decline practice links with no extra token | `AccountController.ConfirmAccount` |
| People, provider, and network controllers without `[Authorize]` | controller class declarations |
| Login issues the auth cookie before the practice-activation check | `AccountController.Login` |
| SSL 3 is enabled on the outbound API `ServicePointManager` setting | `HCWebService.SetServiceParameters` |

Rotation and removal from history need a human decision. This documentation pass does not change the source repository.

## Development and testing

- IDE implied by the solution header: Visual Studio 2013 (`VisualStudioVersion = 12.0.31101.0`), with later edits (EF migrations and OWIN 4 in 2019).
- No `README` that describes how to build.
- No unit or UI test project.
- No continuous integration definition in the commit.
- `packages` is committed, so a restore from the web is not required to compile if those folders are intact. That was not verified by building.

## Configuration keys

| Key | Value in source | Used by |
|---|---|---|
| `EnvironmentSetting` | `TEST` | Only a commented email banner checks it |
| `EmailFromAddress` | `info@healthchoice.co.za` | `EmailService` |
| `mailAccount`, `mailPassword` | present | No reader found in the C# that was searched, beyond being in config |
| `webpages:Version` | `3.0.0.0` | ASP.NET |
| `ClientValidationEnabled` | `true` | MVC validation |
| `UnobtrusiveJavaScriptEnabled` | `true` | jQuery unobtrusive validation |

`ConfigurationManager.AppSettings.Get("EmailSubject")` is called and then overwritten with a fixed subject in each send method. No `EmailSubject` key exists in `Web.config`. The lookup result is discarded.

## Discrepancy list

| Topic | SSDT or comment | MVC behaviour |
|---|---|---|
| Domain model | Provider, patient, auth, process | Practice, person, invite |
| `HCLogDB` | Full logging database | Not in the solution, no caller |
| Account type 4 | Home page treats it as provider | Login treats 7 as practice admin and 1 as practitioner |
| Lookup `title` vs `titleid` | `title` is seeded | People and practice registration request `titleid` |
| Contact type text | Seed `Email`, `CellPhone`, `Work` | Several queries use `email`, `cellphone`, `work` |
| Culture | `Web.config` `en-GB` | `Application_Start` `en-ZA` |
| Sonar files | Listed on OVER-186 at discovery | Not in git |
