Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release Hotfixes for QF Round #1521

Merged
merged 52 commits into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from 50 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
274819c
add activeQfRoundId to sortingBy InstantBoosting
RamRamez Apr 12, 2024
992e32c
add orderBy totalDonations and totalReactions
RamRamez Apr 12, 2024
e2cbaae
Merge branch 'refs/heads/staging' into make-default-sort-better
RamRamez Apr 15, 2024
af8d37e
fix filtering by QF
RamRamez Apr 15, 2024
641fc9f
remove qfRounds joins for non qf round filters
RamRamez Apr 15, 2024
3e1f67c
add some temp logs
RamRamez Apr 15, 2024
39c4f77
remove temp logs
RamRamez Apr 15, 2024
95997e0
Fix projectActualserviceView
mohammadranjbarz Apr 21, 2024
e821acb
fix stream balance depleted issue (#1496)
RamRamez Apr 21, 2024
2d9f398
rebuild
RamRamez Apr 22, 2024
d16fd55
refresh and fetch user address separately (#1499)
CarlosQ96 Apr 23, 2024
d6a08db
Added pg_trgm extension migration (#1502)
aminlatifi Apr 23, 2024
b8c84d4
Merge branch 'refs/heads/staging' into make-default-sort-better
RamRamez Apr 24, 2024
c5c9a43
fix recurring donation count
RamRamez Apr 24, 2024
e171a38
fix actual matching cap (#1507)
CarlosQ96 Apr 25, 2024
b325be0
Merge pull request #1476 from Giveth/make-default-sort-better
RamRamez Apr 25, 2024
b1600f0
fix query error
RamRamez Apr 25, 2024
67c83b0
fix user donations count
RamRamez Apr 25, 2024
0e285f7
Merge branch 'refs/heads/staging' into fix-recurring-donation-count
RamRamez Apr 25, 2024
26ebee3
fix recurring donation count tests
RamRamez Apr 26, 2024
96e93c8
fix user recurring donation query
RamRamez Apr 26, 2024
6dcbe2c
fix user recurring donation test
RamRamez Apr 26, 2024
d55251a
Merge pull request #1504 from Giveth/fix-recurring-donation-count
RamRamez Apr 26, 2024
f3fe43d
add donations relation to qfround
RamRamez Apr 27, 2024
256ecea
add findArchivedQfRounds endpoint
RamRamez Apr 27, 2024
37dfc5d
add findArchivedQfRounds endpoint
RamRamez Apr 27, 2024
a3c1400
feat: add sponsors & banner images upload
Meriem-BM Apr 28, 2024
24aacbc
add sortBy to findArchivedQfRounds
RamRamez Apr 28, 2024
c6af88e
1.23.3
mohammadranjbarz Apr 29, 2024
1011a10
Merge branch 'master' into staging
mohammadranjbarz Apr 29, 2024
45c2d11
add new test graphql query
RamRamez Apr 29, 2024
ef27638
add tests for new QfArchivedRounds
RamRamez Apr 29, 2024
8180fcc
Merge branch 'refs/heads/staging' into Archived-QF-round-summary-page…
RamRamez Apr 29, 2024
ede05ac
fixes on qfArchivedRounds query
RamRamez Apr 29, 2024
7e70a24
add new tests for qfArchivedRounds query
RamRamez Apr 29, 2024
0408883
fix findArchivedQfRounds tests
RamRamez Apr 29, 2024
de28740
Merge branch 'refs/heads/master' into staging
RamRamez Apr 29, 2024
a9148e1
fix: keep already uploaded sponsors images
Meriem-BM Apr 30, 2024
7658c56
Merge pull request #1509 from Giveth/Archived-QF-round-summary-page-&…
RamRamez Apr 30, 2024
475fa2d
fix skip and limit for findArchivedQfRounds
RamRamez May 1, 2024
b4a24b1
Add logs and refactor the bootstrap code to help investigate latency …
mohammadranjbarz May 1, 2024
9a70d11
Add poolSize to orm config
mohammadranjbarz May 1, 2024
96dd90e
Fix eslint errors
mohammadranjbarz May 1, 2024
6891168
Merge branch 'staging' of github.com:Giveth/impact-graph into staging
mohammadranjbarz May 1, 2024
600774b
Merge branch 'fix_move_some_initialization_for_after_http_listening' …
mohammadranjbarz May 1, 2024
5fe6108
Merge pull request #1510 from Giveth/3250_add_sponsors_and_banner_img
Meriem-BM May 1, 2024
6ad48d7
remove changing squareRootSumOfProjects when cap is overflown
CarlosQ96 May 1, 2024
ef98b7a
Trigger ortto activity when user saves their profile info for the fir…
RamRamez May 2, 2024
b6b4c46
Allow to set the matching pool token & amount to be something other t…
RamRamez May 2, 2024
0955db2
Merge branch 'master' into staging
mohammadranjbarz May 2, 2024
7a0442c
add allocatedFundUSDPreferred and allocatedFundUSD to qfRound
RamRamez May 2, 2024
ac5c0e2
Merge pull request #1522 from Giveth/add-allocatedFundUSDPreferred-an…
RamRamez May 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions migration/1714018700116-add_archived_QFRound_fields.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class AddArchivedQFRoundFields1714018700116
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE "qf_round"
ADD COLUMN IF NOT EXISTS "bannerBgImage" character varying
`);

await queryRunner.query(`
ALTER TABLE "qf_round"
ADD COLUMN IF NOT EXISTS "sponsorsImgs" character varying[] DEFAULT '{}' NOT NULL
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE "qf_round"
DROP COLUMN IF EXISTS "bannerBgImage"
`);

await queryRunner.query(`
ALTER TABLE "qf_round"
DROP COLUMN IF EXISTS "sponsorsImgs"
`);
}
}
21 changes: 21 additions & 0 deletions migration/1714566501335-addTokenAndChainToQFRound.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class AddTokenAndChainToQFRound1714566501335
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE IF EXISTS "qf_round"
ADD COLUMN IF NOT EXISTS "allocatedTokenSymbol" text,
ADD COLUMN IF NOT EXISTS "allocatedTokenChainId" integer;
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE IF EXISTS "qf_round"
DROP COLUMN "allocatedTokenSymbol",
DROP COLUMN "allocatedTokenChainId";
`);
}
}
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "giveth-graphql-api",
"version": "1.23.2",
"version": "1.23.3",
"description": "Backend GraphQL server for Giveth originally forked from Topia",
"main": "./dist/index.js",
"dependencies": {
Expand Down
5 changes: 5 additions & 0 deletions src/adapters/notifications/MockNotificationAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import { logger } from '../../utils/logger';
import { RecurringDonation } from '../../entities/recurringDonation';

export class MockNotificationAdapter implements NotificationAdapterInterface {
async createOrttoProfile(params: User): Promise<void> {
logger.debug('MockNotificationAdapter createOrttoProfile', params);
return Promise.resolve(undefined);
}

async updateOrttoPeople(params: OrttoPerson[]): Promise<void> {
logger.debug('MockNotificationAdapter updateOrttoPeople', params);
return Promise.resolve(undefined);
Expand Down
2 changes: 2 additions & 0 deletions src/adapters/notifications/NotificationAdapterInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export interface OrttoPerson {
}

export interface NotificationAdapterInterface {
createOrttoProfile(params: User): Promise<void>;

updateOrttoPeople(params: OrttoPerson[]): Promise<void>;

donationReceived(params: {
Expand Down
18 changes: 17 additions & 1 deletion src/adapters/notifications/NotificationCenterAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,22 @@ export class NotificationCenterAdapter implements NotificationAdapterInterface {
return;
}

async createOrttoProfile(user: User): Promise<void> {
try {
const { id, email, firstName, lastName } = user;
await callSendNotification({
eventName: NOTIFICATIONS_EVENT_NAMES.CREATE_ORTTO_PROFILE,
trackId: 'create-ortto-profile-' + user.id,
userWalletAddress: user.walletAddress!,
segment: {
payload: { userId: id, email, firstName, lastName },
},
});
} catch (e) {
logger.error('createOrttoProfile >> error', e);
}
}

async updateOrttoPeople(people: OrttoPerson[]): Promise<void> {
// TODO we should me this to notification-center, it's not good that we call Ortto directly
try {
Expand Down Expand Up @@ -1196,7 +1212,7 @@ interface SendNotificationBody {
email?: string;
trackId?: string;
metadata?: any;
projectId: string;
projectId?: string;
userWalletAddress: string;
segment?: {
payload: any;
Expand Down
1 change: 1 addition & 0 deletions src/analytics/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,5 @@ export enum NOTIFICATIONS_EVENT_NAMES {
SUPER_TOKENS_BALANCE_WEEK = 'One week left in stream balance',
SUPER_TOKENS_BALANCE_MONTH = 'One month left in stream balance',
SUPER_TOKENS_BALANCE_DEPLETED = 'Stream balance depleted',
CREATE_ORTTO_PROFILE = 'Create Ortto profile',
}
21 changes: 21 additions & 0 deletions src/entities/qfRound.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import {
UpdateDateColumn,
CreateDateColumn,
Index,
OneToMany,
} from 'typeorm';
import { Project } from './project';
import { Donation } from './donation';

@Entity()
@ObjectType()
Expand Down Expand Up @@ -43,6 +45,14 @@ export class QfRound extends BaseEntity {
@Column()
allocatedFund: number;

@Field(_type => String, { nullable: true })
@Column({ nullable: true })
allocatedTokenSymbol: string;

@Field(_type => Number, { nullable: true })
@Column({ nullable: true })
allocatedTokenChainId: number;

@Field(_type => Number)
@Column('real', { default: 0.2 })
maximumReward: number;
Expand All @@ -67,6 +77,14 @@ export class QfRound extends BaseEntity {
@Column()
endDate: Date;

@Field(_type => String, { nullable: true })
@Column('text', { nullable: true })
bannerBgImage: string;

@Field(_type => [String])
@Column('text', { array: true, default: [] })
sponsorsImgs: string[];

@UpdateDateColumn()
updatedAt: Date;

Expand All @@ -76,6 +94,9 @@ export class QfRound extends BaseEntity {
@ManyToMany(_type => Project, project => project.qfRounds)
projects: Project[];

@OneToMany(_type => Donation, donation => donation.qfRound)
donations: Donation[];

// only projects with status active can be listed automatically
isEligibleNetwork(donationNetworkId: number): boolean {
// when not specified, all are valid
Expand Down
79 changes: 79 additions & 0 deletions src/repositories/qfRoundRepository.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Field, Float, Int, ObjectType, registerEnumType } from 'type-graphql';
import { QfRound } from '../entities/qfRound';
import { AppDataSource } from '../orm';
import { QfArchivedRoundsOrderBy } from '../resolvers/qfRoundResolver';

const qfRoundEstimatedMatchingParamsCacheDuration = Number(
process.env.QF_ROUND_ESTIMATED_MATCHING_CACHE_DURATION || 60000,
Expand All @@ -11,6 +13,83 @@ export const findAllQfRounds = async (): Promise<QfRound[]> => {
.getMany();
};

export enum QfArchivedRoundsSortType {
allocatedFund = 'allocatedFund',
totalDonations = 'totalDonations',
uniqueDonors = 'uniqueDonors',
beginDate = 'beginDate',
}

registerEnumType(QfArchivedRoundsSortType, {
name: 'QfArchivedRoundsSortType',
description: 'The attributes by which archived rounds can be sorted.',
});

@ObjectType()
export class QFArchivedRounds {
@Field(_type => String)
id: string;

@Field(_type => String, { nullable: true })
name: string;

@Field(_type => String)
slug: string;

@Field(_type => Boolean)
isActive: boolean;

@Field(_type => Int)
allocatedFund: number;

@Field(_type => [Int])
eligibleNetworks: number;

@Field(_type => Date)
beginDate: Date;

@Field(_type => Date)
endDate: Date;

@Field(_type => Float, { nullable: true })
totalDonations: number;

@Field(_type => String, { nullable: true })
uniqueDonors: string;
}

export const findArchivedQfRounds = async (
limit: number,
skip: number,
orderBy: QfArchivedRoundsOrderBy,
): Promise<QFArchivedRounds[]> => {
const { direction, field } = orderBy;
const fieldMap = {
[QfArchivedRoundsSortType.beginDate]: 'qfRound.beginDate',
[QfArchivedRoundsSortType.allocatedFund]: 'qfRound.allocatedFund',
[QfArchivedRoundsSortType.totalDonations]: 'SUM(donation.amount)',
[QfArchivedRoundsSortType.uniqueDonors]:
'COUNT(DISTINCT donation.fromWalletAddress)',
};
const fullRounds = await QfRound.createQueryBuilder('qfRound')
.where('"isActive" = false')
.leftJoin('qfRound.donations', 'donation')
.select('qfRound.id', 'id')
.addSelect('qfRound.name', 'name')
.addSelect('qfRound.slug', 'slug')
.addSelect('qfRound.isActive', 'isActive')
.addSelect('qfRound.endDate', 'endDate')
.addSelect('qfRound.eligibleNetworks', 'eligibleNetworks')
.addSelect('SUM(donation.amount)', 'totalDonations')
.addSelect('COUNT(DISTINCT donation.fromWalletAddress)', 'uniqueDonors')
.addSelect('qfRound.allocatedFund', 'allocatedFund')
.addSelect('qfRound.beginDate', 'beginDate')
.groupBy('qfRound.id')
.orderBy(fieldMap[field], direction, 'NULLS LAST')
.getRawMany();
return fullRounds.slice(skip, skip + limit);
};

export const findActiveQfRound = async (): Promise<QfRound | null> => {
return QfRound.createQueryBuilder('qf_round')
.where('"isActive" = true')
Expand Down
1 change: 0 additions & 1 deletion src/resolvers/qfRoundHistoryResolver.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Arg, Int, Query, Resolver } from 'type-graphql';

import { QfRoundHistory } from '../entities/qfRoundHistory';
import { getQfRoundHistory } from '../repositories/qfRoundHistoryRepository';

Expand Down
79 changes: 78 additions & 1 deletion src/resolvers/qfRoundResolver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,95 @@ import {
saveDonationDirectlyToDb,
saveProjectDirectlyToDb,
saveUserDirectlyToDb,
SEED_DATA,
} from '../../test/testUtils';
import { Project } from '../entities/project';
import { QfRound } from '../entities/qfRound';
import {
refreshProjectDonationSummaryView,
refreshProjectEstimatedMatchingView,
} from '../services/projectViewsService';
import { qfRoundStatsQuery } from '../../test/graphqlQueries';
import {
fetchQFArchivedRounds,
qfRoundStatsQuery,
} from '../../test/graphqlQueries';
import { generateRandomString } from '../utils/utils';
import { OrderDirection } from './projectResolver';
import { QfArchivedRoundsSortType } from '../repositories/qfRoundRepository';

describe('Fetch estimatedMatching test cases', fetchEstimatedMatchingTestCases);
describe('Fetch qfRoundStats test cases', fetchQfRoundStatesTestCases);
describe('Fetch archivedQFRounds test cases', fetchArchivedQFRoundsTestCases);

function fetchArchivedQFRoundsTestCases() {
it('should return correct data when fetching archived QF rounds', async () => {
await QfRound.update({}, { isActive: true });
const qfRound1 = QfRound.create({
isActive: true,
name: 'test1',
slug: generateRandomString(10),
allocatedFund: 100000,
minimumPassportScore: 8,
beginDate: new Date(),
endDate: moment().add(10, 'days').toDate(),
});
await qfRound1.save();

await saveDonationDirectlyToDb(
{
...createDonationData(),
valueUsd: 150,
qfRoundId: qfRound1.id,
status: 'verified',
},
SEED_DATA.FIRST_USER.id,
SEED_DATA.FIRST_PROJECT.id,
);
await saveDonationDirectlyToDb(
{
...createDonationData(),
valueUsd: 250,
qfRoundId: qfRound1.id,
status: 'verified',
},
SEED_DATA.FIRST_USER.id,
SEED_DATA.FIRST_PROJECT.id,
);

const qfRound2 = QfRound.create({
isActive: false,
name: 'test2',
slug: generateRandomString(10),
allocatedFund: 200000,
minimumPassportScore: 8,
beginDate: moment().add(-10, 'days').toDate(),
endDate: moment().add(10, 'days').toDate(),
});
await qfRound2.save();
const qfRound3 = QfRound.create({
isActive: false,
name: 'test3',
slug: generateRandomString(10),
allocatedFund: 300000,
minimumPassportScore: 8,
beginDate: new Date(),
endDate: moment().add(10, 'days').toDate(),
});
await qfRound3.save();
const result = await axios.post(graphqlUrl, {
query: fetchQFArchivedRounds,
variables: {
orderBy: {
direction: OrderDirection.DESC,
field: QfArchivedRoundsSortType.beginDate,
},
},
});
const res = result.data.data.qfArchivedRounds;
assert.equal(res[0].id, qfRound3.id);
assert.equal(res.length, 2);
});
}

function fetchQfRoundStatesTestCases() {
let qfRound: QfRound;
Expand Down
Loading
Loading