diff --git a/packages/api/src/controllers/v2/community/details.ts b/packages/api/src/controllers/v2/community/details.ts index e2dc1e8bc..116641396 100644 --- a/packages/api/src/controllers/v2/community/details.ts +++ b/packages/api/src/controllers/v2/community/details.ts @@ -67,6 +67,7 @@ class CommunityController { loginInactivity, search, orderBy, + lastActivity_lt, } = req.query; if (state === undefined || typeof state !== 'string') { state = undefined; @@ -100,7 +101,10 @@ class CommunityController { search !== undefined && typeof search === 'string' ? search : undefined, - orderBy + orderBy, + lastActivity_lt && typeof lastActivity_lt === 'string' + ? parseInt(lastActivity_lt, 10) + : undefined, ) .then((r) => standardResponse(res, 200, true, r)) .catch((e) => standardResponse(res, 400, false, '', { error: e })); diff --git a/packages/api/src/routes/v2/community/details.ts b/packages/api/src/routes/v2/community/details.ts index 5487a504e..dcdbcc5b9 100644 --- a/packages/api/src/routes/v2/community/details.ts +++ b/packages/api/src/routes/v2/community/details.ts @@ -248,6 +248,10 @@ export default (route: Router): void => { * type: string * required: false * description: order key and order direction separated by colon (claimed:desc) + * - in: query + * name: lastActivity_lt + * required: false + * descripition: timestamp to filter the inactive beneficiaries * security: * - BearerToken: [] * responses: diff --git a/packages/core/src/services/ubi/community/details.ts b/packages/core/src/services/ubi/community/details.ts index 5d3e8ea69..366adbe7c 100644 --- a/packages/core/src/services/ubi/community/details.ts +++ b/packages/core/src/services/ubi/community/details.ts @@ -17,6 +17,7 @@ import { getBeneficiariesByAddress, getBeneficiaries, countBeneficiaries, + countInactiveBeneficiaries, } from '../../../subgraph/queries/beneficiary'; import { getCommunityAmbassador, @@ -516,7 +517,8 @@ export class CommunityDetailsService { limit: number, filter: any, searchInput?: string, - orderBy?: string + orderBy?: string, + lastActivity_lt?: number, ): Promise<{ count: number; rows: any[]; @@ -616,7 +618,8 @@ export class CommunityDetailsService { undefined, community.contractAddress, orderKey ? `orderBy: ${orderKey}` : undefined, - orderDirection ? `orderDirection: ${orderDirection}` : undefined + orderDirection ? `orderDirection: ${orderDirection}` : undefined, + lastActivity_lt, ); count = beneficiariesSubgraph.length; @@ -633,7 +636,8 @@ export class CommunityDetailsService { undefined, community.contractAddress, orderKey ? `orderBy: ${orderKey}` : undefined, - orderDirection ? `orderDirection: ${orderDirection}` : undefined + orderDirection ? `orderDirection: ${orderDirection}` : undefined, + lastActivity_lt, ); count = beneficiariesSubgraph.length; appUsers = await models.appUser.findAll({ @@ -657,12 +661,21 @@ export class CommunityDetailsService { undefined, beneficiaryState, orderKey ? `orderBy: ${orderKey}` : undefined, - orderDirection ? `orderDirection: ${orderDirection}` : undefined - ); - count = await countBeneficiaries( - community.contractAddress, - filter.state !== null ? (filter.state as number) : undefined + orderDirection ? `orderDirection: ${orderDirection}` : undefined, + lastActivity_lt, ); + + if (lastActivity_lt) { + count = await countInactiveBeneficiaries( + community.contractAddress, + lastActivity_lt, + ) + } else { + count = await countBeneficiaries( + community.contractAddress, + filter.state !== null ? (filter.state as number) : undefined + ); + } addresses = beneficiariesSubgraph.map((beneficiary) => ethers.utils.getAddress(beneficiary.address) ); diff --git a/packages/core/src/subgraph/queries/beneficiary.ts b/packages/core/src/subgraph/queries/beneficiary.ts index abca9c3b1..2affb6cb5 100644 --- a/packages/core/src/subgraph/queries/beneficiary.ts +++ b/packages/core/src/subgraph/queries/beneficiary.ts @@ -90,7 +90,8 @@ export const getBeneficiariesByAddress = async ( inactive?: string, community?: string, orderBy?: string, - orderDirection?: string + orderDirection?: string, + lastActivity?: number, ): Promise => { try { const idsFormated = addresses.map((el) => `"${el.toLowerCase()}"`); @@ -110,6 +111,7 @@ export const getBeneficiariesByAddress = async ( ? `community: "${community.toLowerCase()}"` : '' } + ${lastActivity ? `lastActivity_lt: ${lastActivity}` : ''} } ) { address @@ -157,7 +159,8 @@ export const getBeneficiaries = async ( lastClaimAt?: string, state?: string, orderBy?: string, - orderDirection?: string + orderDirection?: string, + lastActivity?: number, ): Promise => { try { const graphqlQuery = { @@ -172,6 +175,7 @@ export const getBeneficiaries = async ( community:"${community.toLowerCase()}" ${lastClaimAt ? lastClaimAt : ''} ${state ? state : ''} + ${lastActivity ? `lastActivity_lt: ${lastActivity}` : ''} } ) { address @@ -320,3 +324,50 @@ export const countBeneficiaries = async ( throw new Error(error); } }; + +export const countInactiveBeneficiaries = async ( + community: string, + lastActivity: number +): Promise => { + try { + const graphqlQuery = { + operationName: 'beneficiaryEntities', + query: `query beneficiaryEntities { + beneficiaryEntities( + where: { + community:"${community.toLowerCase()}" + lastActivity_lt: ${lastActivity} + state: 0 + } + ) { + address + } + }`, + }; + + const response = await axiosSubgraph.post< + any, + { + data: { + data: { + beneficiaryEntities: { + address: string, + claimed: string, + since: number, + state: number, + community: { + id: string, + } + }[]; + }; + }; + } + >('', graphqlQuery); + + const beneficiaryEntities = response.data?.data.beneficiaryEntities; + + return beneficiaryEntities.length; + } catch (error) { + throw new Error(error); + } +}