Skip to content

Commit df2704d

Browse files
committed
fixing human verification api
1 parent 26d2ecf commit df2704d

File tree

8 files changed

+131
-157
lines changed

8 files changed

+131
-157
lines changed

tooling/sparta/packages/discord/src/api/axios.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import { OpenAPIClientAxios } from "openapi-client-axios";
2-
import { apiDocs } from "@sparta/utils";
3-
import { type Client } from "@sparta/utils/openapi/types";
1+
// packages/vite/src/api/axios.ts
2+
import { type OpenAPIV3, OpenAPIClientAxios } from "openapi-client-axios";
3+
import spec from "@sparta/utils/openapi/api-docs.json";
4+
import type { Client } from "@sparta/utils/openapi/types";
45

56
const apiInstance = new OpenAPIClientAxios({
6-
// @ts-ignore
7-
definition: apiDocs,
7+
definition: spec as OpenAPIV3.Document,
8+
// validate: false, // Invalid option, removed
89
axiosConfigDefaults: {
9-
baseURL: process.env.VITE_APP_API_URL || "http://localhost:3000",
10+
baseURL: process.env.VITE_APP_API_URL,
1011
timeout: 10_000,
1112
headers: {
1213
"Content-Type": "application/json",

tooling/sparta/packages/discord/src/slashCommands/humans/verify.ts

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { randomUUID } from "crypto";
1818
import { VERIFICATION_STATUS } from "@sparta/utils/const";
1919
import { getDiscordInstance } from "../../clients/discord";
2020
import { HumanSubcommands } from "../../types.js";
21+
import { clientPromise } from "../../api/axios";
2122

2223
/**
2324
* Command definition for the verify subcommand
@@ -40,33 +41,29 @@ export async function handleVerifyCommand(
4041
let discordUsername = interaction.user.username;
4142

4243
// Get API client
43-
const discord = await getDiscordInstance();
44-
const apiProvider = discord.getApiProvider();
45-
const client = apiProvider.getClient();
44+
const client = await clientPromise;
4645

4746
logger.debug(
4847
{ userId, interactionToken, verificationId },
4948
"Verify command"
5049
);
5150

52-
// Check if the user already exists
53-
const userResponse = await client.getUserByDiscordId({
54-
discordUserId: userId,
55-
});
56-
5751
try {
58-
logger.debug({ userResponse }, "User response");
52+
// Check if the user already exists
53+
const { data } = await client.getUserByDiscordId({
54+
discordUserId: userId,
55+
});
5956

60-
const user = userResponse.data.user;
57+
logger.debug({ data }, "User response");
6158

62-
if (user) {
59+
if (data.user) {
6360
// Update existing user
6461
await client.updateUser(
6562
{ discordUserId: userId },
6663
{
6764
humanPassport: {
6865
status:
69-
user.humanPassport?.status ||
66+
data.user.humanPassport?.status ||
7067
VERIFICATION_STATUS.NOT_VERIFIED,
7168
verificationId,
7269
interactionToken,
@@ -79,6 +76,8 @@ export async function handleVerifyCommand(
7976
"Updated user verification data"
8077
);
8178
} else {
79+
logger.info("User not found, creating new user");
80+
8281
// Create a new user
8382
const timestamp = Date.now();
8483

@@ -96,22 +95,23 @@ export async function handleVerifyCommand(
9695
},
9796
});
9897

99-
await client.createUser({
100-
discordUserId: userId,
101-
discordUsername,
102-
walletAddress: undefined,
103-
role: undefined,
104-
humanPassport: {
105-
//@ts-ignore
106-
status: VERIFICATION_STATUS.NOT_VERIFIED,
107-
verificationId,
108-
interactionToken,
109-
lastVerificationTime: null,
110-
score: null,
111-
},
112-
createdAt: timestamp,
113-
updatedAt: timestamp,
114-
});
98+
await client.createUser(
99+
{},
100+
{
101+
discordUserId: userId,
102+
discordUsername,
103+
walletAddress: undefined,
104+
role: undefined,
105+
humanPassport: {
106+
//@ts-ignore
107+
status: VERIFICATION_STATUS.NOT_VERIFIED,
108+
verificationId,
109+
interactionToken,
110+
lastVerificationTime: null,
111+
score: null,
112+
},
113+
}
114+
);
115115

116116
logger.info(
117117
{ userId, verificationId },

tooling/sparta/packages/express/src/db/userRepository.ts

Lines changed: 51 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -12,44 +12,38 @@ import {
1212
DeleteCommand,
1313
QueryCommand,
1414
ScanCommand,
15+
DynamoDBDocumentClient,
1516
} from "@aws-sdk/lib-dynamodb";
1617
import type { User } from "../routes/users/users.js";
1718
import DynamoDBService from "@sparta/utils/dynamo-db.js";
1819

19-
// Type for extended DynamoDB with user methods
20-
interface ExtendedDynamoDB {
21-
getUser(discordUserId: string): Promise<User | null>;
22-
getUserByVerificationId(verificationId: string): Promise<User | null>;
23-
getUserByWalletAddress(walletAddress: string): Promise<User | null>;
24-
getAllUsers(): Promise<User[]>;
25-
createUser(user: User): Promise<User | null>;
26-
updateUser(discordUserId: string, updates: Partial<User>): Promise<boolean>;
27-
deleteUser(discordUserId: string): Promise<boolean>;
28-
getClient(): any;
29-
}
30-
3120
const USERS_TABLE_NAME = process.env.USERS_TABLE_NAME || "users";
3221

3322
// Instantiate the shared service for the users table
34-
const dynamoDB = new DynamoDBService(USERS_TABLE_NAME);
23+
const dynamoDBService = new DynamoDBService(USERS_TABLE_NAME);
3524

36-
const extendedDynamoDB = dynamoDB as unknown as ExtendedDynamoDB;
25+
export class UserRepository {
26+
private client: DynamoDBDocumentClient;
27+
private tableName: string;
3728

38-
logger.info("dynamoDB config", dynamoDB.getClient().config);
29+
constructor() {
30+
this.tableName = USERS_TABLE_NAME;
31+
// Get the client instance from the shared service
32+
this.client = dynamoDBService.getClient();
33+
logger.info(
34+
`UserRepository initialized using shared DynamoDBService for table: ${this.tableName}`
35+
);
36+
}
3937

40-
// Extend the DynamoDB service with user operations
41-
export function extendDynamoDBWithUserMethods(): void {
4238
// Get user by Discord ID
43-
extendedDynamoDB.getUser = async (
44-
discordUserId: string
45-
): Promise<User | null> => {
39+
async getUser(discordUserId: string): Promise<User | null> {
4640
try {
4741
const command = new GetCommand({
48-
TableName: process.env.USERS_TABLE_NAME || "users",
42+
TableName: this.tableName,
4943
Key: { discordUserId },
5044
});
5145

52-
const response = await dynamoDB.getClient().send(command);
46+
const response = await this.client.send(command);
5347
return (response.Item as User) || null;
5448
} catch (error: any) {
5549
logger.error(
@@ -58,23 +52,23 @@ export function extendDynamoDBWithUserMethods(): void {
5852
);
5953
return null;
6054
}
61-
};
55+
}
6256

6357
// Get user by verification ID - uses the flattened verificationId index
64-
extendedDynamoDB.getUserByVerificationId = async (
58+
async getUserByVerificationId(
6559
verificationId: string
66-
): Promise<User | null> => {
60+
): Promise<User | null> {
6761
try {
6862
const command = new QueryCommand({
69-
TableName: process.env.USERS_TABLE_NAME || "users",
63+
TableName: this.tableName,
7064
IndexName: "verificationId-index",
7165
KeyConditionExpression: "verificationId = :verificationId",
7266
ExpressionAttributeValues: {
7367
":verificationId": verificationId,
7468
},
7569
});
7670

77-
const response = await dynamoDB.getClient().send(command);
71+
const response = await this.client.send(command);
7872

7973
if (!response.Items || response.Items.length === 0) {
8074
return null;
@@ -92,26 +86,24 @@ export function extendDynamoDBWithUserMethods(): void {
9286
);
9387
return null;
9488
}
95-
};
89+
}
9690

9791
// Get user by wallet address
98-
extendedDynamoDB.getUserByWalletAddress = async (
99-
walletAddress: string
100-
): Promise<User | null> => {
92+
async getUserByWalletAddress(walletAddress: string): Promise<User | null> {
10193
try {
10294
// Normalize wallet address (lowercase)
10395
const normalizedAddress = walletAddress.toLowerCase();
10496

10597
const command = new QueryCommand({
106-
TableName: process.env.USERS_TABLE_NAME || "users",
98+
TableName: this.tableName,
10799
IndexName: "walletAddress-index", // This assumes a GSI on walletAddress
108100
KeyConditionExpression: "walletAddress = :walletAddress",
109101
ExpressionAttributeValues: {
110102
":walletAddress": normalizedAddress,
111103
},
112104
});
113105

114-
const response = await dynamoDB.getClient().send(command);
106+
const response = await this.client.send(command);
115107

116108
if (response.Items && response.Items.length > 0) {
117109
return response.Items[0] as User;
@@ -125,25 +117,25 @@ export function extendDynamoDBWithUserMethods(): void {
125117
);
126118
return null;
127119
}
128-
};
120+
}
129121

130122
// Get all users
131-
extendedDynamoDB.getAllUsers = async (): Promise<User[]> => {
123+
async getAllUsers(): Promise<User[]> {
132124
try {
133125
const command = new ScanCommand({
134-
TableName: process.env.USERS_TABLE_NAME || "users",
126+
TableName: this.tableName,
135127
});
136128

137-
const response = await dynamoDB.getClient().send(command);
129+
const response = await this.client.send(command);
138130
return (response.Items as User[]) || [];
139131
} catch (error: any) {
140132
logger.error({ error: error.message }, "Error getting all users");
141133
return [];
142134
}
143-
};
135+
}
144136

145137
// Create a new user
146-
extendedDynamoDB.createUser = async (user: User): Promise<User | null> => {
138+
async createUser(user: User): Promise<User | null> {
147139
try {
148140
// Create a clean version of the user object for DynamoDB
149141
const dynamoUser: any = { ...user };
@@ -159,6 +151,12 @@ export function extendDynamoDBWithUserMethods(): void {
159151

160152
// Handle humanPassport fields - remove any null values to ensure proper indexing
161153
if (dynamoUser.humanPassport) {
154+
logger.debug(
155+
{
156+
dynamoUser: dynamoUser.humanPassport,
157+
},
158+
"Human passport in createUser"
159+
);
162160
const cleanHumanPassport: Record<string, any> = {};
163161

164162
// Only keep non-null values
@@ -186,26 +184,24 @@ export function extendDynamoDBWithUserMethods(): void {
186184
}
187185

188186
const command = new PutCommand({
189-
TableName: process.env.USERS_TABLE_NAME || "users",
187+
TableName: this.tableName,
190188
Item: dynamoUser,
191189
ConditionExpression: "attribute_not_exists(discordUserId)",
192190
});
193191

194-
logger.debug({ command }, "Creating user in repository");
195-
196-
await dynamoDB.getClient().send(command);
192+
await this.client.send(command);
197193
return user;
198194
} catch (error: any) {
199195
logger.error({ error: error.message, user }, "Error creating user");
200196
return null;
201197
}
202-
};
198+
}
203199

204200
// Update a user
205-
extendedDynamoDB.updateUser = async (
201+
async updateUser(
206202
discordUserId: string,
207203
updates: Partial<User>
208-
): Promise<boolean> => {
204+
): Promise<boolean> {
209205
try {
210206
// Build update and remove expressions
211207
const updateExpressions: string[] = [];
@@ -289,15 +285,15 @@ export function extendDynamoDBWithUserMethods(): void {
289285
}
290286

291287
const command = new UpdateCommand({
292-
TableName: process.env.USERS_TABLE_NAME || "users",
288+
TableName: this.tableName,
293289
Key: { discordUserId },
294290
UpdateExpression: updateExpression,
295291
ExpressionAttributeNames: expressionAttributeNames,
296292
ExpressionAttributeValues: expressionAttributeValues,
297293
ReturnValues: "UPDATED_NEW",
298294
});
299295

300-
await dynamoDB.getClient().send(command);
296+
await this.client.send(command);
301297
return true;
302298
} catch (error: any) {
303299
logger.error(
@@ -306,19 +302,17 @@ export function extendDynamoDBWithUserMethods(): void {
306302
);
307303
return false;
308304
}
309-
};
305+
}
310306

311307
// Delete a user
312-
extendedDynamoDB.deleteUser = async (
313-
discordUserId: string
314-
): Promise<boolean> => {
308+
async deleteUser(discordUserId: string): Promise<boolean> {
315309
try {
316310
const command = new DeleteCommand({
317-
TableName: process.env.USERS_TABLE_NAME || "users",
311+
TableName: this.tableName,
318312
Key: { discordUserId },
319313
});
320314

321-
await dynamoDB.getClient().send(command);
315+
await this.client.send(command);
322316
return true;
323317
} catch (error: any) {
324318
logger.error(
@@ -327,14 +321,8 @@ export function extendDynamoDBWithUserMethods(): void {
327321
);
328322
return false;
329323
}
330-
};
324+
}
331325
}
332326

333-
// Export the extended dynamoDB for use in other modules
334-
export { extendedDynamoDB };
335-
336-
// Export function to initialize - this will be called during app startup
337-
export function initializeUserRepository(): void {
338-
extendDynamoDBWithUserMethods();
339-
logger.info("User repository initialized");
340-
}
327+
// Export a singleton instance of the repository
328+
export const userRepository = new UserRepository();

0 commit comments

Comments
 (0)