Skip to content

Commit

Permalink
Refactor getGraphData into two functions
Browse files Browse the repository at this point in the history
  • Loading branch information
sofvanh committed Dec 4, 2024
1 parent def911a commit de8faf6
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 32 deletions.
57 changes: 33 additions & 24 deletions backend/src/db/operations/graphOperations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export async function getGraphs(): Promise<{ id: string; name: string }[]> {
return result.rows;
}

export async function getGraphData(graphId: string, userId: string): Promise<Graph> {
export async function getGraphData(graphId: string): Promise<Graph> {
const graphResult = await query('SELECT * FROM graphs WHERE id = $1', [graphId]);
if (graphResult.rows.length === 0) {
throw new Error('Graph not found');
Expand All @@ -26,7 +26,6 @@ export async function getGraphData(graphId: string, userId: string): Promise<Gra
const argumentsResult = await query('SELECT * FROM arguments WHERE graph_id = $1', [graphId]);
const edgesResult = await query('SELECT * FROM edges WHERE graph_id = $1', [graphId]);

// Get reaction counts for all arguments in the graph
const reactionCountsResult = await query(
`SELECT argument_id, type, COUNT(*) as count
FROM reactions
Expand All @@ -35,7 +34,6 @@ export async function getGraphData(graphId: string, userId: string): Promise<Gra
[graphId]
);

// Create a map of reaction counts by argument
const reactionCountsMap = new Map();
reactionCountsResult.rows.forEach((row: any) => {
if (!reactionCountsMap.has(row.argument_id)) {
Expand All @@ -44,25 +42,7 @@ export async function getGraphData(graphId: string, userId: string): Promise<Gra
reactionCountsMap.get(row.argument_id)[row.type] = parseInt(row.count);
});

// Get user reactions if userId is provided
let userReactionsMap = new Map();
if (userId) {
const userReactionsResult = await query(
`SELECT argument_id, type
FROM reactions
WHERE user_id = $1 AND argument_id IN (SELECT id FROM arguments WHERE graph_id = $2)`,
[userId, graphId]
);
userReactionsResult.rows.forEach((row: any) => {
if (!userReactionsMap.has(row.argument_id)) {
userReactionsMap.set(row.argument_id, {});
}
userReactionsMap.get(row.argument_id)[row.type] = true;
});
}

// Get argument scores
// TODO: Make sure this is efficient
// TODO Just change getArgumentScores so that it already returns a map... We don't even need this ArgumentScore type (or we can change it so that Argument uses it directly)
const argumentScores = await getArgumentScores(graphId);
const scoresMap = new Map(
argumentScores.map(score => [
Expand All @@ -73,16 +53,16 @@ export async function getGraphData(graphId: string, userId: string): Promise<Gra
clarity: score.clarityScore
}
])
);
)

// TODO This is terrible, create types for db results already...
const args: Argument[] = argumentsResult.rows.map((row: { id: string; graph_id: string; statement: string; embedding: number[], author_id: string }) => ({
id: row.id,
graphId: row.graph_id,
statement: row.statement,
embedding: row.embedding,
authorId: row.author_id,
reactionCounts: reactionCountsMap.get(row.id) || { agree: 0, disagree: 0, unclear: 0 },
userReaction: userReactionsMap.get(row.id),
score: scoresMap.get(row.id)
}));

Expand All @@ -99,4 +79,33 @@ export async function getGraphData(graphId: string, userId: string): Promise<Gra
arguments: args,
edges: links
} as Graph;
}

export async function getGraphDataWithUserReactions(graphId: string, userId: string): Promise<Graph> {
const graphData = await getGraphData(graphId);
let userReactionsMap = new Map();
const userReactionsResult = await query(
`SELECT argument_id, type
FROM reactions
WHERE user_id = $1 AND argument_id IN (SELECT id FROM arguments WHERE graph_id = $2)`,
[userId, graphId]
);
userReactionsResult.rows.forEach((row: any) => {
if (!userReactionsMap.has(row.argument_id)) {
userReactionsMap.set(row.argument_id, {});
}
userReactionsMap.get(row.argument_id)[row.type] = true;
});

const argsWithUserReactions = graphData.arguments.map(arg => ({
...arg,
userReaction: userReactionsMap.get(arg.id) || {} // TODO I also want typing of the user reaction
}));

return {
id: graphId,
name: graphData.name,
arguments: argsWithUserReactions,
edges: graphData.edges
} as Graph;
}
6 changes: 3 additions & 3 deletions backend/src/websocket/argumentHandler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Socket } from 'socket.io';
import { addArgument } from '../db/operations/argumentOperations';
import { getGraphData } from '../db/operations/graphOperations';
import { getGraphDataWithUserReactions } from '../db/operations/graphOperations';
import { updateGraphEdges } from '../db/operations/edgeOperations';
import { embedText, generateTopKSimilarEdges } from '../embeddingHandler';

Expand All @@ -17,7 +17,7 @@ export const handleAddArgument = async (
}

try {
const graph = await getGraphData(graphId, socket.data.user.id);
const graph = await getGraphDataWithUserReactions(graphId, socket.data.user.id);
if (!graph) {
console.log(`Failed to add argument: Graph not found. Graph ID: ${graphId}, Statement: ${statement}, User ID: ${socket.data.user.id}, Socket ID: ${socket.id}`);
callback?.({ success: false, error: 'Graph not found' });
Expand All @@ -32,7 +32,7 @@ export const handleAddArgument = async (
const newEdges = generateTopKSimilarEdges(graph);
await updateGraphEdges(graphId, newEdges);

const updatedGraph = await getGraphData(graphId, socket.data.user.id);
const updatedGraph = await getGraphDataWithUserReactions(graphId, socket.data.user.id); // TODO This is also broken (shouldn't be using author user id for updating everyone)
io.to(graphId).emit('graph update', updatedGraph);
callback?.({ success: true, argument: newArgument });
} catch (error) {
Expand Down
4 changes: 2 additions & 2 deletions backend/src/websocket/graphHandler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Socket } from 'socket.io';
import { createGraph, getGraphs, getGraphData } from '../db/operations/graphOperations';
import { createGraph, getGraphs, getGraphDataWithUserReactions } from '../db/operations/graphOperations';

export const handleCreateGraph = async (socket: Socket, name: string, callback?: Function) => {
if (!socket.data.user) {
Expand All @@ -19,7 +19,7 @@ export const handleCreateGraph = async (socket: Socket, name: string, callback?:
export const handleJoinGraph = async (socket: Socket, graphId: string) => {
console.log(`Socket ${socket.id} joining graph ${graphId}, user: ${socket.data.user?.id}`);
socket.join(graphId);
const graph = await getGraphData(graphId, socket.data.user?.id);
const graph = await getGraphDataWithUserReactions(graphId, socket.data.user?.id);
socket.emit('graph data', graph);
};

Expand Down
6 changes: 3 additions & 3 deletions backend/src/websocket/reactionHandler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Socket } from 'socket.io';
import { addReaction, removeReaction } from '../db/operations/reactionOperations';
import { getGraphData } from '../db/operations/graphOperations';
import { getGraphDataWithUserReactions } from '../db/operations/graphOperations';
import { query } from '../db/db';


Expand All @@ -21,7 +21,7 @@ export const handleAddReaction = async (
try {
const id = await addReaction(socket.data.user.id, argumentId, type);
const graphId = (await query('SELECT graph_id FROM arguments WHERE id = $1', [argumentId])).rows[0].graph_id;
const updatedGraph = await getGraphData(graphId, socket.data.user.id);
const updatedGraph = await getGraphDataWithUserReactions(graphId, socket.data.user.id);
io.to(graphId).emit('graph update', updatedGraph); // TODO This breaks, because we're sending the current user's score to all users in the graph!
callback?.({ success: true, id });
} catch (error) {
Expand All @@ -45,7 +45,7 @@ export const handleRemoveReaction = async (
try {
await removeReaction(socket.data.user.id, argumentId, type);
const graphId = (await query('SELECT graph_id FROM arguments WHERE id = $1', [argumentId])).rows[0].graph_id;
const updatedGraph = await getGraphData(graphId, socket.data.user.id);
const updatedGraph = await getGraphDataWithUserReactions(graphId, socket.data.user.id);
io.to(graphId).emit('graph update', updatedGraph);
callback?.({ success: true });
} catch (error) {
Expand Down

0 comments on commit de8faf6

Please sign in to comment.