# Project plan — sawis_api

Evidence date: 2026-10-04.

Source repository: `git@bitbucket.org:silicon_bit_bucket/sawis_api.git`.

The scan-host path `~/projects/sonar_scan/repos/sawis_api` was not on this machine. The tree was cloned from `https://bitbucket.org/silicon_bit_bucket/sawis_api.git`.

There is no README, product plan, or prior Silicon Ark set for this repository. This plan describes what the repository contains. It does not decide what the product should become.

## Which revision this plan describes

Two lines of history disagree about what is current.

| Line | Tip | Date | Subject | Relation |
|---|---|---|---|---|
| `master` (`origin/HEAD`) | `162260a` | 2025-06-20 | sonar-project.properties created online with Bitbucket | Default branch. The onboarding task named this revision. Fully read. |
| `prod_api_2020` | `b0d4147` | 2026-09-01 | Merge `qa_api_2020` into `prod_api_2020` | 224 commits ahead of `master`. `master` is not an ancestor of this branch. |
| `qa_api_2020` | `dd092e8` | 2026-09-01 | deploy.php edited online with Bitbucket | 204 commits ahead of `master`. |
| `dev_api_2020` | `aaeb8d6` | 2026-08-31 | Merged in `default_api_2020` (pull request #98) | 193 commits ahead of `master`. |
| `default_api_2020` | `1d39d84` | 2026-09-01 | update htmlspecialchars errors | 185 commits ahead of `master`. |
| `feature/api/DataShare_rest_api_1.3` | `45434ec` | 2022-12-19 | returns code and array in json format | 33 commits ahead of `master`. Not compared call by call. |
| `feature/development/20240719-RS-PHP-8.2-upgrade` | `b6caa43` | 2024-07-22 | PHP 8.2 Upgrade changes (still busy) | Ancestor of `prod_api_2020`. Not an ancestor of `master`. |

`deploy.php` on `prod_api_2020` and on `qa_api_2020` changes directory to `/var/www/html/sawis_api/` and runs `git reset --hard origin/prod_api_2020`. **Inferred:** that script's target branch is `prod_api_2020`.

`deploy.php` on `master` still resets `origin/dev_api_2020` and does not `cd` to that path. That copy is the 2020 script plus no later deploy edit.

Detailed behaviour in the other four Silicon Ark files is taken from `master` at `162260a`, which was read file by file. Where `prod_api_2020` differs in a way that was checked, the difference is labelled **On `prod_api_2020`**. The email class, database class, and `project.functions.inc.php` diffs on that branch were not re-read line by line.

**Unknown / Requires Confirmation:** which branch operators treat as production today. The deploy script on the environment branches points at `prod_api_2020`. `origin/HEAD` still points at `master`.

## Product

**Inferred** from the repository name, hosts `api.sawisonline.co.za` and `sawisonline.co.za`, email display name "SAWIS Online", and the calls in `_framework/_nemo.api.cls.php`.

The running program is a PHP HTTP API, class `NemoAPI`, entered at `api.php`. It reads and writes a MySQL database named `sawis_api`. The data is wine-industry members, farms, vineyard blocks, cultivars, wine types, harvest and blend records, certification, export certificates, and user accounts. Partner-specific calls are named in code for Vinpro, WIETA, Wine Online (`WOLINE`), LMS, WineMS, EzyWine, and TerraClim / CGA.

No written statement of owner, audience, or success measure was found.

## History on `master`

| Commit | Date | Author | Subject |
|---|---|---|---|
| `0cb84dc` | 2020-10-26 | Gareth Bowers | Initial commit |
| `05ded82` | 2020-10-26 | JacquesOverdrive | ini sawis_api |
| `6855beb` | 2025-06-20 | Jaco Brits | bitbucket-pipelines.yml created online with Bitbucket |
| `162260a` | 2025-06-20 | Jaco Brits | sonar-project.properties created online with Bitbucket |

The application code on `master` arrived in `05ded82`. The 2025 commits add a SonarQube pipeline and `sonar.projectKey=sawis_api`. Those two files are absent from `prod_api_2020`.

Code comments inside `_nemo.api.cls.php` record work from 2016 through 2020 (user API v1.4, data-share v1.3, WineMS v1.6, LMS v1.7, CIS `getCGABlockList`). On `prod_api_2020`, comments continue to 2023 (`getBottleWeightList` 2021-11-23, `getEzyWine` 2022-12-05, `putCGABlockSpatial` 2023-11-13).

## Scope

In this repository:

- HTTP entry `api.php`, which constructs `NemoAPI` and calls `processApi()`.
- A second entry `api.user.php`, which fixes the vendor, the call, and a session token instead of reading them from the request.
- MySQL access through `mysqli` and `NemoDatabase`.
- Vendor allow-list `apiVendor`, session tokens `apiToken`, call log `apiLog`, and per-vendor field whitelist `apiVendorField`. Those tables are queried. Their rows are not in git.
- Lookup, member, farm, block, certification, export, WIETA, Vinpro, LMS, WineMS, and (on `prod_api_2020`) bottle-weight, EzyWine, and block-coordinate calls.
- Password hashing in `NemoPassword` (`sysPassword`).
- Password-reset email through `NemoEmail`.
- A file-integrity script `cron.fim.php` (`NemoFIM`).
- A browser form `test/index.php` that calls a short list of read methods.
- A git reset script `deploy.php`.
- Static `403.html`, `404.html`, `500.html`.
- A vendored NuSOAP tree and WSDL files. `api.php` does not load them.

Not in this repository:

- The SAWIS Online web application that reset-password links point at (`resetPassword.php` on another base URL).
- Schema migrations or a SQL dump.
- A README or user guide.
- Automated tests. `test/index.php` is a manual form.
- `system.server.QA.php` and `system.server.DEV.php` on `master`. `system.php` includes both. They are present on `prod_api_2020`.

## Architecture

```text
Browser or partner system
        │  query/body: VendorKey, call, Page, Token, type, xmlData, call arguments
        ▼
api.php  (CORS allow-list, then NemoAPI)
        │
        ├─ system.php → one server-settings file → mysqli → database sawis_api
        │
        └─ NemoAPI::processApi
              ├─ apiVendor (active vendor key)
              ├─ authenticate → apiToken, or check existing token
              ├─ method named by `call`
              └─ apiVendorField whitelist → XML, JSON, or text
```

`system.php` on `master` includes PROD, then QA, then DEV, and then forces the protocol string to `https`. Only `system.server.PROD.php` is in that tree, so QA and DEV includes fail. Warnings are excluded from `error_reporting`, so those failures are not shown.

On `prod_api_2020`, `system.php` includes one settings file based on `$_SERVER["SERVER_NAME"]`, and sets `https` only when `$_SERVER["HTTPS"]` is set.

## Major components

| Piece | Role | Evidence |
|---|---|---|
| `api.php` | HTTP front door | Read on `master`. Request binding differs on `prod_api_2020`. |
| `NemoAPI` | Call dispatch, vendor rules, paging, XML/JSON | `_framework/_nemo.api.cls.php` |
| `REST` | Request method switch, status line, `strip_tags` on inputs | `Rest.inc.php` |
| `NemoDatabase` | Table read/write used by user and write calls | `_framework/_nemo.database2.cls.php` |
| `NemoPassword` | Salted SHA-256 passwords; can create `sysPassword` | `_framework/_nemo.password.cls.php` |
| `NemoEmail` | Template mail for password reset | `_framework/_nemo.email.cls.php` |
| `NemoFIM` | Directory snapshot, compare, chmod | `_framework/_nemo.fim.cls.php`, `cron.fim.php` |
| Nemo UI classes | Menu, list, wizard, tabs, report, CSS | Included or present. No page in this repo renders a full admin UI except the email reader, which loads a layout file that is not in the tree. |
| `project.functions.inc.php` | Farm, block, hectare, harvest-location helpers | Included from `system.php` on `master`. No caller in this repository. On `prod_api_2020` the include is commented out. |

## Milestones visible in comments and git

These are labels in source comments and commit subjects, not a signed plan.

| Label | Where it appears | Status |
|---|---|---|
| WSDL version 1.1, 2016-10-02 | `wsdl/wsdl.php` documentation element | **Implemented** as a generated WSDL for an early list of GET calls. Not loaded by `api.php`. |
| Data-share API v1.3 | Header comments, 2017–2018 | **Implemented** as the lookup, member, certification, and export calls. |
| User API v1.4 | Header comments, 2017 | **Implemented** as create/update/login/password calls. |
| WineMS API v1.6 | Header comments, 2019-01 to 2019-02 | **Implemented**. `setWineMSBlockGUID` comment says "NOT DEV TESTED PROPERLY". |
| LMS v1.2 / v1.7 | Header comments, 2018-11 to 2020-03 | **Implemented** as `getMemberProfileLMS` and `getMemberIDListLMS`. |
| CIS `getCGABlockList` | 2019-06-13, farm name added 2020-03-30 | **Implemented** on `master`. |
| `getBottleWeightList` | Comment 2021-11-23 on `prod_api_2020` | **Implemented** on that branch only. |
| `getEzyWine` | Comment 2022-12-05 on `prod_api_2020` | **Implemented** on that branch only. |
| TerraClim `putCGABlockSpatial` | Comment 2023-11-13 on `prod_api_2020` | **Implemented** on that branch only. |
| PHP 8.2 upgrade | Branch tip 2024-07-22, subject "still busy" | Commits are ancestors of `prod_api_2020`. Whether the upgrade finished is **Unknown / Requires Confirmation**. |
| SonarQube on Bitbucket Pipelines | `master` only, 2025-06-20 | **Implemented** as pipeline YAML on `master`. Removed on `prod_api_2020`. |

## Known dependencies

- PHP with `mysqli`, `simplexml`, `openssl_random_pseudo_bytes`, `hash("sha256")`, and (on `prod_api_2020` `putCGABlockSpatial`) MySQL `ST_GeomFromText`.
- MySQL (or MariaDB) database `sawis_api`. Engine named in the `sysPassword` create statement is InnoDB.
- Settings rows in `sysSettings` (`PageSize`, SMTP keys, password-policy keys, `CURENT_BLOCK_YEAR`, `FIM_EXCLUDE_PATH_LIKE`). Values are not in git.
- Vendor rows in `apiVendor` and field rows in `apiVendorField`.
- An SMTP path inside `NemoEmail`. Host and credentials come from `sysSettings` keys such as `SMTP Send As Sawis3` and `SMTP BCC`.
- jQuery 2.2.0 from `ajax.googleapis.com` on `test/index.php` only.
- Bitbucket Pipelines image `sonarsource/sonarqube-scan:3.0.2` when the `master` pipeline runs. `SONAR_HOST_URL` and `SONAR_TOKEN` are pipeline variables.

No `composer.json`, `package.json`, or Docker file is in the repository.

## Current project status

**Implemented** and present on `master`: the Nemo API described above, last application commit 2020-10-26, plus a SonarQube pipeline file from 2025-06-20.

**Implemented** on `prod_api_2020` and not on `master`: environment switch in `system.php`, QA and DEV settings files, three later API calls, explicit `$_REQUEST` binding in `api.php`, `.htaccess` rewrite (the `master` file is named `deleted.htaccess`), deploy path `/var/www/html/sawis_api/` resetting `prod_api_2020`, and `index.html` containing only the heading "No Content".

**Unknown / Requires Confirmation:** whether the process on `api.sawisonline.co.za` is actually running `prod_api_2020`, and which PHP version it runs.
