# PRD — SHOU-1 (The Shoulder Practice)

Evidence date: 2026-10-04.

Source: `git@bitbucket.org:overdrive/shou-1.git`, `main` at `30a710c` (2026-09-22).

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

No formal PRD existed in the repository or in `silicon_ark/SHOU-1/` before this file. Requirements below are recovered from the tenant web fork, the business layer, configuration, and SQL scripts. They are not a new product decision.

The platform calls itself Palette in the admin shell (`core_custom/SHOU-1/Admin.aspx` includes the text "Welcome to palette"; `Administration.master` title "Palette Framework") and Evolution Software Framework in assembly metadata. The practice-facing brand is The Shoulder Practice. See `project-plan.md` for repository scope.

## Product purpose

SHOU-1 is the Palette tenant used by The Shoulder Practice to:

- publish a public website (canvas pages, content, galleries, enquiries);
- register and sign in website users and send SHOU-1 website users to a patient information page;
- capture clinical records on configurable surface applications, including surgical notes that exist only on this tenant fork;
- book procedures, run a calendar, and verify medical-aid membership through MediSwitch;
- post billing lines, produce debtor statements, and work unprocessed remittance advices;
- administer users, modules, banners, campaigns, and medical reference data (practices, doctors, schemes, tariffs, ICD-10, procedures).

**Implemented** across `core_custom/SHOU-1`, `business/`, and `tools/scheduler`. Which of the framework modules are turned on in the live database is **Unknown / Requires Confirmation**. The admin menu is built from `oModule` rows and the signed-in user's module list (`controls/admin/menu.ascx.cs`).

## Users and roles

Roles are the enum `pNums.UserType` in `business/enums/pNums.cs`.

| Actor | Enum | What the code does | Provenance |
|---|---|---|---|
| Public visitor | none until a session user exists | Can open the public site (`Default.aspx`, canvas routing). | **Implemented** |
| Website user | `WebsiteUser = 1` | Registration creates this type (`Register.aspx.cs`). On SHOU-1, a successful login redirects to `{securePath}/pages/patient~info`. | **Implemented** |
| Power user | `PowerUser = 2` | Surface access thresholds. On SHOU-1, users below Power User get a wizard-only surface form. | **Implemented** in `controls/surface/surface_form.ascx.cs` (path under the tenant site) |
| Super user | `SuperUser = 3` | Named in the enum. A separate bypass exists when `oUser.recId == -1` inside `handler.ValidatePermission`. Whether Super User is assigned in this tenant's data is **Unknown** | **Implemented** as an enum value |
| Admin user | `AdminUser = 4` | Required by `handler.ValidatePermission` for admin module pages, together with the page's module id in `oUser.modules` | **Implemented** |
| Custom user | `CustomUser = 5` | Canvas access can list specific custom users. Surface checks use `mimicUserType` instead of `userType` | **Implemented** |
| Evolution operator | `customerCode` `EVOL-1`, user type above Power User, and not Custom User | `MatchesLoginTenant` allows these users to sign in on a tenant other than their own | **Implemented** in login code |
| Month-end user | email equal to appSetting `MonthEndUser` when `setup.code` is `SHOU-1` | After login, shows a checklist modal if the checklist binds | **Implemented** in `Login.aspx.cs`. The key is not in the committed `Web.config`. The email value is **Unknown** |
| Patient at reception | not a separate enum | `controls/module/medicalPatientSignin.ascx.cs` looks up a surface named `PatientProfile` by mobile number and date of birth | **Implemented** |
| Batch scheduler | process identity of `tools/scheduler` | Runs campaigns, MediSwitch handling, and imports without an interactive user | **Implemented** |

`oUser.modules` is a comma-separated list of module record ids. `oUser.customerCode` scopes the user to a tenant such as `SHOU-1`.

Objects under `business/objects/alt/pms/` (`oRoleSuperUser`, `oAccessPermissionGroups`, `oAccessUsers`) exist as generated types. No call site in the SHOU-1 web or handler code was found. Treat them as unused by this tenant unless a database job says otherwise. **Unknown / Requires Confirmation**.

## Environments and configuration that change behaviour

| Input | Effect | Provenance |
|---|---|---|
| `.env` `DB_CONNECTION_STRING` | Tenant catalog. Example in `.env.example`: `Framework_SHOU-1` | **Documented** and **Implemented** via `library/classes/ConfigResolver.cs` |
| `.env` `DB_LIVE_CONNECTION_STRING` | Central auth catalog. Example: `Framework_EVOL-1`. Password writes go here | **Documented** and **Implemented** |
| `PASSWORD_MIN_LENGTH` | Minimum password length. Default 12. Clamped to 8–128 | **Implemented** in `PasswordPolicy` |
| `BCRYPT_WORK_FACTOR` | BCrypt cost. Default 12. Accepted range 4–31 | **Implemented** in `PasswordService` |
| `LOGIN_MAX_ATTEMPTS` | Lock after this many failed attempts. Default 5. `0` disables lockout | **Implemented** |
| `setup.securePath` | When non-empty, new website users are saved inactive until the registration link is opened | **Implemented** in `Register.aspx.cs` |
| `MonthEndUser` | SHOU-1 checklist modal | **Implemented**. Value **Unknown** |
| MediSwitch gateway appSettings | Committed file uses QA hosts. Live hosts are commented | **Implemented** as the committed DEV file |

## Major workflows

### WF-01 — Open the public site

Trigger: HTTP request to the site root or a canvas route.

Actor: anonymous visitor, or a signed-in user.

Behaviour:

- `Global.asax` loads `.env` through `EnvBootstrap` and registers friendly routes to `.aspx` pages.
- `Default.aspx` renders home content. `Default.aspx.cs` replaces a token `{Image Ask Dr Christelle}` when a gallery title is `Home Ask Dr Christelle`.
- `Core.master` supplies the practice title and meta description.
- Navigation markup in `controls/structure/navigation.ascx` includes Log in, Register, profile, and cart. Palette nav labels are data-driven.

Output: HTML. Exact page copy is stored in the canvas/content tables, not in git.

Error: `Error.aspx` exists. The framework exception path in `library/classes/exception.cs` writes `pal_Exceptions` and can email the `support` appSetting.

Provenance: **Implemented**.

### WF-02 — Register a website user

Trigger: submit `Register.aspx`.

Actor: anonymous visitor.

Inputs: registration fields on the page, including password and a terms checkbox.

Behaviour:

- User type is `WebsiteUser`.
- Duplicate email for the tenant is rejected (`CentralUserExists`). Message includes "A user already exists with this email address".
- Password must pass `PasswordPolicy` (see business rules).
- Terms must be checked before the Register button is enabled.
- If `securePath` is set, the user is stored with `isActive = false` and a confirmation mail is sent. Opening the link with an auth value ending in `reg` calls `PasswordService.ConfirmRegistrationUser`, which sets `isActive = 1` when the user is not deactivated.
- If secure registration fails after the central user was inserted, `handler.RollbackCentralUser` runs.
- SHOU-1 registration success redirects to `/pages/patient~info` (`Register.aspx.cs`).

Provenance: **Implemented**.

### WF-03 — Sign in

Trigger: email and password on `Login.aspx`, or the admin sign-in page `Admin_SignIn.aspx`.

Actor: any person with a user row.

Behaviour:

- Candidates are active, not deactivated, and match the email (`PasswordService.LoadActiveUsersByEmail`).
- Password check uses the BCrypt hash first, then the legacy cipher (`encryption("p@l3tt3")` key material in `VerifyUserPassword`).
- A user whose failed-attempt count is at or above `LOGIN_MAX_ATTEMPTS` is skipped. The login panel text is "Your email or password is incorrect." There is no separate lockout sentence. **Implemented** behaviour; whether a distinct message is desired is **Unknown / Requires Confirmation**.
- Deactivated and inactive users are not candidates, and they see the same incorrect-credentials text.
- On success, failed attempts reset to 0 and `handler.UpdateCentralUser` persists the user on the central catalog.
- Tenant match: the user's `customerCode` must match the current setup, unless the user is an `EVOL-1` operator above Power User and not a Custom User.
- SHOU-1 website users redirect to `{securePath}/pages/patient~info?auth=...`.
- SHOU-1 user whose email matches `MonthEndUser` gets the checklist modal instead of that redirect.
- Other website users look for a canvas flagged `isSecureLandingPage`.
- Admin sign-in sends an already signed-in admin for this tenant, or an `EVOL-1` admin, to `Admin.aspx`. Others go to `/home`.

Google sign-in on the admin page (`Admin_SignIn.aspx.cs` `GoogleLogin`) does not create a user. An unknown email does not sign in. An existing user must pass `IsLoginAllowed`.

Provenance: **Implemented**.

### WF-04 — Reset a password

Trigger: forgot-password on the login page, then `Reset.aspx` with the code.

Behaviour:

- Reset is offered only for an active, non-deactivated user on the tenant. Unknown email shows "Email address not found." Success shows "Success: We have sent you further instructions."
- Reset code is 6 characters. `isReset` is set. `Reset.aspx.cs` treats the code as expired 12 hours after `dateUpdated`.
- The new password must pass `PasswordPolicy`.
- Success clears reset flags and login attempts.

Provenance: **Implemented**.

### WF-05 — Administer users

Trigger: admin opens `Admin_Users.aspx` (`controls/admin/users.ascx`).

Actor: admin user with the Users module.

Behaviour:

- List can filter active versus deactivated users.
- Create and change password go through the password policy. A new user requires a password.
- Duplicate email message: "An user with this email already exists on the system".
- Deactivate sets `isDeactivated = 1` and `dateDeactivated` on central `pal_User`. The confirm text says they will not be able to sign in.
- The signed-in admin cannot deactivate their own account. Message: "You cannot deactivate your own account."
- Reactivate clears deactivation, failed attempts, and reset flags.

Provenance: **Implemented**.

### WF-06 — Patient profile sign-in at the practice

Trigger: mobile number and date of birth on `controls/module/medicalPatientSignin.ascx`.

Actor: staff using the module, or the patient at that screen. Who is intended to operate it is **Inferred** from the control living in the module library. The page copy is in the database.

Behaviour: queries the surface named `PatientProfile` using fields `PatientInformation_PatientDetails_MobileNumber` and date of birth.

Provenance: **Implemented**.

### WF-07 — Clinical surfaces, including surgical notes

Trigger: user opens a canvas whose surface is published under `controls/surface/` or `controls/surface_custom/`.

Actor: staff. Access level is compared with `userType` (or `mimicUserType` for custom users).

Behaviour:

- `Canvas.aspx.cs` loads custom surface controls from `~/controls/surface_custom/`.
- SHOU-1 ships `SurgicalNotes_form.ascx`, `SurgicalNotes_grid.ascx`, and `SurgicalNotes_view.ascx`. Field names in the form include shoulder arthroscopy drawing notes and an Examinations surface.
- `surfaceHandler` generates grid, form, and view markup, including MediSwitch and attachment placeholders.
- On SHOU-1, users below Power User are limited to the wizard UI.
- `MedicalSchemeDisplay` (`App_Code/MedicalSchemeDisplay.cs`) shows a medical scheme name for a BHF code on grids and views. It does not change the stored code. Values `0`, `-1`, `Select`, and `select..` display as empty. An unknown code displays as entered.

Provenance: **Implemented**. The list of surface applications configured for the practice (PatientProfile, Examinations, and others) is **partially evidenced** by field names in code. The full configured set is in the database. **Unknown** beyond those names.

### WF-08 — Letters and referrals

Trigger: a surface save or a document action that runs `xSurfaceCustomAction`.

Actor: staff.

Behaviour when `setup.code` is `SHOU-1`:

- Letter fields prefixed `Letters_PhysiotherapistLetter_` are filled from the surface.
- Templates named in code include "Physio Referral Letter" and "Surgical Physio Referral".
- Post-consultation and post-operation letter file names are special-cased (`PostConsultationLetter`, `PostOperationletter`).
- When a physiotherapist letter is attached and the file `upload/documents/Physio Referral - Shoulder Rehabilitation Protocols.pdf` exists on the server, that PDF is added to the mail.

Provenance: **Implemented**. Whether that PDF is deployed is **Unknown** (the file is looked up on disk; it was not treated as source).

### WF-09 — Calendar

Trigger: `Admin_Calendar.aspx` loads `controls/module/calendar.ascx`.

Actor: staff. The list of calendars the user may see comes from stored procedure `sp_CalendarAccess` with the current user id. The procedure body is not in this repository. **Unknown** beyond the call.

Behaviour of the event query in `BindCalendar`:

- The visible range is expanded to whole weeks using `StartOfWeek` and the scheduler's `FirstDayOfWeek`.
- Events that overlap the range are included (`start < rangeEnd AND end > rangeStart`), not only events fully inside it.
- Recurring masters whose series is still active are included.
- Patient search mode does not apply the date-range filter.

Provenance: **Implemented** in `calendar.ascx.cs` (commits `e212c77`, `ef88b7a`).

### WF-10 — Procedure booking

Trigger: surface field reload on `controls/module/procedureBooking.ascx`.

Actor: staff.

Behaviour: reads and writes `oMedicalPatientProcedureBooking`.

Provenance: **Implemented**.

### WF-11 — Medical-aid verification and claims (MediSwitch)

Trigger: staff search on `controls/module/mediswitchMSV.ascx`, or the scheduler's MediSwitch handler.

Actor: staff, and the scheduler process.

Behaviour:

- `pNums.MediswitchOperationType` names MSV, Claim, and Reversal.
- Gateway URLs are appSettings `Mediswitch.Gateway`, `Mediswitch.Gateway1`, and `Mediswitch.Gateway2`.
- The committed site config uses the QA gateway host (`https://wsgateway.mediswitch.co.za/qa/...`). Live URLs are commented out.
- `MediSwitchResponses` is `0` in the committed `Web.config`.
- Web `Global.asax` leaves delayed MediSwitch processing commented and relies on `tools/scheduler`.

Provenance: **Implemented**. Production gateway choice is **Unknown / Requires Confirmation** because the committed file is the QA set.

### WF-12 — Billing and debtors

Trigger: enquiry module (`controls/module/enquiry.ascx`) and debtor reports (`controls/module/debtorsReports.ascx`), plus SHOU-1 branches in `business/classes/xDebtors.cs`.

Actor: staff with the Enquiry or Debtors Reports module. Credit notes also require `oUserAccess.allowCredit` for the current user (`enquiry.ascx.cs` `AllowCreditNotes`).

Behaviour (details in `business-rules.md`):

- Posting a billing line can expand a macro procedure (`codeType` 3) into several lines.
- Finalise assigns a shared invoice number and sequence, saves lines, and can mark matching calendar events billed.
- SHOU-1 account lines are built from examination booking procedures. Default tariff `DISC B` is selected when the plan is empty or the scheme is not WCA and the scheme name does not contain `FEDHEALTH`.
- Tariff `0083` does not add modifier lines (commit `1318028`).
- Statements are PDF templates of type Debtors. Email of a statement changes subject and body when the balance is zero.
- Deleted-history and unprocessed remittance advice (ERA) panels are opened from link buttons on the enquiry control.

Provenance: **Implemented**.

### WF-13 — Medical reference data

Trigger: admin opens a `Medical_*.aspx` page.

Actor: admin with the matching module.

Pages: Conditions, Diagnosis, Doctors, ICD-10, Medical administrators, Practice extras, Practices, Procedures, Schemes, Symptoms, Tariffs, Trauma. Each page hosts a control under `controls/medical/`.

Provenance: **Implemented** as pages. Record contents are in the database.

### WF-14 — Campaigns, banners, and SMS credit

Trigger: admin screens `Admin_Campaigns.aspx`, `Admin_Banners.aspx`, `Admin_SMSCredit.aspx`, and the scheduler.

Behaviour:

- Banners shown on the site are active and inside `startDate`..`endDate`, ordered by `sequence` (`handler.ReturnBannerCarousel`).
- Campaign templates use template type Campaign (`3`).
- If available SMS balance is below the campaign threshold, an alert email is sent (`campaigns.ascx.cs` `CheckThreshold`).
- SMS can go out through `library` communication settings or through the SendEasy SOAP client (`business/classes/xSendEasy.cs`).

Provenance: **Implemented**. Whether The Shoulder Practice sends campaigns is **Unknown** (module may be unused).

### WF-15 — Public commerce pages

Trigger: `Products.aspx`, `Cart.aspx`, product admin pages.

The Palette product, category, brand, promotion, and cart modules are in the tenant site. No SHOU-1-specific branch was found that proves the practice sells products online. Status: **Implemented** as framework pages. Use by this practice is **Unknown / Requires Confirmation**.

### WF-16 — Password migration (operator)

Trigger: an operator runs `tools/password-migrate` after the Phase 3 SQL scripts.

Actor: operator with database access. Not an end-user workflow.

Behaviour: copies legacy TripleDES `pal_User.password` values into BCrypt rows in central `pal_UserPassword` for `customerCode = 'SHOU-1'`. Supports `--dry-run`. Can set passwords without the policy (`enforcePolicy: false` on the migration path).

Provenance: **Documented** in `tools/password-migrate/README.md` and **Implemented** in `PasswordService.MigrateShou1LegacyPasswords`.

## Functional requirements

### FR-001 — Practice public identity

The public master page identifies the site as The Shoulder Practice, Cape Town, orthopaedic surgeon, and describes Dr Christelle van der Watt.

Evidence: `core_custom/SHOU-1/Core.master`.

Implementation: **Implemented**. Confidence: High.

### FR-002 — Tenant code SHOU-1

Practice-specific branches run only when setup code is `SHOU-1` (patient redirect, month-end checklist, tariff default, letter fill, account mapping).

Evidence: `Login.aspx.cs`, `xDebtors.cs`, `xSurfaceCustomAction.cs`.

Implementation: **Implemented**. Confidence: High.

### FR-003 — Central authentication store

User rows and password hashes that the site writes are stored on the central catalog (`Framework_EVOL-1` in `.env.example`). The tenant catalog reads them through shared views (`pal_vUserShared`, `pal_vUserPasswordShared`).

Evidence: `PasswordService.cs`, `ConfigResolver.cs`, `data/Scripts/SHOU-1/SHOU-1_3.0.01_create_pal_UserPassword_EVOL-1.sql`, `SHOU-1_3.0.02_create_pal_vUserPasswordShared.sql`.

Implementation: **Implemented**. Confidence: High.

### FR-004 — Password policy on set

Registration, reset, and admin user create/change reject passwords that fail `PasswordPolicy.Enforce`. The migration tool can bypass the policy.

Evidence: `PasswordPolicy.cs`, `Register.aspx.cs`, `Reset.aspx.cs`, `controls/admin/users.ascx.cs`, `PasswordService.SetPassword`.

Implementation: **Implemented**. Confidence: High.

### FR-005 — Login lockout

After `LOGIN_MAX_ATTEMPTS` failed attempts (default 5), the user is no longer offered for password match. `0` turns the rule off. The person sees the same failure text as a wrong password.

Evidence: `PasswordService.cs`, `.env.example`, `Login.aspx`.

Implementation: **Implemented**. Confidence: High.

### FR-006 — Deactivation

A deactivated user cannot sign in or complete a reset. An admin cannot deactivate themselves.

Evidence: `PasswordService.SetUserDeactivated`, `LoadActiveUsersByEmail`, `controls/admin/users.ascx.cs`.

Implementation: **Implemented**. Confidence: High.

### FR-007 — Website user lands on patient info

A SHOU-1 website user, after a successful login that is not the month-end checklist case, is sent to the patient info canvas with an auth query string.

Evidence: `Login.aspx.cs` lines that redirect to `/pages/patient~info`.

Implementation: **Implemented**. Confidence: High.

### FR-008 — Module permission for admin pages

An admin page is allowed when the user is an admin and the module id for that path is in `oUser.modules`, or when `recId` is `-1`.

Evidence: `business/handlers/handler.cs` `ValidatePermission`.

Implementation: **Implemented**. Confidence: High.

### FR-009 — Canvas restriction

A canvas that is not restricted is available. A restricted canvas requires the user type to be listed, or a custom user to be listed in `customUsers`.

Evidence: `handler.validateCanvas`.

Implementation: **Implemented**. Confidence: High.

### FR-010 — Surgical notes UI exists only on the SHOU-1 fork

`controls/surface_custom/SurgicalNotes_form.ascx`, `_grid.ascx`, and `_view.ascx` are part of `core_custom/SHOU-1`. `sonar-project.properties` states that `core-dev` does not auto-sync into this fork.

Evidence: those files; `sonar-project.properties`.

Implementation: **Implemented**. Confidence: High.

### FR-011 — Calendar shows overlapping and recurring events

The calendar query includes events that overlap the visible week and recurring series that are still active.

Evidence: `core_custom/SHOU-1/controls/module/calendar.ascx.cs` `StartOfWeek` and `BindCalendar`.

Implementation: **Implemented**. Confidence: High.

### FR-012 — SHOU-1 tariff default

When billing lines are built for SHOU-1 and the medical plan is empty, or the plan is not `WCA` and the scheme name does not contain `FEDHEALTH`, the tariff code defaults to `DISC B`.

Evidence: `xDebtors.cs` comment dated 2018-04-13 and the assignment `code = "DISC B"`. The enquiry screen also selects `DISC B` when that list item exists (`enquiry.ascx.cs`).

Implementation: **Implemented**. Confidence: High.

### FR-013 — MediSwitch from the scheduler

Claim and remittance follow-up that used to be considered on a web cache callback is left commented in `Global.asax`. `tools/scheduler` contains the MediSwitch handler.

Evidence: `tools/scheduler/Program.cs`, `tools/scheduler/MediSwitch.cs`, tenant `Web.config` gateway keys.

Implementation: **Implemented**. Confidence: High. The schedule (Windows task, time of day) is **Unknown**.

### FR-014 — Scheme code displays as a name

Grids and views that call `MedicalSchemeDisplay` show the scheme name for a known code and leave unknown codes unchanged.

Evidence: `core_custom/SHOU-1/App_Code/MedicalSchemeDisplay.cs`.

Implementation: **Implemented**. Confidence: High.

### FR-015 — Secrets stay out of git

`.env`, `GoogleSheetAPISecretes.json`, and `business/client_secrets.json` are gitignored. `.env.example` and `GoogleSheetAPISecretes.json.example` document the shape without live secrets.

Evidence: `.gitignore`, `.env.example`.

Implementation: **Implemented** as repository policy. Confidence: High. Whether every server follows it is **Unknown**.

### FR-016 — Session length

The tenant `Web.config` sets `sessionState timeout="60"`. `SessionHeartbeat.ashx` writes `Session["Heartbeat"]`.

Evidence: `core_custom/SHOU-1/Web.config`, `SessionHeartbeat.ashx`.

Implementation: **Implemented**. Confidence: High.

## Integrations

| System | Purpose | Direction | Auth as shown | Provenance |
|---|---|---|---|---|
| SQL Server `Framework_SHOU-1` | Tenant clinical, billing, canvas, and module data | App reads and writes | Connection string from `.env`, example uses integrated security | **Documented** and **Implemented** |
| SQL Server `Framework_EVOL-1` | Central users and BCrypt hashes | App writes users and passwords; tenant reads via views | `DB_LIVE_CONNECTION_STRING` | **Documented** and **Implemented** |
| MediSwitch | MSV, claims, reversals, remittance responses | Outbound SOAP; responses processed by the scheduler | Gateway URL in appSettings. Credential fields were not copied into this PRD | **Implemented** |
| SMTP | Mail (registration, statements, campaign threshold, exceptions) | Outbound | `SMTP_HOST`, `SMTP_PORT`, `SMTP_USER`, `SMTP_PASSWORD`, `SMTP_ENABLE_SSL` | **Documented** and **Implemented** |
| SMS gateway | `communication.SendSMSMessage` | Outbound | `SMS_USERNAME`, `SMS_PASSWORD` | **Implemented** |
| SendEasy | SMS SOAP `http://sms.netgen.co.za/SMS_V2.asmx` | Outbound | WCF client in `business/Service References/send_easy/` | **Implemented** |
| Google Sheets | Scheduler import when the argument contains `googlesheetimport` | Inbound read | Service account file from `GOOGLE_SHEETS_CREDENTIALS_FILE` | **Implemented** |
| Paygenius | Card payment client in `library/Payment/PaygeniusClient.cs` | Outbound | `X-Token` and `X-Signature` headers | **Implemented** as a client. Whether SHOU-1 checkout calls it is **Unknown** |
| Country web service | Optional country, currency, and GMT lookup | Outbound | `getCountriesFromWebService` is `0` in the committed config, so this path is off | **Implemented**, disabled in the committed file |
| SonarQube | Static analysis, project key `overdrive_shou_1` | Outbound from a scanner | Token not in the repo | **Documented** in `sonar-project.properties` |
| WCF `framework_service.svc` | Dynamic DB interaction and version file get/save | Site calls the service | Binding security mode is None | **Implemented** |

## Important constraints

- Culture: appSetting `defaultCulture` is `en-ZA` (the key is duplicated in `Web.config`). `globalization` is `uiCulture="en"` and `culture="en-US"`. Both are **Implemented**. Which one wins for a given format is the ASP.NET setting that applies to that API. Treat the pair as an inconsistency that **Requires Confirmation** if a date or currency bug appears.
- `httpRuntime maxRequestLength="10048"` (about 10 MB) and `executionTimeout="1800"`.
- `compilation debug="true"` in the committed `Web.config`.
- Friendly URLs are Web Forms routes (`MapPageRoute`), not ASP.NET MVC.
- Admin module labels and the practice's real menu are database state. Source cannot list the live menu.
- `core-dev` and `core_custom/SHOU-1` can diverge. A fix in shared JavaScript or ASCX must be applied in both trees when both are scanned (`sonar-project.properties` comment).
- There is no automated test project for the site.

## Planned behaviour

No roadmap, ticket, or `TODO` product spec was found that states future scope. Inline comments such as "to do we need to handle better" on the website-user redirect (`Login.aspx.cs`) record a developer note, not an approved plan.

Status of future work: **Unknown / Requires Confirmation**.

## Requirements that could not be confirmed

1. Production base URL and whether patients use `theshoulderpractice.net`.
2. The enabled module list and canvas map in `Framework_SHOU-1`.
3. The `MonthEndUser` address and the checklist items (the items are loaded at runtime).
4. Stored procedure bodies (`sp_CalendarAccess`, invoice number, debtor age report).
5. Whether products, cart, loyalty, and job cards are in use.
6. Whether Paygenius is used for this practice.
7. IIS HTTPS, cookie flags, and the production MediSwitch host. They are not enforced in the committed `Web.config`.
