Skip to content

Commit aa54ae4

Browse files
authored
Merge pull request #970 from PayButton/feat/collapse-payments-csv
feat: collapse payments csv
2 parents aff96c2 + 793f816 commit aa54ae4

11 files changed

Lines changed: 149 additions & 16 deletions

File tree

constants/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,12 @@ export const RESPONSE_MESSAGES = {
4747
FAILED_TO_FETCH_PRICE_FROM_API_500: (day: string, ticker: string) => { return { statusCode: 500, message: `Failed to fetch ${ticker} price for day ${day}` } },
4848
MISSING_WS_AUTH_KEY_400: { statusCode: 400, message: 'Missing WS_AUTH_KEY environment variable' },
4949
MISSING_PRICE_FOR_TRANSACTION_400: { statusCode: 400, message: 'Missing price for transaction.' },
50-
INVALID_PRICES_AMOUNT_FOR_TX_ON_CSV_CREATION_500: (pricesLenght: number) => { return { statusCode: 500, message: `Wrong number of prices for transactions group in CSV creation. Expected 1, got ${pricesLenght}.` } },
50+
INVALID_PRICES_AMOUNT_FOR_TX_ON_CSV_CREATION_500: (pricesLenght: number) => {
51+
return {
52+
statusCode: 500,
53+
message: `Got wrong number of prices for transactions group in CSV creation. Expected 1, got ${pricesLenght}.`
54+
}
55+
},
5156
INVALID_PRICE_STATE_400: { statusCode: 400, message: 'Missing expected quote price for transaction.' },
5257
COULD_NOT_GET_BLOCK_INFO_500: { statusCode: 500, message: "Couldn't get block info." },
5358
NETWORK_SLUG_NOT_PROVIDED_400: { statusCode: 400, message: "'networkSlug' not provided." },

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
"docker": "./scripts/docker-exec-shortcuts.sh",
1919
"ci:integration:test": "yarn pretest && dotenv -e .env.test -- ts-node -O '{\"module\":\"commonjs\"}' node_modules/jest/bin/jest.js tests/integration-tests --forceExit",
2020
"tarDebug": "tar cf debug.tar logs/ paybutton-config.json .env*",
21-
"updateAllPrices": "./scripts/update-all-prices.sh"
21+
"updateAllPrices": "./scripts/update-all-prices.sh",
22+
"updateAllPriceConnections": "./scripts/update-all-price-connections.sh"
2223
},
2324
"dependencies": {
2425
"@emotion/react": "^11.8.2",

pages/api/paybutton/download/transactions/[paybuttonId].ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ export default async (req: any, res: any): Promise<void> => {
2525
const userId = req.session.userId
2626
const user = await fetchUserProfileFromId(userId)
2727
const paybuttonId = req.query.paybuttonId as string
28-
const networkTickerReq = (req.query.network as string).toUpperCase()
28+
const networkTickerReq = req.query.network as string
2929

30-
const networkTicker = (networkTickerReq !== '' && isNetworkValid(networkTickerReq as NetworkTickersType)) ? networkTickerReq as NetworkTickersType : undefined
30+
const networkTicker = (networkTickerReq !== '' && isNetworkValid(networkTickerReq as NetworkTickersType)) ? networkTickerReq.toUpperCase() as NetworkTickersType : undefined
3131
let quoteId: number
3232
if (req.query.currency === undefined || req.query.currency === '' || Number.isNaN(req.query.currency)) {
3333
quoteId = user.preferredCurrencyId

pages/api/payments/download/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ export default async (req: any, res: any): Promise<void> => {
3131
const userReqTimezone = req.headers.timezone as string
3232
const userPreferredTimezone = user?.preferredTimezone
3333
const timezone = userPreferredTimezone !== '' ? userPreferredTimezone : userReqTimezone
34-
const networkTickerReq = (req.query.network as string).toUpperCase()
34+
const networkTickerReq = req.query.network as string
3535

36-
const networkTicker = (networkTickerReq !== '' && isNetworkValid(networkTickerReq as NetworkTickersType)) ? networkTickerReq as NetworkTickersType : undefined
36+
const networkTicker = (networkTickerReq !== '' && isNetworkValid(networkTickerReq as NetworkTickersType)) ? networkTickerReq.toUpperCase() as NetworkTickersType : undefined
3737
res.setHeader('Content-Type', 'text/csv')
3838
let networkIdArray = Object.values(NETWORK_IDS)
3939
if (networkTicker !== undefined) {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
set -e
2+
3+
echo This will affect the database. Are you sure of what you\'re doing? [y/N]
4+
read ans
5+
if [[ "$ans" = "Y" || "$ans" = "y" ]]; then
6+
JOBS_ENV=true dotenv -e .env -c -- ts-node -O '{"module":"commonjs"}' -r tsconfig-paths/register ./scripts/updateAllPriceConnections.ts
7+
else
8+
echo Exited.
9+
fi
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import { flattenTimestamp } from '../services/priceService'
2+
import prisma from 'prisma/clientInstance'
3+
import { connectTransactionsListToPrices } from 'services/transactionService'
4+
import { Transaction } from '@prisma/client'
5+
import moment from 'moment'
6+
import { exit } from 'process'
7+
8+
async function misconnectTxs (txsIds: string[]): Promise<void> {
9+
if (process.env.ENVIRONMENT === 'production') {
10+
return
11+
}
12+
if (txsIds.length === 0) {
13+
return
14+
}
15+
console.log('Misconnecting', txsIds.length, 'for testing purposes')
16+
for (const txId of txsIds) {
17+
const tx = await prisma.transaction.findUniqueOrThrow({
18+
where: {
19+
id: txId
20+
}
21+
})
22+
const txDayTimestamp = flattenTimestamp(tx.timestamp)
23+
let signal = 1
24+
if (txDayTimestamp === flattenTimestamp(moment.utc().unix())) {
25+
signal = -1
26+
}
27+
await prisma.transaction.update({
28+
where: {
29+
id: txId
30+
},
31+
data: {
32+
timestamp: tx.timestamp + (signal * 86400)
33+
}
34+
})
35+
}
36+
console.log('Finished misconnecting txs')
37+
}
38+
39+
async function fixMisconnectedTxs (): Promise<void> {
40+
const total = await prisma.transaction.count()
41+
const pageSize = 1000
42+
let page = 0
43+
44+
await misconnectTxs([
45+
// ADD TXS IDS HERE TO TEST IT
46+
])
47+
48+
console.log('Fixing misconnected txs...')
49+
while (true) {
50+
const txsToFix: Transaction[] = []
51+
// Get txs page
52+
const txs = await prisma.transaction.findMany({
53+
orderBy: {
54+
timestamp: 'asc'
55+
},
56+
include: {
57+
prices: {
58+
select: {
59+
price: {
60+
select: {
61+
timestamp: true
62+
}
63+
}
64+
}
65+
}
66+
},
67+
skip: page * pageSize,
68+
take: pageSize
69+
})
70+
71+
const viewedCount = page * pageSize + txs.length
72+
73+
// Finish if empty
74+
if (txs.length === 0) {
75+
break
76+
}
77+
78+
// Find txs with misaligned timestamps
79+
txs.forEach(tx => {
80+
const txFlattenedTimestamp = flattenTimestamp(tx.timestamp)
81+
const txPriceTimestamps = tx.prices.map(p => p.price.timestamp)
82+
if (txPriceTimestamps.filter(t => t !== txFlattenedTimestamp).length > 0) {
83+
txsToFix.push(tx)
84+
}
85+
})
86+
if (txsToFix.length !== 0) {
87+
console.log(`[${viewedCount}/${total}] Fixing ${txsToFix.length} txs...`)
88+
console.log('Tx ids:\n', txsToFix.map(t => t.id).join('\n'))
89+
await connectTransactionsListToPrices(txsToFix)
90+
console.log(`[${viewedCount}/${total}] Finished fixing ${txsToFix.length} txs.`)
91+
}
92+
console.log(`[${viewedCount}/${total}]`)
93+
page++
94+
}
95+
console.log('FINISHED')
96+
exit()
97+
}
98+
99+
async function run (): Promise<void> {
100+
await fixMisconnectedTxs()
101+
}
102+
103+
void run()

services/chronikService.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
createManyTransactions,
1010
deleteTransactions,
1111
fetchUnconfirmedTransactions,
12-
createTransaction,
12+
upsertTransaction,
1313
getSimplifiedTransactions,
1414
getSimplifiedTrasaction,
1515
connectAllTransactionsToPrices
@@ -417,7 +417,7 @@ export class ChronikBlockchainClient {
417417
const addressesWithTransactions = await this.getAddressesForTransaction(transaction)
418418
const inputAddresses = this.getSortedInputAddresses(transaction)
419419
for (const addressWithTransaction of addressesWithTransactions) {
420-
const { created, tx } = await createTransaction(addressWithTransaction.transaction)
420+
const { created, tx } = await upsertTransaction(addressWithTransaction.transaction)
421421
if (tx !== undefined) {
422422
const broadcastTxData = this.broadcastIncomingTx(addressWithTransaction.address.address, tx, inputAddresses)
423423
if (created) { // only execute trigger for newly added txs
@@ -470,7 +470,7 @@ export class ChronikBlockchainClient {
470470
const inputAddresses = this.getSortedInputAddresses(transaction)
471471

472472
for (const addressWithTransaction of addressesWithTransactions) {
473-
const { created, tx } = await createTransaction(addressWithTransaction.transaction)
473+
const { created, tx } = await upsertTransaction(addressWithTransaction.transaction)
474474
if (tx !== undefined) {
475475
const broadcastTxData = this.broadcastIncomingTx(addressWithTransaction.address.address, tx, inputAddresses)
476476
if (created) { // only execute trigger for newly added txs

services/priceService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { validatePriceAPIUrlAndToken, validateNetworkTicker } from 'utils/valida
77
import moment from 'moment'
88

99
export function flattenTimestamp (timestamp: number): number {
10-
const date = moment((timestamp * 1000))
10+
const date = moment.utc((timestamp * 1000))
1111
const dateStart = date.startOf('day')
1212
return dateStart.unix()
1313
}

services/transactionService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ interface CreateTransactionResult {
295295
created: boolean
296296
}
297297

298-
export async function createTransaction (
298+
export async function upsertTransaction (
299299
transactionData: Prisma.TransactionUncheckedCreateInput
300300
): Promise<CreateTransactionResult> {
301301
if (transactionData.amount === new Prisma.Decimal(0)) { // out transactions

tests/unittests/transactionService.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ describe('Create services', () => {
7171
...mockedTransaction,
7272
addressId: mockedBCHAddress.id
7373
}
74-
const result = await transactionService.createTransaction(
74+
const result = await transactionService.upsertTransaction(
7575
argsTransaction
7676
)
7777
expect(result).toEqual({

0 commit comments

Comments
 (0)