Skip to content

Commit

Permalink
API Overhaul - NestJS, better plaid imports and Transaction support #77
Browse files Browse the repository at this point in the history
# The biggest refactor ever
This started with the motivation of having a good baseline before tackling the next big feature #49 but it morphed into a complete re-write of the old API in a new framework, along with tonnes of bug fixes, a comprehensive suite of API graphql tests (Which we didn't have before) and even some new functionality.

## Features
- `Transactions` - I just went ahead and implemented the backend for transactions, now given a set of tranasctions our application can apply them to a portfolio by adding / removing holdings
- Cash is now a holding, i made cash into a security, but this still needs some work. This provides a better UX as users can see cash exposure alongside their stock holdings in a single UI. IT also theoretically supports difference currencies, so down the line we could even support FX trading, although I reckon the UI for portfolios is not the best fit for FX trading.
- **Better plaid import** - I completely overthauled the plaid importing, not only is the code now actually sensible and readable, but it is faster, handles edge cases better and our UI / API can now hold **securities that do not exist on baggers**. Thats the big one for me, so if a users broker has several weird deriviates that we could not possibly have market data for,the UI can still render them and show them some kind of price information based on the plaid data. 


## Re-thinks
- Portfolios will once again go back to **Basic** , **Trade** and **Watchlist**. This is to provide users with a more taylored experience for the type of portfolio they want to work with. Because a user who just wants to quickly add several holdings directly from their phone UI to see their approximate value, does not really care about transactions, ie. when they bought and when they sold each share. And vice versa, a user who is selling trading signals to a group of users does not care about directly adding holdings, timing is everythign for those guys. So it would make sense to completeley taylor the portfolo UI based on each of these experiences.
  • Loading branch information
dan-cooke authored Aug 26, 2022
1 parent 97b8a31 commit e5b6411
Show file tree
Hide file tree
Showing 2,734 changed files with 70,977 additions and 66,689 deletions.
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
cypress
dist
.github
coverage
11 changes: 7 additions & 4 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# Editor configuration, see http://editorconfig.org
root = true

[*]
end_of_line = lf
insert_final_newline = true

[*.{js,json,yml}]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
max_line_length = off
trim_trailing_whitespace = false
37 changes: 0 additions & 37 deletions .eslintrc

This file was deleted.

36 changes: 36 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"root": true,
"plugins": ["@nrwl/nx"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {
"@nrwl/nx/enforce-module-boundaries": [
"error",
{
"enforceBuildableLibDependency": true,
"allow": ["~"],
"depConstraints": [
{
"sourceTag": "*",
"onlyDependOnLibsWithTags": ["*"]
}
]
}
]
}
},
{
"files": ["*.ts", "*.tsx"],
"extends": ["plugin:@nrwl/nx/typescript"],
"rules": {
"@typescript-eslint/no-unused-vars": "error"
}
},
{
"files": ["*.js", "*.jsx"],
"extends": ["plugin:@nrwl/nx/javascript"],
"rules": {}
}
]
}
22 changes: 10 additions & 12 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,33 @@ name: CD
on:
push:
branches:
- "develop"

- 'develop'

jobs:
deployUi:
name: "Deploy UI"
name: 'Deploy UI'
if: ${{ !contains(github.event.commits[0].message, '[skip ci]') }}
runs-on: ubuntu-latest
environment: "Production"
environment: 'Production'
steps:
- uses: actions/checkout@v2
- name: "Deploy ui"
- name: 'Deploy ui'
uses: superfly/flyctl-actions@master
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
FLY_PROJECT_PATH: packages/ui
with:
args: "deploy"
args: 'deploy -c apps/web/fly.toml'

deployApi:
name: "Deploy API"
name: 'Deploy API'
if: ${{ !contains(github.event.commits[0].message, '[skip ci]') }}
runs-on: ubuntu-latest
environment: "Production"
environment: 'Production'
steps:
- uses: actions/checkout@v2
- name: "Deploy API"
- name: 'Deploy API'
uses: superfly/flyctl-actions@master
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
FLY_PROJECT_PATH: packages/api
with:
args: "deploy"
args: 'deploy -c apps/api/fly.toml'
79 changes: 49 additions & 30 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,63 +2,82 @@ name: CI

on:
pull_request:


jobs:
test:
name: "Lint + Typecheck"
name: 'Lint + Typecheck'
if: ${{ !contains(github.event.commits[0].message, '[skip ci]') }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install
run: yarn install --immutable
- name: "Typecheck"
run: yarn typecheck
- name: "Lint"
run: yarn lint
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: nrwl/nx-set-shas@v2
with:
main-branch-name: develop
- name: Install
run: npm ci
- name: NX Workspace lint
run: npx nx workspace-lint
# This fails on the web package for some reasn
# seems quite buggy and doesnt work with exclude=web so just skippin for now
# - name: Format check
# run: npx nx format:check --exclude=web
- name: Lint
run: npx nx affected --target=lint --parallel=3
- name: Type Check
run: npx nx affected --target=type-check --parallel=3
- name: Test
run: npx nx affected --target=test --parallel=3
env:
OPEN_FIGI_KEY: ${{ secrets.OPEN_FIGI_KEY }}
PLAID_ENV: ${{ secrets.PLAID_ENV }}
PLAID_CLIENT_ID: ${{ secrets.PLAID_CLIENT_ID }}
PLAID_CLIENT_SECRET: ${{ secrets.PLAID_CLIENT_SECRET }}
IEX_BASE_URL: ${{ secrets.IEX_BASE_URL }}
IEX_TOKEN: ${{ secrets.IEX_TOKEN }}

deployUi:
name: "Deploy UI to staging"
name: 'Deploy UI to staging'
needs: test
if: ${{ !contains(github.event.commits[0].message, '[skip ci]') }}
runs-on: ubuntu-latest
environment: "Staging"
environment: 'Staging'
steps:
- uses: actions/checkout@v2
- name: "Deploy ui"
- name: 'Deploy ui'
uses: superfly/flyctl-actions@master
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
FLY_PROJECT_PATH: packages/ui
with:
args: "deploy -c fly.staging.toml"
args: 'deploy -c apps/web/fly.staging.toml'

deployApi:
name: "Deploy API to staging"
name: 'Deploy API to staging'
needs: test
if: ${{ !contains(github.event.commits[0].message, '[skip ci]') }}
runs-on: ubuntu-latest
environment: "Staging"
environment: 'Staging'
steps:
- uses: actions/checkout@v2
- name: "Deploy API"
- name: 'Deploy API'
uses: superfly/flyctl-actions@master
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
FLY_PROJECT_PATH: packages/api
with:
args: "deploy -c fly.staging.toml"
args: 'deploy -c apps/api/fly.staging.toml'

cypress-chrome:
name: "Cypress - chrome"
needs:
- deployApi
name: 'Cypress - chrome'
needs:
- deployUi
- deployApi
if: ${{ !contains(github.event.commits[0].message, '[skip ci]') }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: "yarn install"
- run: "yarn e2e:chrome"
- run: npm ci
- run: npx nx start e2e --record --key a4d15492-3acd-487c-8651-3306c6b45cb2 --browser chrome
env:
CYPRESS_FF_USER: ${{ secrets.CYPRESS_FF_USER }}
CYPRESS_FF_PASS: ${{ secrets.CYPRESS_FF_PASS }}
Expand All @@ -72,16 +91,16 @@ jobs:
CYPRESS_ATLAS_CLUSTER_URI: ${{ secrets.CYPRESS_ATLAS_CLUSTER_URI }}

cypress-firefox:
name: "Cypress - firefox"
needs:
- deployApi
name: 'Cypress - firefox'
needs:
- deployUi
- deployApi
if: ${{ !contains(github.event.commits[0].message, '[skip ci]') }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: "yarn install"
- run: "yarn e2e:firefox"
- run: npm ci
- run: npx nx start e2e --record --key a4d15492-3acd-487c-8651-3306c6b45cb2 --browser firefox
env:
CYPRESS_FF_USER: ${{ secrets.CYPRESS_FF_USER }}
CYPRESS_FF_PASS: ${{ secrets.CYPRESS_FF_PASS }}
Expand All @@ -92,4 +111,4 @@ jobs:
CYPRESS_AUTH0_CLIENT_SECRET: ${{ secrets.CYPRESS_AUTH0_CLIENT_SECRET }}
CYPRESS_AUTH0_AUDIENCE: ${{ secrets.CYPRESS_AUTH0_AUDIENCE }}
CYPRESS_AUTH0_SCOPE: ${{ secrets.CYPRESS_AUTH0_SCOPE }}
CYPRESS_ATLAS_CLUSTER_URI: ${{ secrets.CYPRESS_ATLAS_CLUSTER_URI }}
CYPRESS_ATLAS_CLUSTER_URI: ${{ secrets.CYPRESS_ATLAS_CLUSTER_URI }}
61 changes: 42 additions & 19 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,24 +1,47 @@
/node_modules
# See http://help.github.com/ignore-files/ for more about ignoring files.

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
old-api
# compiled output
dist
/tmp
/out-tsc

# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
# dependencies
node_modules

tags
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace

.yarn/*
!.yarn/cache
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

lerna-debug.log
# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings

# System Files
.DS_Store
Thumbs.db

.env*
!.env.test
# Remix files
apps/**/build
apps/**/.cache

2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v18.3.0
v16.13.0
4 changes: 4 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Add files here to ignore them from prettier formatting

/dist
/coverage
5 changes: 1 addition & 4 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
{
"trailingComma": "all",
"singleQuote": true,
"printWidth": 80,
"tabWidth": 2
"singleQuote": true
}
5 changes: 0 additions & 5 deletions .vscode/settings.json

This file was deleted.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading

0 comments on commit e5b6411

Please sign in to comment.