# Features — lambda (IM Capital backend)

Evidence date: 2026-09-28. Revision: `master` `dfb4dca` (2024-02-02).

No feature list exists in the source repository. Status below is from code and git history.

Planned features: **none are written down**, except one code comment that taxable versus non-taxable Sanlam credentials "will change depending on user type" (`SanlamFunctions/GetToken.java`). That branch is not implemented; `taxable` is hardcoded `true`.

Removed features: **none are recorded**. Several behaviours are commented out and still present in source. Those are listed under inactive code.

## Three stacks

| Stack | Status | Evidence |
|---|---|---|
| SAM Java API | Current surface of the repository. Last commit adds a route here | `SAM/IM-CAPITAL-BACKEND-SERVICE/template.yaml` |
| Root Node Serverless | Still on `master`. Four GET routes. README is older than the YAML | `serverless.yml`, `README.md` |
| Kotlin Serverless | Still on `master`. Four GET routes with a `Java` suffix. Port of the Node token chain | `Java/IM-CAPITAL-BACKEND-SERVICE-JAVA/serverless.yml`, `GetToken.kt` |

Which stack is deployed is **Unknown / Requires Confirmation**.

## SAM HTTP features

Routes are defined in `template.yaml`. Handlers live under `SAM/IM-CAPITAL-BACKEND-SERVICE/IM-CAPITAL-BACKEND-SERVICE/src/main/java/`.

| Feature | Path | Methods | Handler | Status |
|---|---|---|---|---|
| I&M token only | `/gettoken` | GET | `getToken.GetToken` | Implemented. Does not continue into agreements |
| Token presence check | `/tokencheck` | GET | `TokenCheck.TokenCheck` | Implemented. I&M calls commented out |
| Sanlam member transactions | `/statementdata` | GET, POST, OPTIONS | `SanlamStatementData.SanlamStatementData` | Implemented. Body `member_no`, `access_token` |
| Sanlam subgroup members | `/subgroupmembers` | GET | `SanlamSubGroupMembers.SanlamSubGroupMembers` | Route implemented |
| Request OTP | `/requestotp` | GET, POST, OPTIONS | `RequestOTP.RequestOTP` | Implemented as SSM call `IM_Request_OTP` |
| Validate OTP | `/validateotp` | GET, POST, OPTIONS | `ValidateOTP.ValidateOTP` | Implemented as SSM call `IM_Validate_OTP` |
| Fixed-account balance | `/accountbalance` | GET | `AccountBalance.AccountBalance` | Implemented against a hardcoded UAT account |
| Service agreement and product summary | `/serviceagreement` | GET, POST, OPTIONS | `ServiceAgreement.ServiceAgreement` | Implemented |
| Profile image | `/profileimage` | POST, OPTIONS | `ProfileImage.ProfileImage` | Route implemented. SSM `IM_Get_Profile_Image` |
| Create or update user | `/createuser` | GET, POST, OPTIONS | `CreateUser.CreateUser` | Implemented |
| User id by email | `/getuser` | GET, POST, OPTIONS | `GetUser.GetUser` | Implemented |
| Insert local transaction | `/transaction` | GET, POST, OPTIONS | `Transaction.Transaction` | Implemented |
| Update transaction process | `/updatetransaction` | GET, POST, OPTIONS | `UpadteTransaction.UpdateTransaction` | Implemented. Package folder is spelled `UpadteTransaction` |
| List transactions by CIF | `/gettransaction` | GET, POST, OPTIONS | `GetTransactions.GetTransactions` | Implemented |
| Sanlam statement for a fixed member | `/usertoken` | GET | `UserToken.UserToken` | Implemented. Member `00638` is hardcoded |
| Daily yield | `/dailyyield` | GET, POST, OPTIONS | `SanlamDailyYield.SanlamDailyYield` | Implemented. Body `auth_token` |
| I&M customer details | `/imcustomerdetails` | GET, POST, OPTIONS | `IMCustomerDetails.IMCustomerDetails` | Route implemented. SSM `IM_Get_Customer_Details` |
| Initiate payment | `/initiatepayment` | GET, POST, OPTIONS | `InitiatePayment.InitiatePayment` | Implemented |
| Preferred 2FA | `/preferred2fa` | GET, POST, OPTIONS | `GetPreferred2FA.GetPreferred2FA` | Route implemented. SSM `IM_Preferred_2FA` |
| I&M / Sanlam statement | `/imstatement` | GET, POST, OPTIONS | `IMStatement.IMStatement` | Route implemented. SSM `Sanlam_Get_Customer_Statements` |
| Sanlam API token | `/sanlamgettoken` | GET | `SanlamGetToken.SanlamGetToken` | Implemented. Taxable credentials only |
| Purchase flow | `/sanlampurchaseflow` | GET, POST, OPTIONS | `SanlamPurchaseFlow.SanlamPurchaseFlow` | Implemented |
| Withdrawal flow | `/sanlamwithdrawalflow` | GET, POST, OPTIONS | `SanlamWithdrawalFlow.SanlamWithdrawalFlow` | Implemented |
| List Sanlam members | `/getsanlammembers` | GET, POST, OPTIONS | `GetSanlamMembers.GetSanlamMembers` | Route implemented |
| Withdrawal charges | `/sanlamwitdrawalcharge` | GET, POST, OPTIONS | `SanlamWithdrawalCharges.SanlamWithdrawalCharges` | Implemented. Path omits the second `h` in withdrawal |
| Sanlam account balance | `/sanlamaccountbalance` | GET, POST, OPTIONS | `SanlamAccountBalance.SanlamAccountBalance` | Route implemented. SSM `Sanlam_Get_Account_Balance` |
| I&M get customer | `/imgetcustomer` | GET, POST, OPTIONS | `IMGetCustomer.IMGetCustomer` | Route implemented. One customer URL in `GetIMCustomer.java` is commented out |
| Client error log | `/logerror` | GET, POST, OPTIONS | `LogError.LogError` | Implemented |
| CIF whitelist | `/checkwhitelist` | GET, POST, OPTIONS | `CheckWhiteList.CheckWhiteList` | Implemented |
| Setting by name | `/getsettings` | GET | `GetSettings.GetSettings` | Implemented. Latest feature (`dfb4dca`) |

GET, POST, and OPTIONS on the same path invoke the same Java handler. Handlers that parse `input.body` fail on a GET that has no JSON body. Provenance: **Implemented** routing; body requirement is **Inferred** from the parsers.

## SAM non-HTTP features

| Feature | Trigger | Status |
|---|---|---|
| Export `logs` to S3 | `rate(1 hour)` on `WriteS3Logs` | Implemented. Bucket `imcapital-dev-app-logs` |
| Statement test function | No API event and no schedule | Present as `StatementTest.StatementTest`. Calls `http://192.168.205.26:1880/restgateway/services/KEWeathManagementStatement/statement` from `StatementTestIM.java`. How it is invoked is **Unknown** |
| Application Insights | Commented out at the bottom of `template.yaml` | Not active |

## Node features (`serverless.yml`)

| Feature | Path | Handler | Status |
|---|---|---|---|
| Full I&M token chain through product summary | `GET /getToken` | `handler.getToken` | Implemented |
| Sanlam subgroup members for member `08000` | `GET /getMembers` | `sanlam_subgroup_members.getToken` | Implemented |
| Sanlam statement for member `00006` on date `2022-05-06` | `GET /getStatements` | `sanlam_statement_data.getToken` | Implemented |
| Token check using the caller's token | `GET /getTokenCheck` | `token_check.getTokenCheck` | Implemented. Fixture: `test/token_check.json` |

`serverless-offline` is a devDependency and a plugin. Local invoke commands are **Documented** in `README.md`.

**Discrepancy:** `README.md` documents `getTransactions` at `GET /getTransactions` and a sample body `"Success"`. `serverless.yml` has no `getTransactions` function. The README deployment section says the template deploys `getTokon` (spelling as in the file).

`express` and `serverless-http` are dependencies. The four handlers use Axios directly and do not reference Express. Provenance: **Implemented** dependency declarations; unused by the handlers that were read.

`getWelcomeLetterData` in `sanlam_subgroup_members.js` calls the I&M service-agreements URL and is not called by `module.exports.getToken`. Provenance: **Implemented** and unused.

Commented MySQL `api_logs` inserts in both Sanlam Node files are not active. Database `im_bank` appears only in those comments.

## Kotlin features

| Feature | Path | Handler |
|---|---|---|
| Token chain | `GET /getTokenJava` | `com.serverless.Handler` → `getToken()` in `GetToken.kt` |
| Token check | `GET /getTokenCheckJava` | `com.serverless.TokenCheck` |
| Statements | `GET /getStatementsJava` | `com.serverless.SanlamStatementData` |
| Members | `GET /getMembersJava` | `com.serverless.SanlamSubgroupMembers` |

`GetToken.kt` performs the same four I&M steps as Node `handler.js`. Provenance: **Implemented**.

README in that folder documents `./gradlew clean build` and `./gradlew deploy` (`build.gradle` deploy task runs `sls deploy`). Provenance: **Documented**.

## Inactive or sample code

| Item | Evidence | Status |
|---|---|---|
| Hello World SAM sample | `SAM/IM-CAPITAL-BACKEND-SERVICE/README.md` still describes `HelloWorldFunction`, `/hello`, and `sam local start-api` | README is the AWS sample text. `template.yaml` does not define `HelloWorldFunction` |
| `helloworld.App` | `src/main/java/helloworld/App.java` fetches `https://checkip.amazonaws.com` | Not routed in `template.yaml` |
| Token-check I&M calls | Commented block in `TokenCheck.java` | Inactive in the SAM function |
| Customer details URL | Commented in `GetIMCustomer.java` | Inactive at that line |
| Node MySQL logging | Commented in the two Sanlam JS files | Inactive |

## Recently changed

`dfb4dca` (2024-02-02) "adding settings api": `GET /getsettings`, `GetSettings`, `GetSettingByName`.

The previous application commits in January 2024 are message-only in this review (`new updates`, `update functions`, `logg functions`). File-level contents of those commits were not diffed one by one. The log export and `logs` table are present at `dfb4dca` and match the January "logg functions" subject. Provenance: **Inferred** link from the commit subject to `WriteS3Logs` / `LogToDatabase`.

## Deprecated

No function is marked deprecated. The Node README's `getTransactions` name does not exist in the current YAML.

## Tests as a feature

JUnit classes exist for `GetToken`, `TokenCheck`, `SanlamStatementData`, and `helloworld.App`. The `GetTokenTest` methods are empty or commented. They do not assert behaviour. Provenance: **Implemented** as files, not as executed checks.
