Skip to content

Commit cd9ceda

Browse files
migrate to new indexer (#36)
1 parent 35dc9a8 commit cd9ceda

File tree

7 files changed

+120
-56
lines changed

7 files changed

+120
-56
lines changed

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/ext/indexer/indexer.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ class IndexerClient {
8787
getRoundManager,
8888
requestVariables
8989
);
90-
9190
if (response.rounds.length === 0) {
9291
this.logger.warn(
9392
`No round found for poolId: ${alloPoolId} on chainId: ${chainId}`
@@ -97,15 +96,15 @@ class IndexerClient {
9796

9897
const round = response.rounds[0];
9998

100-
if (round.roles.length === 0) {
99+
if (round.roundRoles.length === 0) {
101100
this.logger.warn(
102101
`No manager found for poolId: ${alloPoolId} on chainId: ${chainId}`
103102
);
104103
return [];
105104
}
106105

107106
this.logger.info(`Successfully fetched round manager`);
108-
return round.roles.map(role => role.address);
107+
return round.roundRoles.map(role => role.address);
109108
} catch (error) {
110109
this.logger.error(`Failed to fetch round manager: ${error.message}`, {
111110
error,
@@ -157,7 +156,16 @@ class IndexerClient {
157156
return null;
158157
}
159158

160-
const round = response.rounds[0];
159+
const round = {
160+
chainId: response.rounds[0].chainId,
161+
id: response.rounds[0].id,
162+
roundMetadata: response.rounds[0].roundMetadata,
163+
roundMetadataCid: response.rounds[0].roundMetadataCid,
164+
applications: response.rounds[0].applications.map(application => ({
165+
...application,
166+
project: application.projects[0],
167+
})),
168+
};
161169

162170
// Cache the result
163171
this.cache.set(cacheKey, round);
@@ -197,15 +205,15 @@ class IndexerClient {
197205
requestVariables
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+
projects(where: { projectType: { _eq: "canonical" } }) {
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: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// 1. Basic Types & Enums
12
export type Address = `0x${string}`;
23

34
export enum Status {
@@ -6,6 +7,7 @@ export enum Status {
67
REJECTED = 'REJECTED',
78
}
89

10+
// 2. Metadata & Supporting Interfaces
911
export interface ApplicationMetadata {
1012
signature: string;
1113
application: {
@@ -52,34 +54,48 @@ export interface ProjectMetadata {
5254
projectTwitter?: string;
5355
userGithub?: string;
5456
projectGithub?: string;
55-
// credentials: ProjectCredentials;
5657
owners: Array<{ address: string }>;
5758
createdAt: number;
5859
lastUpdated: number;
5960
}
6061

61-
export interface Application {
62+
// 3. Base Interfaces (Used in Multiple Places)
63+
export interface BaseProject {
64+
metadata: ProjectMetadata;
65+
metadataCid: string;
66+
}
67+
68+
export interface BaseApplication {
6269
id: string;
6370
metadata: ApplicationMetadata;
6471
metadataCid: string;
6572
status: Status;
6673
projectId: string;
67-
project: {
68-
metadata: ProjectMetadata;
69-
metadataCid: string;
70-
};
7174
}
7275

73-
export interface RoundWithApplications {
76+
// 4. Extended Implementations
77+
export interface Application extends BaseApplication {
78+
project: BaseProject;
79+
}
80+
81+
export interface ApplicationQuery extends BaseApplication {
82+
projects: BaseProject[];
83+
}
84+
85+
export interface BaseRound<T extends BaseApplication> {
7486
chainId: number;
7587
id: string;
7688
roundMetadata: RoundMetadata;
7789
roundMetadataCid: string;
78-
applications: Application[];
90+
applications: T[];
7991
}
8092

93+
export type RoundWithApplications = BaseRound<Application>;
94+
export type RoundWithApplicationsQuery = BaseRound<ApplicationQuery>;
95+
96+
// 5. API Response Structures
8197
export interface RoundApplicationsQueryResponse {
82-
rounds: RoundWithApplications[];
98+
rounds: RoundWithApplicationsQuery[];
8399
}
84100

85101
export interface ApplicationWithRound {
@@ -94,12 +110,12 @@ export interface ApplicationWithRound {
94110
}
95111

96112
export interface ApplicationRoundQueryResponse {
97-
application: ApplicationWithRound;
113+
applications: ApplicationWithRound[];
98114
}
99115

100116
export interface ManagerRolesResponse {
101117
rounds: Array<{
102-
roles: Array<{
118+
roundRoles: Array<{
103119
address: string;
104120
}>;
105121
}>;

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)