Skip to content

Commit

Permalink
Resolve merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
mohammadranjbarz committed May 23, 2024
2 parents f03ab1f + 0db090e commit 197f7ea
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 49 deletions.
52 changes: 52 additions & 0 deletions migration/1715728347907-AddCalculatedFieldAsColumnsForProject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class AddCalculatedFieldAsColumnsForProject1715728347907
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE "project"
ADD COLUMN IF NOT EXISTS "sumDonationValueUsdForActiveQfRound" DOUBLE PRECISION DEFAULT 0;
`);

await queryRunner.query(`
ALTER TABLE "project"
ADD COLUMN IF NOT EXISTS "sumDonationValueUsd" DOUBLE PRECISION DEFAULT 0;
`);

// Add new integer columns for counting unique donors with 'IF NOT EXISTS'
await queryRunner.query(`
ALTER TABLE "project"
ADD COLUMN IF NOT EXISTS "countUniqueDonorsForActiveQfRound" INTEGER DEFAULT 0;
`);

await queryRunner.query(`
ALTER TABLE "project"
ADD COLUMN IF NOT EXISTS "countUniqueDonors" INTEGER DEFAULT 0;
`);

await queryRunner.query(`
UPDATE "project"
SET "countUniqueDonors" = pds."uniqueDonorsCount",
"sumDonationValueUsd" = pds."sumVerifiedDonations"
FROM "project_donation_summary_view" AS pds
WHERE "project"."id" = pds."projectId";
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
// Use 'IF EXISTS' in the DROP statement to avoid errors in case the column does not exist
await queryRunner.query(
`ALTER TABLE "project" DROP COLUMN IF EXISTS "sumDonationValueUsdForActiveQfRound"`,
);
await queryRunner.query(
`ALTER TABLE "project" DROP COLUMN IF EXISTS "sumDonationValueUsd"`,
);
await queryRunner.query(
`ALTER TABLE "project" DROP COLUMN IF EXISTS "countUniqueDonorsForActiveQfRound"`,
);
await queryRunner.query(
`ALTER TABLE "project" DROP COLUMN IF EXISTS "countUniqueDonors"`,
);
}
}
41 changes: 8 additions & 33 deletions src/entities/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,6 @@ import { Category } from './category';
import { FeaturedUpdate } from './featuredUpdate';
import { getHtmlTextSummary } from '../utils/utils';
import { QfRound } from './qfRound';
import {
countUniqueDonors,
countUniqueDonorsForRound,
sumDonationValueUsd,
sumDonationValueUsdForQfRound,
} from '../repositories/donationRepository';
import {
getProjectDonationsSqrtRootSum,
getQfRoundTotalProjectsDonationsSum,
Expand Down Expand Up @@ -475,41 +469,22 @@ export class Project extends BaseEntity {
createdAt: new Date(),
}).save();
}
/**
* Custom Query Builders to chain together
*/

@Field(_type => Float, { nullable: true })
async sumDonationValueUsdForActiveQfRound() {
const activeQfRound = this.getActiveQfRound();
return activeQfRound
? await sumDonationValueUsdForQfRound({
projectId: this.id,
qfRoundId: activeQfRound.id,
})
: 0;
}
@Column({ type: 'float', nullable: true })
sumDonationValueUsdForActiveQfRound: number;

@Field(_type => Float, { nullable: true })
async sumDonationValueUsd() {
return await sumDonationValueUsd(this.id);
}
@Column({ type: 'float', nullable: true })
sumDonationValueUsd: number;

@Field(_type => Int, { nullable: true })
async countUniqueDonorsForActiveQfRound() {
const activeQfRound = this.getActiveQfRound();
return activeQfRound
? await countUniqueDonorsForRound({
projectId: this.id,
qfRoundId: activeQfRound.id,
})
: 0;
}
@Column({ type: 'int', nullable: true })
countUniqueDonorsForActiveQfRound: number;

@Field(_type => Int, { nullable: true })
async countUniqueDonors() {
return await countUniqueDonors(this.id);
}
@Column({ type: 'int', nullable: true })
countUniqueDonors: number;

// In your main class
@Field(_type => EstimatedMatching, { nullable: true })
Expand Down
1 change: 1 addition & 0 deletions src/orm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export class AppDataSource {
schema: 'public',
type: 'postgres',
replication: {
defaultMode: 'master',
master: {
database: config.get('TYPEORM_DATABASE_NAME') as string,
username: config.get('TYPEORM_DATABASE_USER') as string,
Expand Down
21 changes: 8 additions & 13 deletions src/resolvers/projectResolver.allProject.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,23 +51,18 @@ import { ChainType } from '../types/network';
describe('all projects test cases --->', allProjectsTestCases);

function allProjectsTestCases() {
it('should return projects search by owner', async () => {
it('should return projects search by title', async () => {
const result = await axios.post(graphqlUrl, {
query: fetchMultiFilterAllProjectsQuery,
variables: {
searchTerm: SEED_DATA.SECOND_USER.name,
searchTerm: SEED_DATA.FIRST_PROJECT.title,
},
});

const projects = result.data.data.allProjects.projects;
const secondUserProjects = await Project.find({
where: {
adminUserId: SEED_DATA.SECOND_USER.id,
},
});

assert.equal(projects.length, secondUserProjects.length);
assert.equal(projects[0]?.adminUserId, SEED_DATA.SECOND_USER.id);
assert.isTrue(projects.length > 0);
assert.equal(projects[0]?.adminUserId, SEED_DATA.FIRST_PROJECT.adminUserId);
assert.isNotEmpty(projects[0].addresses);
projects.forEach(project => {
assert.isNotOk(project.adminUser.email);
Expand All @@ -79,10 +74,10 @@ function allProjectsTestCases() {
getHtmlTextSummary(project.description),
);
assert.isNull(project.estimatedMatching);
assert.exists(project.sumDonationValueUsd);
assert.exists(project.sumDonationValueUsdForActiveQfRound);
assert.exists(project.countUniqueDonorsForActiveQfRound);
assert.exists(project.countUniqueDonors);
assert.isNull(project.sumDonationValueUsd);
assert.isNull(project.sumDonationValueUsdForActiveQfRound);
assert.isNull(project.countUniqueDonorsForActiveQfRound);
assert.isNull(project.countUniqueDonors);
});
});

Expand Down
6 changes: 3 additions & 3 deletions src/resolvers/projectResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,13 +329,13 @@ export class ProjectResolver {
// .setParameter('searchTerm', searchTerm)
.andWhere(
new Brackets(qb => {
qb.where('project.title % :searchTerm ', {
qb.where('project.title %> :searchTerm ', {
searchTerm,
})
.orWhere('project.description % :searchTerm ', {
.orWhere('project.description %> :searchTerm ', {
searchTerm,
})
.orWhere('project.impactLocation % :searchTerm', {
.orWhere('project.impactLocation %> :searchTerm', {
searchTerm,
});
}),
Expand Down
3 changes: 3 additions & 0 deletions src/services/donationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import { getTransactionInfoFromNetwork } from './chains';
import { getEvmTransactionTimestamp } from './chains/evm/transactionService';
import { getOrttoPersonAttributes } from '../adapters/notifications/NotificationCenterAdapter';
import { CustomToken, getTokenPrice } from './priceService';
import { updateProjectStatistics } from './projectService';

export const TRANSAK_COMPLETED_STATUS = 'COMPLETED';

Expand Down Expand Up @@ -369,6 +370,8 @@ export const syncDonationStatusWithBlockchainNetwork = async (params: {
await refreshProjectEstimatedMatchingView();
await refreshProjectDonationSummaryView();

await updateProjectStatistics(donation.projectId);

const donationStats = await getUserDonationStats(donation.userId);
const donor = await findUserById(donation.userId);

Expand Down
36 changes: 36 additions & 0 deletions src/services/projectService.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { Project } from '../entities/project';
import {
countUniqueDonors,
countUniqueDonorsForRound,
sumDonationValueUsd,
sumDonationValueUsdForQfRound,
} from '../repositories/donationRepository';
import { findProjectById } from '../repositories/projectRepository';

export const getAppropriateSlug = async (
slugBase: string,
Expand All @@ -22,6 +29,35 @@ export const getAppropriateSlug = async (
return slug;
};

export const updateProjectStatistics = async (projectId: number) => {
const project = await findProjectById(projectId);
if (!project) return;

const activeQfRound = project.getActiveQfRound();
if (activeQfRound) {
project.sumDonationValueUsdForActiveQfRound =
await sumDonationValueUsdForQfRound({
projectId: project.id,
qfRoundId: activeQfRound.id,
});
project.countUniqueDonorsForActiveQfRound = await countUniqueDonorsForRound(
{
projectId: project.id,
qfRoundId: activeQfRound.id,
},
);
}

if (!activeQfRound) {
project.sumDonationValueUsdForActiveQfRound = 0;
project.countUniqueDonorsForActiveQfRound = 0;
}

project.sumDonationValueUsd = await sumDonationValueUsd(project.id);
project.countUniqueDonors = await countUniqueDonors(project.id);
await project.save();
};

// Current Formula: will be changed possibly in the future
export const getQualityScore = (description, hasImageUpload, heartCount?) => {
const heartScore = 10;
Expand Down

0 comments on commit 197f7ea

Please sign in to comment.