Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions packages/server/src/routes/rooms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { db } from "../db/index";
import { chatRooms, createRoomSchema, nearbyRoomsQuerySchema, users } from "@intellicircle/shared";
import { reverseGeocode } from "../services/geocoding";
import { createSuccessResponse, createErrorResponse } from "../utils/response";
import { sql, eq, desc } from "drizzle-orm";
import { sql, eq, desc, and, lt } from "drizzle-orm";
import { messages } from "@intellicircle/shared";
import { trackTiming } from "../utils/metrics";

Expand All @@ -29,7 +29,7 @@ export async function roomRoutes(app: FastifyInstance) {
name,
description,
interests,
location: { x: lng, y: lat } as any,
location: locationPoint, // <-- FIXED: Was incorrectly bypassing locationPoint
// We're dynamically adding a region string column next migration to hold OpenCage result.
// Currently just making sure the spatial bounds store.
}).returning();
Expand Down Expand Up @@ -128,6 +128,11 @@ export async function roomRoutes(app: FastifyInstance) {
const roomId = parseInt(_id, 10);
if (isNaN(roomId)) return reply.status(400).send(createErrorResponse("Invalid Room ID"));

// FIXED: Extract optional cursor (message ID) for pagination
const query = request.query as { cursor?: string };
const cursor = query.cursor ? parseInt(query.cursor, 10) : undefined;
const PAGE_LIMIT = 50;

try {
// Fetch Room Details
const [roomDef] = await db.select({
Expand All @@ -139,7 +144,12 @@ export async function roomRoutes(app: FastifyInstance) {

if (!roomDef) return reply.status(404).send(createErrorResponse("Room not found"));

// Fetch Top 50 latest messages, tracked via Datadog StatsD
// FIXED: Dynamic condition to fetch messages older than the cursor if provided
const historyCondition = cursor
? and(eq(messages.roomId, roomId), lt(messages.id, cursor))
: eq(messages.roomId, roomId);

// Fetch Top latest messages, tracked via Datadog StatsD
const history = await trackTiming("db_query_time", async () => {
return db.select({
id: messages.id,
Expand All @@ -151,19 +161,23 @@ export async function roomRoutes(app: FastifyInstance) {
})
.from(messages)
.leftJoin(users, eq(messages.userId, users.id))
.where(eq(messages.roomId, roomId))
.where(historyCondition)
.orderBy(desc(messages.createdAt))
.limit(50);
.limit(PAGE_LIMIT);
}, ["query:room_history_hydration"]);

// FIXED: Determine the next cursor (the ID of the oldest message in this batch)
const nextCursor = history.length === PAGE_LIMIT ? history[history.length - 1].id : null;

// Reverse to chronological order for React Feed
return reply.send(createSuccessResponse({
room: roomDef,
messages: history.reverse()
messages: history.reverse(),
nextCursor // Send cursor to frontend
}));
} catch (error) {
app.log.error(error);
return reply.status(500).send(createErrorResponse("Failed to fetch room history"));
}
});
}
}