# Technical documentation — legitimate

Evidence date: 2026-10-10. Source: `git@bitbucket.org:overdrive/legitimate.git`, `main` at `0a9b1c8` (2026-02-11).

This describes the tree that was inspected. It does not restate every business rule. Those are in `business-rules.md`.

## Platform

| Item | Evidence |
|---|---|
| Language | C# |
| Framework | .NET Framework 4.6.2 (`Neo.Legitimate.Web.csproj` `TargetFrameworkVersion`) |
| Web | ASP.NET MVC 4.0.20710, Razor 2, WebPages 2 |
| ORM | Entity Framework 6.1.3 |
| Database | SQL Server, provider `System.Data.SqlClient` and `System.Data.EntityClient` |
| Realtime | SignalR 2.2.1 on OWIN, mapped at `/signalr` |
| JSON | Newtonsoft.Json 6.0.8 |
| Errors | Sentry 1.2.0 with `Sentry.EntityFramework` 1.0.0, started from `Global.asax.cs` when a DSN is set |
| Documents | DocX 1.1.0; a Websupergoo PDF key in `appSettings` (value omitted) |
| UI script | jQuery 1.6.4, Knockout bindings in the cshtml consoles |
| Hosting assumed | IIS. `Global.asax.cs` comments mention IIS 6 and IIS 7 classic mode. No Docker, Terraform, or pipeline file was found |
| Solution | `Neo.Legitimate.sln` plus `Neo.Legitimate.LegitimateWebService.sln` and `Neo.Legitimate.WinService.sln` |

The application framework under the web modules is Pilotfish Afx (`Pilotfish.Afx.Core`, `Pilotfish.Afx.Security`, `Pilotfish.Afx.Services.*`). Those assemblies are referenced. Their source is not in this repository. `Assemblies/` contains XML documentation and three `.reg` files (printing, fingerprint reader, document scanner). `Deploy/AfxWorkflows` contains more Afx XML and `.svc` stubs.

## Repository layout

Top-level projects and folders that checked out:

- `Neo.Legitimate.Web` — site.
- Module projects: Applications, Associations, Members, Routes, Vehicles, OperatingLicences.
- Console projects: Association, Member, Route, Vehicle, Operating licence, Gazette, Adjudication, Inspection, Verification, Bulk vehicle verification, Integration, User.
- Workflow projects: ApplicationRequest, NewRouteRequest, NewAssociationRequest, NewMemberRequest, NewVehicleRequest, LicenceIssueRequest, LicenceUpliftmentExtensionRequest.
- `Neo.Legitimate.Common`, `Neo.Legitimate.Data`, `Neo.Legitimate.Admin`.
- `Neo.Legitimate.NLTISWebService`, `LTPSWebService`, `LegitimateWebService`.
- `Neo.Legitimate.WinService`, `WinService.Extensions`, `WinService.SystemTriggers`.
- `Neo.Legitimate.Printing`, `Printing.TestApp`, `ServerReports`.
- `AffectedApplicationDocumentScanner`, `AffectedApplicationProjects`.
- `DbScripts`, `_database schema changes`.
- `Deploy`, `Assemblies`.
- `Neo.Legitimate.Setup.Client`, `Neo.Legitimate.Setup.WindowsService`.

`Neo.Legitimate.Common` holds `Enums.cs`, `SecurityHelper`, `ApplicationRequestHelper`, `WorkflowHelper`, `OlasXmlHelper`, `ChecklistHelpers`, and the MVC `ControllerBase` / `Controller<TDatabase>` types.

Controllers are partial classes split by screen (`ApplicationsController.Receipt.cs`, `ApplicationsController.Purification.cs`, and so on). JSON actions are called from Knockout through `app.dataManager.post(controller, action, data)`.

## Routing and auth

`RegisterRoutes` ignores favicon and `*.axd`, then optional paths in app setting `ExternalRouteIgnores`. The default route is `{controller}/{action}/{id}` with defaults `Applications` / `Default`.

Areas are registered. No area folder was opened; Afx may add areas from referenced assemblies.

Authentication mode is Forms. Membership, role, and profile providers are the Afx domain providers, `applicationName` "Neo Legitimate". The role cookie name is `.NeoLegitimate_ASPROLES`. Roles are cached in the cookie. `userIsOnlineTimeWindow` is 60.

`AuthController` does not inherit the Afx controller base, because that base has an `Authorize` attribute. Sign-in actions are `AllowAnonymous`. The rest of the site relies on the `authorization` deny rule.

Checked-in `BaseUrl` is `http://localhost:8100`. Production URL is **Unknown**.

## Data

Entity Framework contexts named in the web `Web.config` connectionStrings include, among others:

- `LegitimateEntities` (`Models.LegitimateDataModel`)
- `ApplicationContext`, `LicenceIssueContext`, `LicenceExtensionContext`
- `NewRouteContext`, `NewMemberContext`, `NewAssociationContext`, `NewVehicleContext`
- `LtpsEntities` (`Models.Ltps.LtpsDataModel`)
- Afx contexts: Config, Correspondence, Document, Form, Integration, Query, Workflow, Report, Comment, Audit
- Afx admin contexts: Crm, Doc, Delegation, Form, Integration, Report, Security, Svc, Workflow, Audit, Sys

Catalog names disagree across files. See the table in `project-plan.md`. Passwords and the ASMX interface key are in those config files and are **not** repeated here. They should be rotated; they are committed on `main`.

Schema changes checked in:

| Path | What it contains |
|---|---|
| `DbScripts/01`–`07` | E-hailing mode, service type, allowed-types function, licence-issue report, licence exceptions, documents and questions |
| `DbScripts/COV application fees/` | Receipt cost, receipt required, COV type, receipt procedures, request types table |
| `_database schema changes/20241112` through `20250826` | Indexes, membership report, advanced search, licence exceptions, purification insert, pre-check upsert, receipt functions |

There is no EF migration folder. Schema change is hand-written SQL. Whether every script has been applied to each catalog is **Unknown**.

Stored procedures referenced from the Legitimate ASMX service:

- `App.Pr_ApplicationPrecheckInterfaceSearch` for `GetApplications`.
- `dbo.Pr_ImportedOLASLicenceSearch` for `GetOLASApplications`, against catalog `Legitimate_OLAS`.
- `GetAssociationsMasterdataStoredProcedure` is read from config and is absent from the checked-in service `Web.config`.

## Web services and endpoints

Staff site WCF (`system.serviceModel`): `aspNetCompatibilityEnabled`, `httpGetEnabled` metadata, `includeExceptionDetailInFaults` true, very large buffer quotas, streamed transfer. Message logging is configured to log entire messages (max 3000).

ASMX projects are separate web applications with their own `Web.config`.

`AffectedApplicationProjects/AffectedApplicationWebServices` exposes `Services/AffectedApplicationService.svc`.

## Background processing

`Neo.Legitimate.WinService` is a `ServiceBase`. `OnStart` ORs `SecurityProtocol` with TLS 1.2 and starts `Pilotfish.Afx.Services.DatabaseServiceScheduler`. The comment says the Messages worker uses SMTP (example: SendGrid). That worker is not in this repository.

`SystemTriggerHandler` is an Afx `Worker`. It dequeues `SystemTrigger`, opens a SignalR client to setting `SignalRPath`, hub `MessageHub`, and invokes `AddVerificationToList`. Traces go to the Afx service-trace table. The handler comment names `[Svc].[ServiceTraces]`.

`AutoVerificationTask` is another worker under `WinService.Extensions/TaskHandlers`.

Only one system-trigger type is defined in the enum. Other scheduled work is whatever rows the Afx scheduler has in the database. Those rows were not in source.

## SignalR

`Startup.Configuration` maps SignalR at `/signalr` with detailed errors off. `ConfigureAuth` is commented out.

`MessageHub` methods: `AddVerificationToList`, `SetVerificationAsAssigned`, `RemoveVerificationFromList`. They broadcast to `Clients.All`. No group or user filter was seen. Any connected client receives every verification event. **Inferred** from the hub. Whether the pipeline or IIS restricts who can connect to `/signalr` is **Unknown**.

## Printing and reports

`Neo.Legitimate.Printing` draws receipts (`AppReceiptPrinter`) and includes registration and VIN lines, skipping the literal "Not Available".

`Neo.Legitimate.Printing.TestApp` is a manual test application, not an automated suite.

`Neo.Legitimate.ServerReports` is a SQL Server Reporting Services project (`.rptproj`). `ReportsController` is the MVC entry.

## Client installers and scanner

`Neo.Legitimate.Setup.WindowsService` is an InstallShield project (`.isproj`, `.isl`). `Neo.Legitimate.Setup.Client` is the matching client installer. Target machines and upgrade codes were not extracted.

`AffectedApplicationDocumentScanner` is WinForms (`Program` runs `LoginForm`). It includes a service reference to `AffectedApplicationService`. One generated `.datasource` file could not be checked out on this Windows machine because the path exceeded `MAX_PATH`.

## Security notes (no secret values)

These are properties of the committed config, not a penetration test.

- SQL logins and passwords are in `Web.config` files on `main`.
- The Legitimate ASMX interface key is in the service `Web.config`.
- A Sentry DSN and a PDF component key are in the web `appSettings`.
- Membership `passwordFormat` is `Clear`.
- `compilation debug` is true.
- WCF fault details and message logging are on.
- `SystemUsername` is set to a named mailbox at softedgesolutions.co.za.
- SignalR broadcasts verification tasks to all clients.
- Securable ids 1023 and 2012 are each used by two enum members, so permission checks for those ids cannot tell the two features apart.

## Testing and development

No PHPUnit, NUnit, or MSTest project was found. The only test-named project is `Neo.Legitimate.Printing.TestApp`.

`Web.config` is the developer configuration (localhost base URL, QA catalog name, debug on). A transform for Release was not confirmed. How KZN is deployed (IIS site name, installer versus xcopy) is **Unknown / Requires Confirmation**.

Git history on `main` is two import commits plus eleven follow-up commits. Authors visible on the tip commit: Renier van Rooyen. The import commits were not attributed further.

## Related repository

`legitimate_licences` (`Neo.LegitimateLicences.*`) is documented separately under `silicon_ark/legitimate_licences/`. Do not merge the two feature lists. This tree is the one whose 2025–2026 commits add KZN e-hailing, the two-person panel, and the receipt-cost scripts.
