# Features — sawis_api

Evidence date: 2026-10-04.

Source: `git@bitbucket.org:silicon_bit_bucket/sawis_api.git`, `master` at `162260a` (2025-06-20), compared with `prod_api_2020` at `b0d4147` (2026-09-01).

There is no features list in the source repository. "Current" means the method or file exists on `master` at `162260a`. Items that exist only on `prod_api_2020` are marked that way. Secrets are not listed.

## Current features

### Vendor session

- **Status:** Current.
- **Behaviour:** Active `apiVendor` key, `authenticate` issues a UUID token, later calls must send it, tokens older than `3 DAY` are deleted. See PRD FR-001 and FR-002.
- **Code:** `_framework/_nemo.api.cls.php` (`checkVendor`, `authenticate`, `generateToken`, `checkToken`, `clearTokenCache`, `processApi`).

### XML and JSON bodies

- **Status:** Current.
- **Behaviour:** Default XML envelope `<data><rows><row>`. `type=json` returns `{data:{rows:[]}}`. `type=text` returns the method's string. Field names with `:` become `_` in the whitelist step.
- **Code:** `NemoAPI::xml`, `json`, `getJsonArray`, `cleanVendorRST`.

### Call log

- **Status:** Current.
- **Behaviour:** Every vendor failure, auth failure, invalid call, and successful dispatch writes `apiLog`. Rows older than 3 months are deleted on each write.
- **Code:** `NemoAPI::record`.

### Reference lists

- **Status:** Current. Comments date the v1.3 additions to March–May 2017, with dev-tested notes on several of them.
- **Behaviour:** Paged `SELECT` of cultivars, wine types, irrigation, trellis, locations, packing materials, incoterms, country codes, BG9/11 types, certificate transaction codes, reject codes, packing codes, certificate statuses, certificate results, pack volume colour, closure type, bottle description, manufacturers, magisterial districts.
- **Code:** matching `get*List` methods and `$arrCallFROM` in `_framework/_nemo.api.cls.php`.

### Members, addresses, contacts, profiles

- **Status:** Current.
- **Behaviour:** `getMemberList`, `getMemberAddressList`, `getMemberContactList`, `getMemberProfile`, `getMemberTypeList`. Vendor-specific WHERE clauses for `VINPRO`, `WOLINE`, `WIETA1`, and `EZW1NE`. Member id must be greater than 0. Member type id must be greater than 0.
- **Code:** `setVendor_CallWHERE_Additional`, `getMemberProfile`.

### Farms and vineyard blocks

- **Status:** Current.
- **Behaviour:** `getFarmList` keeps farms linked to member types `FRM000`, `FRMEST`, `FRMOWN` via relationship type `Farm to Member`, grouped by `FarmID`. `getVineyardBlockList` reads `tblBlock`. `getWIETAFarmList` adds summed hectares and a GPS flag.
- **Code:** `$arrCallFROM["getFarmList"]`, `getWIETAFarmList`.

### Blends, WSB, and WS (harvest)

- **Status:** Current. Comments 2018-03.
- **Behaviour:** `getBlendMaster` builds an OR filter from request fields that match blend-master columns. `getWSB` filters by `WSBID`. `getWS` excludes harvest items with `blnDeleted = 0` (keeps rows where the flag is not 0).
- **Code:** `getBlendMaster`, `getWSB`, `getWS`.

### Certification and wine export

- **Status:** Current. Comments 2017-04, results search parameters 2020-01-27.
- **Behaviour:** Read `tblCertification` and `tblLabAnalysis`. Write certification, lab results, and `tblExportTransaction`. Status change to `ST`, `CS`, `ES`, or `KS` clears `blnSent` and stamps `dtCertificateDate`.
- **Code:** `getCertificationList`, `getCertificationResultsList`, `setCertificationRecord`, `setCertificationResultsRecord`, `setWineExportRecord`.

### Title deeds

- **Status:** Current. Comment 2017-05-16, exclusion 2017-09-20.
- **Behaviour:** `getTitleDeedsList` from `tblTitleDeed` where `EntityType NOT LIKE '%TMP%'`.
- **Code:** `$arrCallWHERE_Additional["getTitleDeedsList"]`.

### WIETA membership

- **Status:** Current. Comment 2017-05-31 and 2017-09-29.
- **Behaviour:** Read `tblWietaCertification`. Upsert by `MemberID`. Empty certification date becomes today. Empty expiry becomes SQL `NULL`.
- **Code:** `getWietaMembershipList`, `setWietaMembership`.

### Vinpro member flag import

- **Status:** Current. The SQL statement as written uses `TRUNCATE TABEL`.
- **Behaviour:** XML rows of `MemberID` and `blnVinPro` are inserted into `tmpVinPro` and copied onto `tblMember.blnVinPro`.
- **Code:** `setVinProMembers`.

### User accounts

- **Status:** Current. Comments label this User API v1.4 (2017-06 to 2017-07). Password checks aligned to "SAWIS" in comments dated 2017-08-30, 2018-03-23, and 2019-04-08.
- **Behaviour:** `getUser`, `createUser`, `updateUser`, `setPassword`, `resetPassword`, `loginUser`, `loginToken`.
- **Code:** those methods, `_framework/_nemo.password.cls.php`.

### LMS member feed

- **Status:** Current. Comments 2018-11 through 2020-03.
- **Behaviour:** `getMemberProfileLMS` returns member contact and address fields plus nested farms. Status filter: inactive or active when `refLMS <> 9`, or active when `refLMS` is null. `getMemberIDListLMS` limits relationship types to `FRMOWN`, `FRMTNT`, `FRMSCP`. A comment says the LMS page size was cut to a tenth; that code is commented out, so the normal `PageSize` applies.
- **Code:** `getMemberProfileLMS`, `getMemberIDListLMS`.

### WineMS

- **Status:** Current. Comments 2019-01 to 2019-02. `setWineMSBlockGUID` comment: not properly dev-tested.
- **Behaviour:** Farm, member, block GUID, and SAWIS-1 reads from `vieWMS`, with active farm/member filters on several calls. Writes: cellar block staging, block activity, block GUID.
- **Code:** `getWineMS*`, `setWineMSCellar`, `setWineMSBlockActivity`, `setWineMSBlockGUID`.

### CGA block list

- **Status:** Current. Comment 2019-06-13. Farm name added 2020-03-30.
- **Behaviour:** Requires `FarmID`. Filters `intYear` to `sysSettings` key `CURENT_BLOCK_YEAR` (spelling as in code).
- **Code:** `getCGABlockList`.

### CORS for named browser origins

- **Status:** Current. Comment 2019-07-17.
- **Behaviour:** Allow-list in `api.php`. Credentials and `Access-Control-Max-Age: 86400`.
- **Code:** `api.php`.

### Password-reset and read-receipt mail hooks

- **Status:** Current.
- **Behaviour:** Reset mail from `resetPassword`. Receipt pixel sets `tblEmail.strStatus = 'Read'` unless status is `Error`, then returns a 1×1 JPEG. Online reader does the same update and tries to render `tblEmail.txtBody`. Comment on the online page: not in use on the API. Layout file `layout.online.email.incl.php` is not in the tree.
- **Code:** `email.read.receipt.php`, `email.read.online.php`, `_framework/_nemo.email.cls.php`.

### Manual API form

- **Status:** Current.
- **Behaviour:** Posts a vendor key and one of eight read calls to `{host}/sawis_api_v1/api.php`. Shows `FarmID` only for `getVineyardBlockList`.
- **Code:** `test/index.php`.

### File integrity monitor

- **Status:** Current. Class comments 2016-06-10, cron comments through 2017-05-11.
- **Behaviour:** Audit table per environment, compare, chmod. Named actions for reset, ignore, and update. Pull-master action is empty.
- **Code:** `cron.fim.php`, `_framework/_nemo.fim.cls.php`.

### Git deploy script

- **Status:** Current on `master`, behaviour differs on later branches.
- **Behaviour on `master`:** `git fetch` / `git reset --hard` of `origin/dev_api_2020`. Page title "SAWIS Upload QA".
- **On `prod_api_2020` and `qa_api_2020`:** `cd /var/www/html/sawis_api/` then reset `origin/prod_api_2020`.
- **Code:** `deploy.php`.

### SonarQube pipeline

- **Status:** Current on `master` only (2025-06-20). Deleted on `prod_api_2020`.
- **Behaviour:** Full clone. On `master` and on every pull request, pipe `sonarsource/sonarqube-scan:3.0.2` with `sonar.projectKey=sawis_api`.
- **Code:** `bitbucket-pipelines.yml`, `sonar-project.properties`.

### Static error pages

- **Status:** Current.
- **Behaviour:** `403.html`, `404.html`, `500.html` are standalone HTML files. They are not generated by `api.php`.
- **Code:** those three files.

## Current on `prod_api_2020`, absent from `master`

### Bottle weights

- **Status:** On `prod_api_2020`. Comment 2021-11-23.
- **Behaviour:** `getBottleWeightList` selects `tblBottleWeight` ordered by `BottleWeightID`, paged.
- **Code:** `_framework/_nemo.api.cls.php`.

### EzyWine harvest share

- **Status:** On `prod_api_2020`. Comment 2022-12-05, author name in the comment: Ettiene.
- **Behaviour:** `getEzyWine` by producer number and harvest year, with a consent flag `blnEzyWine`. Year `all` returns every vintage for that member.
- **Code:** `getEzyWine`.

### TerraClim block geometry

- **Status:** On `prod_api_2020`. Comment 2023-11-13, "TerraClim API".
- **Behaviour:** `putCGABlockSpatial` writes `tblBlock.Coordinates` for the year in `sysYear.intYear`.
- **Code:** `putCGABlockSpatial`.

### Environment-specific database files

- **Status:** On `prod_api_2020`. `system.php` switches on server name. `system.server.QA.php` and `system.server.DEV.php` exist. `master` includes those filenames and does not contain the files.
- **Code:** `system.php`, `system.server.*.php`.

### Front-controller rewrite

- **Status:** On `prod_api_2020` the rewrite file is `.htaccess`. On `master` the same rules are in `deleted.htaccess` and `deletedagain.htaccess` (identical contents). Git records the prod change as a rename of `deleted.htaccess` to `.htaccess`.
- **Behaviour:** Non-file requests rewrite to `api.php`.
- **Code:** `.htaccess` on `prod_api_2020`.

### Placeholder index

- **Status:** On `prod_api_2020` only.
- **Behaviour:** `index.html` body is a heading "No Content".
- **Code:** `index.html`.

## Planned or unfinished in comments

| Item | Evidence | Status |
|---|---|---|
| Token lifetime back to 30 minutes | Comment on `$SessionExpire` | **Planned** in a comment. Code value is `3 DAY`. |
| LMS page size divided by 10 | Commented-out lines in `getMemberProfileLMS` and `getListPages` | **Removed** from the running path. Comment remains. |
| `setWineExportRecord` required-field checks | Comment `//TODO!!!` | **Not implemented** beyond the key `ExportCertificateID`. |
| `setWietaMembership` required-field checks | Comment `//TODO!!!` | **Not implemented** beyond `MemberID` and the date defaults. |
| `setWineMSBlockGUID` dev test | Comment "NOT DEV TESTED PROPERLY! TODO: DEV TEST" | **Implemented** with that note. |
| `FIM: PULL MASTER DATA` | Empty `case` | **Not implemented**. |
| PHP 8.2 upgrade | Branch subject "still busy" (2024-07-22). Those commits are ancestors of `prod_api_2020`. | **Unknown / Requires Confirmation** whether the upgrade is finished. |
| `getMemberProfile` for vendor `EZW1NE` | WHERE clause forced to `AND 1=0` | **Implemented** as an empty member profile, list, address, and contact result. |

## Deprecated or disconnected

| Item | Evidence | Status |
|---|---|---|
| NuSOAP calculator WSDL | `wsdl/SawisService.wsdl`, namespace `http://maths.lenin.com`, operations add/sub/mod/mul/div. Library under `wsdl/test/lib/`. | Present. Not called by `api.php`. |
| Early HTTP-GET WSDL | `wsdl/wsdl.php` documents version 1.1 (2016-10-02) and lists cultivar, member, farm, block, irrigation, trellis, location, wine type. | Present. Not included by `api.php`. It does not list the later calls. |
| `email.read.online.php` | Comment "NB! NOT IN USE ON API". | File still runs if requested. |
| `project.functions.inc.php` helpers | Farm id, hectare, block copy, harvest location. No caller in the repository. Include commented out on `prod_api_2020`. | **Inferred** leftover from the SAWIS web app. |
| Nemo menu, wizard, tabs, report, CSS classes | Files under `_framework/`. `prod_api_2020` comments out the menu includes in `system.php`. | Not a user-facing feature of this API. |
| Sonar pipeline | On `master`, deleted on `prod_api_2020`. | **Unknown** which branch's pipeline, if any, runs in Bitbucket. |

## Recently changed

On `master`, the last behaviour change is `05ded82` (2020-10-26, "ini sawis_api"). The 2025-06-20 commits add only the pipeline and Sonar properties.

On `prod_api_2020`, the tip is 2026-09-01 (merge of `qa_api_2020`). The newest API behaviour identified in comments, not necessarily the newest commit, is `putCGABlockSpatial` (2023-11-13). Commit-by-commit product changes after that date were not classified.
