Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/finos-labs/bankerX
Browse files Browse the repository at this point in the history
  • Loading branch information
stephengoldbaum committed Sep 29, 2024
2 parents a5514bb + 8db9ab6 commit 73e6729
Show file tree
Hide file tree
Showing 35 changed files with 537 additions and 230 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ out/
morphir-hashes.json
morphir-ir.json
package-lock.json
*.semanticdb
*.semanticdb

.user/
.out/
106 changes: 61 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,34 @@ Purchase ('fdc3.purchase')
```ts
interface Purchase {
type: string; //'fdc3.purchase'
amount: number;
vendor: string;
timestamp: number;
purchaser: string; //is there a common identifier for the purchaser? do we even want to include this (or is this too much PII)?
merchant: string; //identifier for the merchant/point of purchase - is there a common identifier
category?: string;
data: {
amount: number;
vendor: string;
date: string;
time: string;
userID: string; //is there a common identifier for the purchaser? do we even want to include this (or is this too much PII)?
pointOfSale: string; //identifier for the merchant/point of purchase - is there a common identifier
category?: 'Groceries'
| 'Dining'
| 'Home'
| 'Shopping'
| 'Travel'
| 'Fuel';
}
}

//example
{
type: 'fdc3.purchase',
amount: 30,
vendor: 'My Favorite Vendor',
timestamp: new Date().getDate(),
purchaser: 'me',
merchant: 'you',
category: 'stuff'
{
type: 'fdc3.purchase',
data: {
amount: 30,
vendor: 'My Favorite Vendor',
date: '9/29/2024',
time: '3:28:10 PM',
userId: '[email protected]',
pointOfSale: 'POS_ID',
category: 'Groceries'
}
}

```
Expand All @@ -71,49 +82,54 @@ Terms ('fdc3.Terms')
```ts
interface Terms {
type: string; //'fdc3.terms
points: number;
rate: number;
provider: Provider; //identifiers and display information of bank providing terms
}

interface Provider {
id: string;
name: string;
logo?: string;
data: {
points: number;
rate: number;
provider: string; //display name of bank providing terms
providerId: string; //identifier of bank providing terms
}
}

//example
{
type: 'fdc3.terms',
points: 13,
rate: 1,
provider: {
name: 'E*TRADE',
id: 'testApp1',
logo: './images/etrade.png'
}
data: {
points: 13,
rate: 1,
provider: {
name: 'E*TRADE',
id: 'testApp1',
logo: './images/etrade.png'
}
}
}

```

intent: MakePurchase (result)

```ts
interface PurchaseConfirmation {
type: string; //fdc3.purchaseConfirmation
provider: Provider;
}

//example
{
type: 'fdc3.purchaseConfirmation',
provider: {
name: 'E*TRADE',
id: 'testApp1',
logo: './images/etrade.png'
}
```ts
interface PurchaseConfirmation {
type: string; //fdc3.purchaseConfirmation
data: {
provider: Provider;
}
}

//example
{
type: 'fdc3.purchaseConfirmation',
data: {
provider: {
name: 'E*TRADE',
id: 'testApp1',
logo: './images/etrade.png'
}
}
}

```

```

## Roadmap

Expand Down
50 changes: 50 additions & 0 deletions api/ReadMe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# BankerX API

Contains the Morphir model for the BankerX project.

The model includes the API for the simple banking application, that is setup to demonstrate the use of the FDC3 protocol to integrate with Morphir based services by speaking FDC3 over REST.

## Developing

### Building

At the root of the project run the following command to build the api project:

```sh
./mill api.build
```

<details>

<summary>Building for Windows users</summary>

```sh
mill.bat api.build
```

or using Powershell

```sh
.\mill.ps1 api.build
```

</details>

### Testing

At the root of the project run the following command to test the api project:

```sh
./mill api.test
```

### Morphir Code Generation

The custom mill target called `morphirScalaGen` found in the `MorphirScalaModule` is responsible for generating the Scala code from the Morphir model.
You can find the various reused custom mill targets in [`util.mill`](../util.mill) at the root of the project.

> NOTE: In order to keep incremental compilation running smoothly, the code is generated into the mill out folder, as according to mill's conventions.
> The generated [morphir-ir.json](../out/api/morphirMakeOutputDir.dest/morphir-ir.json) is found in the out folder if the `api.build` target is ran.
> The [generated Scala code](../out/api/morphirScalaGenOutputDir.dest/) is found in the out folder if the `morphirScalaGen` target is ran (it is automatically ran as a result of running `build`).
Part of the benefit of using mill is its ability to heavily customize the build process using normal Scala code.
2 changes: 1 addition & 1 deletion api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "BankerX API definitions",
"main": "index.js",
"scripts": {
"build": "morphir-elm gen -c --target-version 3.5.0 --output src/generated/scala",
"build": "morphir-elm gen -c -s --target-version 3.5.0 --output src/generated/scala",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
Expand Down
7 changes: 7 additions & 0 deletions api/package.mill
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,11 @@ object `package` extends RootModule with MorphirScalaModule with BankerXScalaMod
ivy"com.github.plokhotnyuk.jsoniter-scala::jsoniter-scala-core:${V.Libs.`jsoniter-scala`}",
ivy"com.github.plokhotnyuk.jsoniter-scala::jsoniter-scala-macros:${V.Libs.`jsoniter-scala`}",
)

object test extends ScalaTests with TestModule.ScalaTest{
def ivyDeps = Agg(
ivy"org.scalatest::scalatest::${V.Libs.scalatest}",
ivy"com.lihaoyi::pprint::${V.Libs.pprint}"
)
}
}
10 changes: 7 additions & 3 deletions api/src-elm/BankerX/API.elm
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ type alias Terms =
, promotionalPeriod : PromotionalPeriod
}


type alias BankName = String
type alias BankID = String
type alias Amount = Int
type alias Vendor = String
type alias Date = LocalDate
Expand All @@ -41,8 +42,11 @@ type alias Purchase =
, pointOfSale : PointOfSale
}

type alias BankRegistration =
{ bankName : BankName
, bankID : BankID
, getTerms : Purchase -> Terms
}

-- getTerms : Purchase -> Terms
-- getTerms purchase = todo "Implement getTerms"


41 changes: 41 additions & 0 deletions api/src-elm/BankerX/Banks/CapitalOne.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
module BankerX.Banks.CapitalOne exposing (..)

import BankerX.API exposing (..)
import Morphir.SDK.LocalDate exposing (LocalDate)
import Morphir.SDK.LocalTime exposing (LocalTime)

bankname = "Capital One Bank"
bankId = "CapitalOne"
registration: BankRegistration
registration =
{ bankName = bankname
, bankID = bankId
, getTerms = getTerms
}

preferredVendors : List Vendor
preferredVendors =
[ "Vendor.A"
, "Vendor.W"
, "Vendor.T"
]

getTerms : Purchase -> Terms
getTerms purchase =
let
points : Points
points =
getPoints purchase.vendor purchase.amount
in
{ provider = bankname
, points = points
, interestRate = 0.5
, promotionalPeriod = 30
}

getPoints : Vendor -> Amount -> Points
getPoints vendor amount =
if List.member vendor preferredVendors then
4 * amount
else
amount
41 changes: 41 additions & 0 deletions api/src-elm/BankerX/Banks/Etrade.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
module BankerX.Banks.Etrade exposing (..)

import BankerX.API exposing (..)
import Morphir.SDK.LocalDate exposing (LocalDate)
import Morphir.SDK.LocalTime exposing (LocalTime)

bankname = "Etrade"
bankId = "Etrade"
registration: BankRegistration
registration =
{ bankName = bankname
, bankID = bankId
, getTerms = getTerms
}

preferredVendors : List Vendor
preferredVendors =
[ "Gamestop"
, "Morgan Stanley"
, "NYSE"
]

getTerms : Purchase -> Terms
getTerms purchase =
let
points : Points
points =
getPoints purchase.vendor purchase.amount
in
{ provider = bankname
, points = points
, interestRate = 0.615
, promotionalPeriod = 60
}

getPoints : Vendor -> Amount -> Points
getPoints vendor amount =
if List.member vendor preferredVendors then
4 * amount
else
amount
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module BankerX.FirstBank exposing (..)
module BankerX.Banks.FirstBank exposing (..)

import BankerX.API exposing (..)
import Morphir.SDK.LocalDate exposing (LocalDate)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module BankerX.SecondBank exposing (..)
module BankerX.Banks.SecondBank exposing (..)

import BankerX.API exposing (..)
import Morphir.SDK.LocalDate exposing (LocalDate)
Expand Down
26 changes: 26 additions & 0 deletions api/src-elm/BankerX/SmartWallet.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module BankerX.SmartWallet exposing (..)
import BankerX.API exposing (..)

import BankerX.Banks.CapitalOne as CapitalOne
import BankerX.Banks.Etrade as Etrade
import BankerX.Banks.FirstBank as FirstBank
import BankerX.Banks.SecondBank as SecondBank

{-| Service definition for the SmartWallet service -}
type alias Service =
{ getTerms: BankName -> Purchase -> Maybe Terms}

{-| Service implementation for the SmartWallet service -}
service : Service
service =
{ getTerms = getTerms }

{-| Get the terms for a purchase from a bank -}
getTerms : BankName -> Purchase -> Maybe Terms
getTerms bankName purchase =
case bankName of
"CapitalOne" -> Just(CapitalOne.getTerms purchase)
"Etrade" -> Just(Etrade.getTerms purchase)
"FirstBank" -> Just(FirstBank.getTerms purchase)
"SecondBank" -> Just(SecondBank.getTerms purchase)
_ -> Nothing
7 changes: 6 additions & 1 deletion api/src/bankerx/api/Codecs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ package bankerx.api
import bankerx.API.*
import com.github.plokhotnyuk.jsoniter_scala.core.JsonValueCodec
import com.github.plokhotnyuk.jsoniter_scala.macros.JsonCodecMaker
object Codecs:

trait Codecs:
given categoryJsonValueCodec: JsonValueCodec[Category] =
JsonCodecMaker.makeWithoutDiscriminator
given purchaseJsonValueCodec: JsonValueCodec[Purchase] = JsonCodecMaker.make
given termsJsonValueCodec: JsonValueCodec[Terms] = JsonCodecMaker.make

object Codecs extends Codecs
8 changes: 4 additions & 4 deletions api/src/bankerx/api/PublicEndpoints.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import bankerx.API.*
import bankerx.api.Codecs.{given, *}

object PublicEndpoints:
val getTermsEndpoint: PublicEndpoint[Purchase, Unit, Terms, Any] =
val getTermsEndpoint
: PublicEndpoint[(BankName, Purchase), String, Terms, Any] =
endpoint.post
.in("terms")
.in("api" / "bank" / path[BankName]("bankName") / "terms")
.in(jsonBody[Purchase])
.out(jsonBody[Terms])


.errorOut(stringBody)
File renamed without changes.
Loading

0 comments on commit 73e6729

Please sign in to comment.