From 3e306f70255d795a6acf49edb6f2dc774c55793b Mon Sep 17 00:00:00 2001 From: ceroma <678940+ceroma@users.noreply.github.com> Date: Wed, 9 Oct 2024 14:12:08 -0300 Subject: [PATCH] RFC/one Symbol Profile per interest name Currently, each Interest activity creates a new Symbol Profile. This may leave the DB cluttered with multiple single-activity Symbols (see #3381), causing a slowness in portfolio snapshot computation and some difficulty in parsing all symbols in Admin Control > Market Data page. This is a proposal to keep a single Symbol Profile for each unique name used for an Interest-typed activity. Test Plan: 1. Create an Interest activity named "AAAA" 2. Create another Interest activity named "AAAA" 3. Verify in Market Data that only one Symbol Profile exists for both interest activities 4. Delete the first "AAAA" Interest activity 5. Verify the other activity still exists 6. Verify the "AAAA" Symbol Profile still exists 7. Delete the second "AAAA" Interest activity 8. Verify the "AAAA" Symbol Profile got deleted 9. Create an Interest activity named "BBBB" 10. Create another Interest activity named "BBBB" 11. Update one of the activities to be named "CCCC" 12. Verify one "BBBB" and one "CCCC" activities exist 12. Verify in Market Data that there are two Symbol Profiles, one for "BBBB" and one for "CCCC" 13. Rename Symbol Profile "CCCC" to "DDDD" from the Market Data page 14. Verifify the activity in Activities page shows up as "DDDD" now --- apps/api/src/app/order/order.service.ts | 62 +++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/apps/api/src/app/order/order.service.ts b/apps/api/src/app/order/order.service.ts index a26099e9d..67d41717a 100644 --- a/apps/api/src/app/order/order.service.ts +++ b/apps/api/src/app/order/order.service.ts @@ -130,11 +130,28 @@ export class OrderService { data.SymbolProfile.connectOrCreate.create.assetSubClass = assetSubClass; data.SymbolProfile.connectOrCreate.create.dataSource = dataSource; data.SymbolProfile.connectOrCreate.create.name = name; - data.SymbolProfile.connectOrCreate.create.symbol = id; data.SymbolProfile.connectOrCreate.create.userId = userId; + + let symbolProfileSymbol = id; + + if (['FEE', 'INTEREST'].includes(data.type)) { + const symbolProfile = await this.prismaService.symbolProfile.findFirst({ + where: { + dataSource: dataSource, + name: name, + userId: userId + } + }); + + if (symbolProfile) { + symbolProfileSymbol = symbolProfile.symbol; + } + } + + data.SymbolProfile.connectOrCreate.create.symbol = symbolProfileSymbol; data.SymbolProfile.connectOrCreate.where.dataSource_symbol = { dataSource, - symbol: id + symbol: symbolProfileSymbol }; } @@ -625,12 +642,51 @@ export class OrderService { let isDraft = false; - if (['FEE', 'INTEREST', 'ITEM', 'LIABILITY'].includes(data.type)) { + if (['ITEM', 'LIABILITY'].includes(data.type)) { delete data.SymbolProfile.connect; if (data.Account?.connect?.id_userId?.id === null) { data.Account = { disconnect: true }; } + } else if (['FEE', 'INTEREST'].includes(data.type)) { + if (data.Account?.connect?.id_userId?.id === null) { + data.Account = { disconnect: true }; + } + + const symbolProfileDataSource = + data.SymbolProfile.connect.dataSource_symbol.dataSource; + const symbolProfileName = + data.SymbolProfile.connect.dataSource_symbol.symbol; + + delete data.SymbolProfile.update; + delete data.SymbolProfile.connect; + + const symbolProfile = await this.prismaService.symbolProfile.findFirst({ + where: { + currency: data.currency, + dataSource: symbolProfileDataSource, + name: symbolProfileName, + userId: data.User?.connect?.id + } + }); + + const symbolProfileSymbol = symbolProfile?.symbol ?? uuidv4(); + + data.SymbolProfile.connectOrCreate = { + create: { + currency: data.currency, + dataSource: symbolProfileDataSource, + name: symbolProfileName, + symbol: symbolProfileSymbol, + userId: data.User?.connect?.id + }, + where: { + dataSource_symbol: { + dataSource: symbolProfileDataSource, + symbol: symbolProfileSymbol + } + } + }; } else { delete data.SymbolProfile.update;