diff --git a/apps/server/src/app/__tests__/account.integration.spec.ts b/apps/server/src/app/__tests__/account.integration.spec.ts index 83ee4a04..d8ebb18e 100644 --- a/apps/server/src/app/__tests__/account.integration.spec.ts +++ b/apps/server/src/app/__tests__/account.integration.spec.ts @@ -15,11 +15,17 @@ import { startServer, stopServer } from './utils/server' import { getAxiosClient } from './utils/axios' import { resetUser } from './utils/user' import { createTestInvestmentAccount } from './utils/account' +import { default as _plaid } from '../lib/plaid' +jest.mock('../middleware/validate-plaid-jwt.ts') jest.mock('bull') +jest.mock('plaid') const prisma = new PrismaClient() +// For TypeScript support +const plaid = jest.mocked(_plaid) // eslint-disable-line + const authId = '__TEST_USER_ID__' let axios: AxiosInstance let user: User @@ -101,6 +107,10 @@ describe('/v1/accounts API', () => { mask: null, isActive: true, syncStatus: 'IDLE', + plaidType: null, + plaidSubtype: null, + plaidAccountId: null, + plaidLiability: null, currencyCode: 'USD', currentBalance: new Decimal(21_000), availableBalance: null, diff --git a/prisma/migrations/20240119180135_remove_gen_statement_investment_transaction/migration.sql b/prisma/migrations/20240119180135_remove_gen_statement_investment_transaction/migration.sql deleted file mode 100644 index 2add40ab..00000000 --- a/prisma/migrations/20240119180135_remove_gen_statement_investment_transaction/migration.sql +++ /dev/null @@ -1,7 +0,0 @@ -ALTER TABLE - "investment_transaction" DROP COLUMN "category"; - -ALTER TABLE - "investment_transaction" -ADD - COLUMN "category" "InvestmentTransactionCategory" DEFAULT 'other' :: "InvestmentTransactionCategory" NOT NULL; diff --git a/prisma/migrations/20240119213343_replace_return_calculations_function/migration.sql b/prisma/migrations/20240119213343_replace_return_calculations_function/migration.sql deleted file mode 100644 index f47d6fee..00000000 --- a/prisma/migrations/20240119213343_replace_return_calculations_function/migration.sql +++ /dev/null @@ -1,61 +0,0 @@ -CREATE OR REPLACE FUNCTION calculate_return_dietz(p_account_id account.id%type, p_start date, p_end date, out percentage numeric, out amount numeric) AS $$ - DECLARE - v_start date := GREATEST(p_start, (SELECT MIN(date) FROM account_balance WHERE account_id = p_account_id)); - v_end date := p_end; - v_days int := v_end - v_start; - BEGIN - SELECT - ROUND((b1.balance - b0.balance - flows.net) / NULLIF(b0.balance + flows.weighted, 0), 4) AS "percentage", - b1.balance - b0.balance - flows.net AS "amount" - INTO - percentage, amount - FROM - account a - LEFT JOIN LATERAL ( - SELECT - COALESCE(SUM(-fw.flow), 0) AS "net", - COALESCE(SUM(-fw.flow * fw.weight), 0) AS "weighted" - FROM ( - SELECT - SUM(it.amount) AS flow, - (v_days - (it.date - v_start))::numeric / v_days AS weight - FROM - investment_transaction it - WHERE - it.account_id = a.id - AND it.date BETWEEN v_start AND v_end - -- filter for investment_transactions that represent external flows - AND ( - it.category = 'transfer' - ) - GROUP BY - it.date - ) fw - ) flows ON TRUE - LEFT JOIN LATERAL ( - SELECT - ab.balance AS "balance" - FROM - account_balance ab - WHERE - ab.account_id = a.id AND ab.date <= v_start - ORDER BY - ab.date DESC - LIMIT 1 - ) b0 ON TRUE - LEFT JOIN LATERAL ( - SELECT - COALESCE(ab.balance, a.current_balance) AS "balance" - FROM - account_balance ab - WHERE - ab.account_id = a.id AND ab.date <= v_end - ORDER BY - ab.date DESC - LIMIT 1 - ) b1 ON TRUE - WHERE - a.id = p_account_id; - END; -$$ LANGUAGE plpgsql STABLE; - diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 9b01c4ae..d358089e 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -250,7 +250,7 @@ model InvestmentTransaction { currencyCode String @default("USD") @map("currency_code") // Derived from provider types - category InvestmentTransactionCategory @default(other) + category InvestmentTransactionCategory @default(dbgenerated("\nCASE\n WHEN (plaid_type = 'buy'::text) THEN 'buy'::\"InvestmentTransactionCategory\"\n WHEN (plaid_type = 'sell'::text) THEN 'sell'::\"InvestmentTransactionCategory\"\n WHEN (plaid_subtype = ANY (ARRAY['dividend'::text, 'qualified dividend'::text, 'non-qualified dividend'::text])) THEN 'dividend'::\"InvestmentTransactionCategory\"\n WHEN (plaid_subtype = ANY (ARRAY['non-resident tax'::text, 'tax'::text, 'tax withheld'::text])) THEN 'tax'::\"InvestmentTransactionCategory\"\n WHEN ((plaid_type = 'fee'::text) OR (plaid_subtype = ANY (ARRAY['account fee'::text, 'legal fee'::text, 'management fee'::text, 'margin expense'::text, 'transfer fee'::text, 'trust fee'::text]))) THEN 'fee'::\"InvestmentTransactionCategory\"\n WHEN (plaid_type = 'cash'::text) THEN 'transfer'::\"InvestmentTransactionCategory\"\n WHEN (plaid_type = 'cancel'::text) THEN 'cancel'::\"InvestmentTransactionCategory\"\n WHEN (finicity_investment_transaction_type = ANY (ARRAY['purchased'::text, 'purchaseToClose'::text, 'purchaseToCover'::text, 'dividendReinvest'::text, 'reinvestOfIncome'::text])) THEN 'buy'::\"InvestmentTransactionCategory\"\n WHEN (finicity_investment_transaction_type = ANY (ARRAY['sold'::text, 'soldToClose'::text, 'soldToOpen'::text])) THEN 'sell'::\"InvestmentTransactionCategory\"\n WHEN (finicity_investment_transaction_type = 'dividend'::text) THEN 'dividend'::\"InvestmentTransactionCategory\"\n WHEN (finicity_investment_transaction_type = 'tax'::text) THEN 'tax'::\"InvestmentTransactionCategory\"\n WHEN (finicity_investment_transaction_type = 'fee'::text) THEN 'fee'::\"InvestmentTransactionCategory\"\n WHEN (finicity_investment_transaction_type = ANY (ARRAY['transfer'::text, 'contribution'::text, 'deposit'::text, 'income'::text, 'interest'::text])) THEN 'transfer'::\"InvestmentTransactionCategory\"\n WHEN (finicity_investment_transaction_type = 'cancel'::text) THEN 'cancel'::\"InvestmentTransactionCategory\"\n ELSE 'other'::\"InvestmentTransactionCategory\"\nEND")) // plaid data plaidInvestmentTransactionId String? @unique @map("plaid_investment_transaction_id")