# Business rules — clientSalesTracking

Evidence date: 2026-10-18. Revision: `master` `5d5d307`.

No business-rules document exists in the source repository or previously in Silicon Ark. No rule below is **Documented**. Each rule is what the code does, marked **Inferred**. An inferred rule is not a confirmed business decision.

## Who may use the product

| ID | Rule | Source | Label |
|---|---|---|---|
| BR-001 | Any caller who can reach the PHP scripts can list every `tblClient` row, read one row by id, update contact fields, and list every `sysuser` row | No auth check in `header.php` or the four endpoint scripts | Inferred |
| BR-002 | The React UI exposes the client list and the edit form without a login | `src/App.js` routes only `/ClientDetails` and `/edit/:id` | Inferred |
| BR-003 | `sysuser` is readable from `userDetails.php` and is not shown in the UI | `userDetails.php`; no request in `src/` | Inferred |

## Client identity and fields

| ID | Rule | Source | Label |
|---|---|---|---|
| BR-004 | A client row is identified by `ClientID`. The edit route and the update statement both use that value | `ListView.js`, `getClient.php`, `update.php` | Inferred |
| BR-005 | The list shows `ClientID`, `strClient`, `strTel`, `strFax`, `strEmail`, `strAddress`, `refPaymentType`, `txtClientJob`, and `dtLastEdit` | `contactDetails.php` mapping and the table columns | Inferred |
| BR-006 | An update may change only `strClient`, `strEmail`, `strAddress`, `strTel`, and `strFax` | `UPDATE` column list in `update.php` | Inferred |
| BR-007 | Payment type (`refPaymentType`) and last edit (`dtLastEdit`) are displayed and are not written by this application | List columns vs `update.php` | Inferred. Whether the database maintains them is **Unknown / Requires Confirmation** |
| BR-008 | Client job (`txtClientJob`) is loaded into the form and is not sent or saved | `Card.js` state vs `onSubmit`; `update.php` omits the column | Inferred |
| BR-009 | The update runs only when the JSON body has `client_name` set. The other fields are then trimmed and written, including empty strings | `update.php` | Inferred |

## Update outcome

| ID | Rule | Source | Label |
|---|---|---|---|
| BR-010 | The update script does not report a normal success payload for an `UPDATE`. On a truthy query result it calls `mysqli_num_rows`. The other branch prints `0` and JSON saying "User Inserted." | `update.php` | Inferred defect in the implementation, not a business rule that a user was inserted |
| BR-011 | The screen does not tell the person whether the save worked. It logs the HTTP response | `Card.js` `onSubmit` | Inferred |

## Validation

| ID | Rule | Source | Label |
|---|---|---|---|
| BR-012 | Email is an HTML email input. No other field has a format check | `Card.js` | Inferred |
| BR-013 | The server does not check email format, telephone format, length, or that the client id exists before the `UPDATE` | `update.php` | Inferred |
| BR-014 | `ClientID` from the query string or JSON body is concatenated into SQL. There is no escaping and no type check | `getClient.php`, `update.php` | Inferred. This is an implementation constraint, not an approved data rule |
| BR-015 | List and get return whatever the database has for the mapped columns. They do not drop inactive rows, because no active flag is referenced | `contactDetails.php`, `getClient.php` | Inferred. Whether `tblClient` has further columns (the scripts also `SELECT *`) is **Unknown / Requires Confirmation** |

## Workflow constraints

| ID | Rule | Source | Label |
|---|---|---|---|
| BR-016 | The person cannot create a client in this application | No INSERT | Inferred |
| BR-017 | The person cannot delete a client in this application | No DELETE | Inferred |
| BR-018 | The list is not filtered by owner, region, payment type, or search text | `ListView.js`; filter import is commented out | Inferred |
| BR-019 | Sorting offered by the UI is on `ClientID` only | Column `sort: true` only on that field | Inferred |
| BR-020 | Pagination is in the browser. The server returns the full mapped list | `paginationFactory()`, `contactDetails.php` | Inferred |

## Access and exposure

| ID | Rule | Source | Label |
|---|---|---|---|
| BR-021 | Responses declare `Access-Control-Allow-Origin: *` | `header.php` | Inferred |
| BR-022 | `getClient.php` JSON-encodes the whole selected row, not a fixed field list. Extra columns on `tblClient` would be included | `json_encode($row)` after `SELECT *` | Inferred |
| BR-023 | The client list builds a fixed set of keys and does not return other columns | `contactDetails.php` | Inferred |

No currency, tax, discount, approval, or sales-stage rule is present in the code.
