Skip to content

Commit 3dc0196

Browse files
committed
migrate to new indexer
1 parent 35dc9a8 commit 3dc0196

File tree

9 files changed

+100
-49
lines changed

9 files changed

+100
-49
lines changed

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ SYNCHRONIZE=false
33
LOGGING=true
44
PORT=4000
55
INDEXER_URL=https://grants-stack-indexer-v2.gitcoin.co/
6+
INDEXER_ADMIN_SECRET=your_indexer_admin_secret
67
OPENAI_API_KEY=your_openai_api_key
78
NODE_ENV=development
89
# Performance tuning

src/controllers/evaluationController.ts

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,27 @@ export const recreateEvaluationQuestions = async (
108108
return;
109109
}
110110

111-
await evaluationQuestionService.resetEvaluationQuestions(
112-
chainId,
113-
alloPoolId,
114-
evaluationQuestions
111+
const [errorReset] = await catchError(
112+
evaluationQuestionService.resetEvaluationQuestions(
113+
chainId,
114+
alloPoolId,
115+
evaluationQuestions
116+
)
115117
);
116118

117-
await evaluationService.cleanEvaluations();
119+
if (errorReset !== undefined) {
120+
logger.error('Failed to reset evaluation questions', { errorReset });
121+
res.status(500).json({ message: 'Failed to reset evaluation questions' });
122+
return;
123+
}
124+
125+
const [errorClean] = await catchError(evaluationService.cleanEvaluations());
126+
127+
if (errorClean !== undefined) {
128+
logger.error('Failed to clean evaluations', { errorClean });
129+
res.status(500).json({ message: 'Failed to clean evaluations' });
130+
return;
131+
}
118132

119133
res.status(200).json(evaluationQuestions);
120134
};
@@ -150,14 +164,16 @@ export const evaluateApplication = async (
150164
summaryInput,
151165
};
152166

153-
const isAllowed = await isPoolManager<CreateEvaluationParams>(
154-
createEvaluationParams,
155-
signature,
156-
chainId,
157-
alloPoolId
167+
const [isAllowedError, isAllowed] = await catchError(
168+
isPoolManager<CreateEvaluationParams>(
169+
createEvaluationParams,
170+
signature,
171+
chainId,
172+
alloPoolId
173+
)
158174
);
159175

160-
if (!isAllowed) {
176+
if (isAllowedError !== undefined || isAllowed === undefined) {
161177
logger.warn(
162178
`User with address: ${evaluator} is not allowed to evaluate application`
163179
);
@@ -301,16 +317,17 @@ export const triggerLLMEvaluation = async (
301317
questions,
302318
};
303319

304-
try {
305-
await createLLMEvaluations([data]);
306-
res.status(200).json({ message: 'LLM evaluation triggered successfully' });
307-
} catch (error) {
320+
const [error] = await catchError(createLLMEvaluations([data]));
321+
if (error !== undefined) {
308322
logger.error('Failed to create evaluations:', error);
309323
res.status(500).json({
310324
message: 'Failed to create evaluations',
311325
error: error.message,
312326
});
313327
}
328+
329+
logger.info('LLM evaluation triggered successfully');
330+
res.status(200).json({ message: 'LLM evaluation triggered successfully' });
314331
};
315332

316333
const batchPromises = <T>(array: T[], batchSize: number): T[][] => {
Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import type { Request, Response } from 'express';
2-
import { validateRequest } from '@/utils';
2+
import { catchError, validateRequest } from '@/utils';
33
import type { ProjectApplicationForManager } from '@/ext/passport/types';
44
import { isVerified } from '@/ext/passport/credentialverification';
5+
import { createLogger } from '@/logger';
56

67
interface SocialCredentialBody {
78
application: Partial<ProjectApplicationForManager>;
89
}
910

11+
const logger = createLogger();
12+
1013
export const validateSocialCredential = async (
1114
req: Request,
1215
res: Response
@@ -15,13 +18,16 @@ export const validateSocialCredential = async (
1518

1619
const { application } = req.body as SocialCredentialBody;
1720

18-
try {
19-
const result = await isVerified(application);
20-
res.json({
21-
message: 'Social credential validated',
22-
provider: result,
23-
});
24-
} catch (error) {
21+
const [error, result] = await catchError(isVerified(application));
22+
if (error !== undefined) {
23+
logger.error('Failed to validate social credential:', error);
2524
res.status(400).json({ message: 'Error validating social credential' });
25+
return;
2626
}
27+
28+
logger.info('Social credential validated', { result });
29+
res.json({
30+
message: 'Social credential validated',
31+
provider: result,
32+
});
2733
};

src/controllers/poolController.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,17 @@ const handlePoolEvaluationQuestions = async (
186186
pool: Pool,
187187
poolMetadata: IndexerRoundMetadata
188188
): Promise<PromptEvaluationQuestions> => {
189-
const questions =
190-
await evaluationQuestionService.getEvaluationQuestionsByAlloPoolId(
189+
const [error, questions] = await catchError(
190+
evaluationQuestionService.getEvaluationQuestionsByAlloPoolId(
191191
pool.alloPoolId,
192192
pool.chainId
193-
);
193+
)
194+
);
195+
196+
if (error !== undefined || questions === undefined) {
197+
logger.error('Failed to get evaluation questions:', error);
198+
throw new Error('Failed to get evaluation questions');
199+
}
194200

195201
if (questions.length > 0) {
196202
return questions.map(question => question.question);

src/env.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ interface EnvVars {
1010
SYNCHRONIZE: string;
1111
LOGGING: string;
1212
INDEXER_URL: string;
13+
INDEXER_ADMIN_SECRET: string;
1314
OPENAI_API_KEY: string;
1415
[key: string]: string | number | undefined;
1516
}
@@ -25,6 +26,7 @@ export const env: EnvVars = {
2526
SYNCHRONIZE: process.env.SYNCHRONIZE ?? 'false',
2627
LOGGING: process.env.LOGGING ?? 'false',
2728
INDEXER_URL: process.env.INDEXER_URL ?? '',
29+
INDEXER_ADMIN_SECRET: process.env.INDEXER_ADMIN_SECRET ?? '',
2830
OPENAI_API_KEY: process.env.OPENAI_API_KEY ?? '',
2931
...process.env,
3032
};

src/ext/indexer/indexer.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,11 @@ class IndexerClient {
8585
const response: ManagerRolesResponse = await request(
8686
this.indexerEndpoint,
8787
getRoundManager,
88-
requestVariables
88+
requestVariables,
89+
{
90+
'x-hasura-admin-secret': env.INDEXER_ADMIN_SECRET,
91+
}
8992
);
90-
9193
if (response.rounds.length === 0) {
9294
this.logger.warn(
9395
`No round found for poolId: ${alloPoolId} on chainId: ${chainId}`
@@ -97,15 +99,15 @@ class IndexerClient {
9799

98100
const round = response.rounds[0];
99101

100-
if (round.roles.length === 0) {
102+
if (round.roundRoles.length === 0) {
101103
this.logger.warn(
102104
`No manager found for poolId: ${alloPoolId} on chainId: ${chainId}`
103105
);
104106
return [];
105107
}
106108

107109
this.logger.info(`Successfully fetched round manager`);
108-
return round.roles.map(role => role.address);
110+
return round.roundRoles.map(role => role.address);
109111
} catch (error) {
110112
this.logger.error(`Failed to fetch round manager: ${error.message}`, {
111113
error,
@@ -147,7 +149,10 @@ class IndexerClient {
147149
const response: RoundApplicationsQueryResponse = await request(
148150
this.indexerEndpoint,
149151
getRoundWithApplications,
150-
requestVariables
152+
requestVariables,
153+
{
154+
'x-hasura-admin-secret': env.INDEXER_ADMIN_SECRET,
155+
}
151156
);
152157

153158
if (response.rounds.length === 0) {
@@ -194,18 +199,21 @@ class IndexerClient {
194199
const response: ApplicationRoundQueryResponse = await request(
195200
this.indexerEndpoint,
196201
getApplicationWithRound,
197-
requestVariables
202+
requestVariables,
203+
{
204+
'x-hasura-admin-secret': env.INDEXER_ADMIN_SECRET,
205+
}
198206
);
199207

200-
const application = response.application;
208+
const application = response.applications[0];
201209

202210
if (application == null) {
203211
this.logger.warn(
204212
`No application found for applicationId: ${applicationId} in roundId: ${roundId} on chainId: ${chainId}`
205213
);
206214
return null;
207215
}
208-
return response.application;
216+
return application;
209217
} catch (error) {
210218
this.logger.error(
211219
`Failed to fetch round with single application: ${error.message}`,

src/ext/indexer/queries.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ import { gql } from 'graphql-request';
22

33
export const getRoundManager = gql`
44
query RoundManager($chainId: Int!, $alloPoolId: String!) {
5-
rounds(
6-
filter: { chainId: { equalTo: $chainId }, id: { equalTo: $alloPoolId } }
7-
) {
8-
roles {
5+
rounds(where: { chainId: { _eq: $chainId }, id: { _eq: $alloPoolId } }) {
6+
roundRoles {
97
address
108
}
119
}
@@ -14,9 +12,7 @@ export const getRoundManager = gql`
1412

1513
export const getRoundWithApplications = gql`
1614
query RoundApplications($chainId: Int!, $roundId: String!) {
17-
rounds(
18-
filter: { chainId: { equalTo: $chainId }, id: { equalTo: $roundId } }
19-
) {
15+
rounds(where: { chainId: { _eq: $chainId }, id: { _eq: $roundId } }) {
2016
chainId
2117
id
2218
roundMetadata
@@ -27,7 +23,7 @@ export const getRoundWithApplications = gql`
2723
metadataCid
2824
status
2925
projectId
30-
project: canonicalProject {
26+
project {
3127
metadata
3228
metadataCid
3329
}
@@ -42,7 +38,13 @@ export const getApplicationWithRound = gql`
4238
$roundId: String!
4339
$applicationId: String!
4440
) {
45-
application(chainId: $chainId, roundId: $roundId, id: $applicationId) {
41+
applications(
42+
where: {
43+
chainId: { _eq: $chainId }
44+
roundId: { _eq: $roundId }
45+
id: { _eq: $applicationId }
46+
}
47+
) {
4648
metadata
4749
metadataCid
4850
round {

src/ext/indexer/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,12 @@ export interface ApplicationWithRound {
9494
}
9595

9696
export interface ApplicationRoundQueryResponse {
97-
application: ApplicationWithRound;
97+
applications: ApplicationWithRound[];
9898
}
9999

100100
export interface ManagerRolesResponse {
101101
rounds: Array<{
102-
roles: Array<{
102+
roundRoles: Array<{
103103
address: string;
104104
}>;
105105
}>;

src/utils.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,23 @@ export async function isPoolManager<T>(
5959
chainId: number,
6060
alloPoolId: string
6161
): Promise<boolean> {
62-
const validAddresses = await indexerClient.getRoundManager({
63-
chainId,
64-
alloPoolId,
65-
});
62+
const [error, validAddresses] = await catchError(
63+
indexerClient.getRoundManager({
64+
chainId,
65+
alloPoolId,
66+
})
67+
);
68+
69+
if (error !== undefined || validAddresses === undefined) {
70+
logger.error('Failed to fetch pool manager', { error });
71+
return false;
72+
}
73+
6674
if (env.NODE_ENV === 'development' && signature === '0xdeadbeef') {
6775
logger.info('Skipping signature check in development mode');
6876
return true;
6977
}
78+
7079
try {
7180
const address = await recoverSignerAddress(obj, signature);
7281
logger.info(`Recovered address: ${address}`);

0 commit comments

Comments
 (0)