Skip to content

Commit

Permalink
Feat/separate givback verfied (#1770)
Browse files Browse the repository at this point in the history
* add isGivbackEligible field

* add AddIsGivbackEligibleColumnToProject1637168932304

* add UpdateIsGivbackEligibleForVerifiedProjects1637168932305 migration

* add migration to rename isProjectVerified to isProjectGivbackEligible

* change isProjectVerified tp isProjectGivbackEligible

* update octant donation

* add approve project

* treat project.verified and project.isGivbackEligible equally on sorting

* remove reset verification status on verify

* check isGivbackEligible on create ProjectVerificationForm

* add ProjectInstantPowerViewV3 migration

* use verifiedOrIsGivbackEligibleCondition

* Use different materialized view for givback factor

related to #1770

* Fix build error

* Fix build error

* Fix project query for isGivbackEligible and verified

* Fix add base token migration

* Fix eslint errors

* Fix add base token migration

* Fix add base token migration

* Fix add base token migration

* Fix donation test cases related to isGivbackEligible

* Fix build error

---------

Co-authored-by: Mohammad Ranjbar Z <[email protected]>
  • Loading branch information
MohammadPCh and mohammadranjbarz authored Sep 12, 2024
1 parent 4910d7b commit b54b825
Show file tree
Hide file tree
Showing 44 changed files with 684 additions and 120 deletions.
1 change: 1 addition & 0 deletions migration/1646295724658-createTokensTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export class createTokensTable1646295724658 implements MigrationInterface {
name text COLLATE pg_catalog."default" NOT NULL,
symbol text COLLATE pg_catalog."default" NOT NULL,
address text COLLATE pg_catalog."default" NOT NULL,
"isQR" BOOLEAN DEFAULT FALSE NOT NUL,
"networkId" integer NOT NULL,
decimals integer NOT NULL,
"order" integer,
Expand Down
2 changes: 1 addition & 1 deletion migration/1696918830123-add_octant_donations_to_db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const transactions: Partial<Donation>[] = [
transactionId:
'0x30954cb441cb7b2184e6cd1afc6acbd1318f86a68b669f6bfb2786dd459e2d6c',
currency: 'ETH',
isProjectVerified: true,
isProjectGivbackEligible: true,
isTokenEligibleForGivback: true,
amount: 5,
valueUsd: 9_458.4,
Expand Down
4 changes: 4 additions & 0 deletions migration/1716367359560-add_base_chain_tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import { NETWORK_IDS } from '../src/provider';

export class AddBaseChainTokens1716367359560 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE token ADD COLUMN IF NOT EXISTS "isQR" BOOLEAN DEFAULT FALSE NOT NULL`,
);

const environment = config.get('ENVIRONMENT') as string;

const networkId =
Expand Down
23 changes: 23 additions & 0 deletions migration/1724060343213-AddIsGivbackEligibleColumnToProject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { MigrationInterface, QueryRunner, TableColumn } from 'typeorm';

export class AddIsGivbackEligibleColumnToProject1637168932304
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
// Add the new column
await queryRunner.addColumn(
'project',
new TableColumn({
name: 'isGivbackEligible',
type: 'boolean',
isNullable: false,
default: false,
}),
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
// Drop the isGivbackEligible column
await queryRunner.dropColumn('project', 'isGivbackEligible');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class UpdateIsGivbackEligibleForVerifiedProjects1637168932305
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
// Update isGivbackEligible to true for verified projects
await queryRunner.query(`
UPDATE project
SET "isGivbackEligible" = true
WHERE "verified" = true;
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
// Revert the update (optional)
await queryRunner.query(`
UPDATE project
SET "isGivbackEligible" = false
WHERE "verified" = true;
`);
}
}
66 changes: 66 additions & 0 deletions migration/1724223781248-ProjectInstantPowerViewV3.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class ProjectInstantPowerViewV31724223781248
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
DROP MATERIALIZED VIEW IF EXISTS public.project_instant_power_view;
CREATE MATERIALIZED VIEW IF NOT EXISTS public.project_instant_power_view AS
SELECT
innerview."projectId",
ROUND(CAST(innerview."totalPower" as NUMERIC), 2) as "totalPower",
rank() OVER (
ORDER BY
innerview."totalPower" DESC
) AS "powerRank"
FROM
(
SELECT
project.id AS "projectId",
CASE
WHEN (project.verified = true OR project."isGivbackEligible" = true) AND project."statusId" = 5 THEN COALESCE(sum(pp."boostedPower"), 0 :: double precision)
ELSE 0 :: double precision
END AS "totalPower"
FROM
project
LEFT JOIN (
SELECT
"powerBoosting"."projectId",
sum("instantPowerBalance".balance * "powerBoosting".percentage :: double precision / 100 :: double precision) AS "boostedPower",
now() AS "updateTime"
FROM
instant_power_balance "instantPowerBalance"
JOIN power_boosting "powerBoosting" ON "powerBoosting"."userId" = "instantPowerBalance"."userId"
GROUP BY
"powerBoosting"."projectId"
) pp ON pp."projectId" = project.id
GROUP BY
project.id
) innerview
ORDER BY
innerview."totalPower" DESC WITH DATA;
`);

await queryRunner.query(`
CREATE UNIQUE INDEX idx_project_instant_power_view_unique ON public.project_instant_power_view ("projectId");
`);

await queryRunner.query(`
CREATE INDEX project_instant_power_view_project_id ON public.project_instant_power_view USING hash ("projectId") TABLESPACE pg_default;
`);

await queryRunner.query(`
CREATE INDEX project_instant_power_view_total_power ON public.project_instant_power_view USING btree ("totalPower" DESC) TABLESPACE pg_default;
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
DROP MATERIALIZED VIEW IF EXISTS public.project_instant_power_view;
DROP INDEX IF EXISTS public.idx_project_instant_power_view_unique;
DROP INDEX IF EXISTS public.project_instant_power_view_project_id;
DROP INDEX IF EXISTS public.project_instant_power_view_total_power;
`);
}
}
66 changes: 66 additions & 0 deletions migration/1725260193333-projectGivbackRankView.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class ProjectGivbackRankViewV31725260193333
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`
DROP
MATERIALIZED VIEW IF EXISTS public.project_givback_rank_view;
CREATE MATERIALIZED VIEW IF NOT EXISTS public.project_givback_rank_view AS
SELECT
innerview."projectId",
ROUND(CAST(innerview."totalPower" as NUMERIC), 2) as "totalPower",
rank() OVER (
ORDER BY
innerview."totalPower" DESC
) AS "powerRank",
"powerRound".round
FROM
(
SELECT
project.id AS "projectId",
CASE project."isGivbackEligible" and project."statusId" = 5 WHEN false THEN 0 :: double precision ELSE COALESCE(
sum(pp."boostedPower"),
0 :: double precision
) END AS "totalPower"
FROM
project project
LEFT JOIN (
SELECT
"powerRound".round,
"powerBoostingSnapshot"."projectId",
"powerBoostingSnapshot"."userId",
avg(
"powerBalanceSnapshot".balance * "powerBoostingSnapshot".percentage :: double precision / 100 :: double precision
) AS "boostedPower",
now() AS "updateTime"
FROM
power_round "powerRound"
JOIN power_snapshot "powerSnapshot" ON "powerSnapshot"."roundNumber" = "powerRound".round
JOIN power_balance_snapshot "powerBalanceSnapshot" ON "powerBalanceSnapshot"."powerSnapshotId" = "powerSnapshot".id
JOIN power_boosting_snapshot "powerBoostingSnapshot" ON "powerBoostingSnapshot"."powerSnapshotId" = "powerSnapshot".id
AND "powerBoostingSnapshot"."userId" = "powerBalanceSnapshot"."userId"
GROUP BY
"powerRound".round,
"powerBoostingSnapshot"."projectId",
"powerBoostingSnapshot"."userId"
) pp ON pp."projectId" = project.id
GROUP BY
project.id
) innerview,
power_round "powerRound"
ORDER BY
innerview."totalPower" DESC WITH DATA;
CREATE UNIQUE INDEX project_givback_rank_view_project_id_round_unique ON public.project_givback_rank_view ("projectId", "round");
CREATE INDEX project_givback_rank_view_project_id ON public.project_givback_rank_view USING hash ("projectId") TABLESPACE pg_default;
CREATE INDEX project_givback_rank_view_total_power ON public.project_givback_rank_view USING btree ("totalPower" DESC) TABLESPACE pg_default;
`,
);
}

public async down(_queryRunner: QueryRunner): Promise<void> {
//
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class RenameIsProjectVerifiedToIsGivbackEligibleInDonation1637168932306
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE donation
RENAME COLUMN "isProjectVerified" TO "isProjectGivbackEligible";
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE donation
RENAME COLUMN "isProjectGivbackEligible" TO "isProjectVerified";
`);
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@
"test:anchorContractAddressRepository": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/repositories/anchorContractAddressRepository.test.ts",
"test:recurringDonationRepository": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/repositories/recurringDonationRepository.test.ts",
"test:userPassportScoreRepository": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/repositories/userPassportScoreRepository.test.ts",
"test:projectGivbackRepository": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/repositories/projectGivbackViewRepository.test.ts",
"test:recurringDonationService": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/services/recurringDonationService.test.ts",
"test:dbCronRepository": "NODE_ENV=test mocha -t 90000 ./test/pre-test-scripts.ts ./src/repositories/dbCronRepository.test.ts",
"test:powerBoostingResolver": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/resolvers/powerBoostingResolver.test.ts",
Expand Down
53 changes: 53 additions & 0 deletions src/entities/ProjectGivbackRankView.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {
OneToOne,
ViewColumn,
ViewEntity,
JoinColumn,
RelationId,
BaseEntity,
PrimaryColumn,
Column,
Index,
} from 'typeorm';
import { Field, Float, Int, ObjectType } from 'type-graphql';
import { Project } from '../entities/project';
import { ColumnNumericTransformer } from '../utils/entities';

@ViewEntity('project_givback_rank_view', { synchronize: false })
@Index('project_givback_rank_view_project_id_unique', ['projectId', 'round'], {
unique: true,
})
// It's similar to ProjectPowerView, but with a small difference that it uses a different view
// That just includes project with isGivbackEligible = true
@ObjectType()
export class ProjectGivbackRankView extends BaseEntity {
@Field()
@ViewColumn()
@PrimaryColumn()
@RelationId(
(projectGivbackRankView: ProjectGivbackRankView) =>
projectGivbackRankView.project,
)
projectId: number;

@ViewColumn()
@Field(_type => Float)
@Column('numeric', {
scale: 2,
transformer: new ColumnNumericTransformer(),
})
totalPower: number;

@Field(_type => Project)
@OneToOne(_type => Project, project => project.projectPower)
@JoinColumn({ referencedColumnName: 'id' })
project: Project;

@ViewColumn()
@Field(_type => Int)
powerRank: number;

@ViewColumn()
@Field(_type => Int)
round: number;
}
2 changes: 1 addition & 1 deletion src/entities/donation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class Donation extends BaseEntity {
@Field()
@Column('boolean', { default: false })
// https://github.com/Giveth/impact-graph/issues/407#issuecomment-1066892258
isProjectVerified: boolean;
isProjectGivbackEligible: boolean;

@Field()
@Column('text', { default: DONATION_STATUS.PENDING })
Expand Down
3 changes: 3 additions & 0 deletions src/entities/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import { ProjectActualMatchingView } from './ProjectActualMatchingView';
import { ProjectSocialMedia } from './projectSocialMedia';
import { DraftRecurringDonation } from './draftRecurringDonation';
import { UserQfRoundModelScore } from './userQfRoundModelScore';
import { ProjectGivbackRankView } from './ProjectGivbackRankView';

export const getEntities = (): DataSourceOptions['entities'] => {
return [
Expand Down Expand Up @@ -118,5 +119,7 @@ export const getEntities = (): DataSourceOptions['entities'] => {
AnchorContractAddress,
RecurringDonation,
DraftRecurringDonation,

ProjectGivbackRankView,
];
};
4 changes: 4 additions & 0 deletions src/entities/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,10 @@ export class Project extends BaseEntity {
// @Column({ type: 'boolean', default: false })
// tunnableQf?: boolean;

@Field(_type => Boolean, { nullable: true })
@Column({ type: 'boolean', default: false })
isGivbackEligible: boolean;

@Field(_type => String)
@Column({
type: 'enum',
Expand Down
2 changes: 1 addition & 1 deletion src/repositories/donationRepository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ function createDonationTestCases() {
const newDonation = await createDonation({
donationAnonymous: false,
donorUser: user,
isProjectVerified: false,
isProjectGivbackEligible: false,
isTokenEligibleForGivback: false,
project,
segmentNotified: false,
Expand Down
6 changes: 3 additions & 3 deletions src/repositories/donationRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const createDonation = async (data: {
fromWalletAddress: string;
transactionId: string;
tokenAddress: string;
isProjectVerified: boolean;
isProjectGivbackEligible: boolean;
donorUser: any;
isTokenEligibleForGivback: boolean;
segmentNotified: boolean;
Expand Down Expand Up @@ -99,7 +99,7 @@ export const createDonation = async (data: {
tokenAddress,
project,
isTokenEligibleForGivback,
isProjectVerified,
isProjectGivbackEligible,
donationAnonymous,
toWalletAddress,
fromWalletAddress,
Expand Down Expand Up @@ -128,7 +128,7 @@ export const createDonation = async (data: {
tokenAddress,
project,
isTokenEligibleForGivback,
isProjectVerified,
isProjectGivbackEligible,
createdAt: new Date(),
segmentNotified: true,
toWalletAddress,
Expand Down
Loading

0 comments on commit b54b825

Please sign in to comment.