Skip to content

Submission fixes, problem creation, refreshing towards next problem#102

Open
devsheth05 wants to merge 9 commits intomainfrom
devS
Open

Submission fixes, problem creation, refreshing towards next problem#102
devsheth05 wants to merge 9 commits intomainfrom
devS

Conversation

@devsheth05
Copy link
Contributor

No description provided.

@vercel
Copy link

vercel bot commented Feb 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
bsg Ready Ready Preview, Comment Feb 16, 2026 10:20pm

Request Review

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request implements a comprehensive set of fixes and features for submission handling, problem creation, and automatic progression to the next problem. The changes span across the RTC service, central service, and browser extension to create an end-to-end workflow for competitive programming sessions.

Changes:

  • Refactored chat manager in RTC service to use map-based storage (string keys) instead of pointer-based maps for improved lookup performance
  • Changed Room and Round IDs from UUID to string type throughout the system to support custom room codes
  • Disabled Kafka integration (commented out) and added direct HTTP submission endpoint
  • Implemented LeetCode submission detection in browser extension with automatic navigation to next problem
  • Added seed generation script for populating problem database from LeetCode API
  • Disabled authentication middleware for local development testing

Reviewed changes

Copilot reviewed 24 out of 31 changed files in this pull request and generated 32 comments.

Show a summary per file
File Description
rtc-service/servicesmanager/service.go Added lazy room creation and changed user iteration to handle string-keyed maps
rtc-service/chatmanager/user.go Changed UserList from map[*User]bool to map[string]*User
rtc-service/chatmanager/room.go Refactored to use handle-based user lookups instead of pointer iteration
rtc-service/chatmanager/manager.go Changed RoomsList to map[string]*Room for string-based room lookups
central-service/services/submission-queue.go Disabled Kafka producer/consumer with extensive commented code
central-service/services/round.go Changed RoomID from UUID to string, wrapped problem association in transaction
central-service/services/room.go Added generateRoomCode function, new ProcessSubmissionSuccess method
central-service/services/problem.go Added slug field support, simplified problem query logic
central-service/models/room.go Changed Room.ID from uuid.UUID to string
central-service/models/round.go Changed Round.RoomID from uuid.UUID to string
central-service/main.go Disabled authentication middleware, added fake token for testing
central-service/controllers/submission.go New submission controller for handling problem submissions
docker-compose.yml Added rtc-service dependency, seed SQL mount, changed adminer port
bsg-frontend/extension/contentScript.js Implemented LeetCode submission detection with DOM observation
bsg-frontend/extension/background.js Added submission handling with auto-navigation and state persistence
bsg-frontend/extension/manifest.json Added notifications permission and overwriteFetch.js
bsg-frontend/extension/overwriteFetch.js New file intercepting LeetCode API responses
bsg-frontend/apps/extension/pages/room-choice.tsx Backend integration for room/round creation
bsg-frontend/apps/extension/pages/_app.tsx Complete room state management and chat UI
central-service/scripts/generate_seeds.py New script for fetching and seeding LeetCode problems

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 107 to 117
//e.Use(userController.ValidateUserRequest) //temp disabled for testing
e.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
// Create a fake auth token for testing
fakeToken := &auth.Token{
UID: "test-user-123",
}
c.Set("authToken", fakeToken)
return next(c)
}
})
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The authentication middleware has been disabled and replaced with a fake token for testing purposes. This creates a critical security vulnerability as any request will be processed with a fake "test-user-123" UID, bypassing actual authentication checks. This should be re-enabled before merging to any environment that isn't strictly local development.

Copilot uses AI. Check for mistakes.
Comment on lines 29 to 239
@@ -122,32 +136,32 @@ func (egressQueueService *SubmissionEgressQueueService) ProcessSubmissionData(ra
}

var scoreToAdd uint = 0
var problem models.Problem
var lbUserID uint = 0

if payload.Verdict == constants.SUBMISSION_STATUS_ACCEPTED {
egressQueueService.db.First(&problem, submission.ProblemID)

if submission.SubmissionOwnerType == "round_submissions" {
var roundSubmission models.RoundSubmission
err := egressQueueService.db.Preload("Round").Preload("RoundParticipant").First(&roundSubmission, submission.SubmissionOwnerID).Error
if err == nil {
scoreToAdd, _ = egressQueueService.roundService.DetermineScoreDeltaForUserBySubmission(
&problem,
&roundSubmission.RoundParticipant,
&roundSubmission.Round,
)
var user models.User
if err := egressQueueService.db.Where("auth_id = ?", roundSubmission.RoundParticipant.ParticipantAuthID).First(&user).Error; err == nil {
lbUserID = user.ID
}
}
} else {
// honestly no clue when this would get hit
scoreToAdd = egressQueueService.roundService.problemAccessor.GetProblemAccessor().DetermineScoreForProblem(&problem)
lbUserID = uint(submission.SubmissionOwnerID)
}
var problem models.Problem
var lbUserID uint = 0

if payload.Verdict == constants.SUBMISSION_STATUS_ACCEPTED {
egressQueueService.db.First(&problem, submission.ProblemID)

if submission.SubmissionOwnerType == "round_submissions" {
var roundSubmission models.RoundSubmission
err := egressQueueService.db.Preload("Round").Preload("RoundParticipant").First(&roundSubmission, submission.SubmissionOwnerID).Error
if err == nil {
scoreToAdd, _ = egressQueueService.roundService.DetermineScoreDeltaForUserBySubmission(
&problem,
&roundSubmission.RoundParticipant,
&roundSubmission.Round,
)

var user models.User
if err := egressQueueService.db.Where("auth_id = ?", roundSubmission.RoundParticipant.ParticipantAuthID).First(&user).Error; err == nil {
lbUserID = user.ID
}
}
} else {
// honestly no clue when this would get hit
scoreToAdd = egressQueueService.roundService.problemAccessor.GetProblemAccessor().DetermineScoreForProblem(&problem)
lbUserID = uint(submission.SubmissionOwnerID)
}

if lbUserID != 0 {
var existingAcceptedCount int64
@@ -156,15 +170,15 @@ func (egressQueueService *SubmissionEgressQueueService) ProcessSubmissionData(ra
Joins("LEFT JOIN round_submissions rs ON submissions.submission_owner_id = rs.id AND submissions.submission_owner_type = 'round_submissions'").
Joins("LEFT JOIN round_participants rp ON rs.round_participant_id = rp.id").
Joins("LEFT JOIN users u ON (u.id = submissions.submission_owner_id AND submissions.submission_owner_type = 'user') OR (u.auth_id = rp.participant_auth_id)").
Where("submissions.problem_id = ? AND submissions.verdict = ? AND u.id = ? AND submissions.id <> ?",
Where("submissions.problem_id = ? AND submissions.verdict = ? AND u.id = ? AND submissions.id <> ?",
submission.ProblemID, constants.SUBMISSION_STATUS_ACCEPTED, lbUserID, submission.ID).
Count(&existingAcceptedCount).Error

if err == nil && existingAcceptedCount > 0 {
scoreToAdd = 0
}
}
}
}

// update verdict in database
result = egressQueueService.db.Model(&submission).Update("verdict", payload.Verdict)
@@ -195,28 +209,31 @@ func (egressQueueService *SubmissionEgressQueueService) ProcessSubmissionData(ra
}

func (egressQueueService *SubmissionEgressQueueService) ListenForSubmissionData() {
run := true
msg_count := 0
for run {
ev := egressQueueService.consumer.Poll(100)
switch e := ev.(type) {
case *kafka.Message:
msg_count += 1
if msg_count % MIN_COMMIT_COUNT == 0 {
egressQueueService.consumer.Commit()
//Kafka consumer loop is disabled
/*
run := true
msg_count := 0
for run {
ev := egressQueueService.consumer.Poll(100)
switch e := ev.(type) {
case *kafka.Message:
msg_count += 1
if msg_count % MIN_COMMIT_COUNT == 0 {
egressQueueService.consumer.Commit()
}
err := egressQueueService.ProcessSubmissionData(e.Value)
if err != nil {
fmt.Printf("Error processing message at Kafka Egress Queue: %v\n", err)
}
case kafka.Error:
fmt.Printf("Error detected at Kafka Egress Consumer: %v\n", e)
run = false
default:
if e != nil {
fmt.Printf("Unexpected message at Kafka Egress Consumer: %v\n", e)
}
}
}
err := egressQueueService.ProcessSubmissionData(e.Value)
if err != nil {
fmt.Printf("Error processing message at Kafka Egress Queue: %v\n", err)
}
case kafka.Error:
fmt.Printf("Error detected at Kafka Egress Consumer: %v\n", e)
run = false
default:
if e != nil {
fmt.Printf("Unexpected message at Kafka Egress Consumer: %v\n", e)
}
}
}
egressQueueService.consumer.Close()
} No newline at end of file
egressQueueService.consumer.Close()
*/
}
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Large blocks of commented-out Kafka code should be removed rather than commented out. This reduces code clutter and makes the codebase easier to maintain. If this code needs to be preserved for future reference, it should be documented in a separate design document or git history can be used to retrieve it.

Copilot uses AI. Check for mistakes.
Comment on lines 167 to 168
console.warn("⚠️ Firebase not initialized or user not logged in. Using dummy token for local development.");
return "dummy-token-123";
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling when auth.currentUser is null defaults to using a "dummy-token-123" (line 168). In production environments, this should fail gracefully rather than proceeding with a fake token. Consider throwing an error or showing a login prompt instead of silently using a dummy token.

Suggested change
console.warn("⚠️ Firebase not initialized or user not logged in. Using dummy token for local development.");
return "dummy-token-123";
console.warn("⚠️ Firebase not initialized or user not logged in. Cannot obtain auth token.");
throw new Error("User is not authenticated or Firebase is not initialized.");

Copilot uses AI. Check for mistakes.

// List of all chat users connected to RTC service.
type UserList map[*User]bool
// List of all chat users connected to RTC service.
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The duplicate comment on line 4 "List of all chat users connected to RTC service." should be removed. It's redundant with the comment on line 3.

Suggested change
// List of all chat users connected to RTC service.

Copilot uses AI. Check for mistakes.
Comment on lines +35 to +38
// Update or add user to the room by their handle
r.Users[user.Handle] = user

logging.Info("Added: ", user.Handle, " to room: ", r.RoomID)
logging.Info("Added/Updated: ", user.Handle, " in room: ", r.RoomID)
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The AddUser method now silently updates existing users instead of checking for duplicates and logging an error (lines 35-38). While this is a valid design choice, it changes the semantics - previously adding an existing user was treated as an error condition. Consider documenting this behavior change or restoring the duplicate check with a warning log to help with debugging.

Copilot uses AI. Check for mistakes.
const containerRef = useRef<HTMLDivElement>(null)

// Initialize WebSocket Hook
const { messages, isConnected, joinRoom, sendChatMessage, addMessage } = useChatSocket(userProfile?.id);
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable isConnected.

Suggested change
const { messages, isConnected, joinRoom, sendChatMessage, addMessage } = useChatSocket(userProfile?.id);
const { messages, joinRoom, sendChatMessage, addMessage } = useChatSocket(userProfile?.id);

Copilot uses AI. Check for mistakes.
Comment on lines 457 to 458
const participants: Participant[] = currentRoom.options?.participants || []

Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable participants.

Suggested change
const participants: Participant[] = currentRoom.options?.participants || []

Copilot uses AI. Check for mistakes.
Comment on lines +222 to +228
// Track if we've already processed the current success state
let isCurrentlySuccess = false;
let lastSubmitTime = 0;

// Listen for clicks on the Submit button
document.addEventListener('click', (e) => {
const target = e.target;
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable isCurrentlySuccess.

Suggested change
// Track if we've already processed the current success state
let isCurrentlySuccess = false;
let lastSubmitTime = 0;
// Listen for clicks on the Submit button
document.addEventListener('click', (e) => {
const target = e.target;
// Track if we've already processed the current success state
let lastSubmitTime = 0;
// Listen for clicks on the Submit button
document.addEventListener('click', (e) => {
const target = e.target;

Copilot uses AI. Check for mistakes.
}

// Navigate to the first problem
if (shouldNavigate && firstProblemSlug) {
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This use of variable 'shouldNavigate' always evaluates to true.

Copilot uses AI. Check for mistakes.
import requests
import os
import csv
import io
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import of 'io' is not used.

Suggested change
import io

Copilot uses AI. Check for mistakes.
@Eskan0r
Copy link
Contributor

Eskan0r commented Feb 10, 2026

🔴 CRITICAL ISSUES IN PR #102

  1. Room Code Lookup Not In RTC Service
    Files: central-service/services/room.go, rtc-service/chatmanager/manager.go

The PR adds FindRoomByCode() in the central service to support 5-character room codes, but the RTC service still uses the old room lookup logic. When the extension sends messages with a room code instead of UUID, RTC won't find the room properly.

Impact: Room messages won't route correctly between clients.

  1. Missing Problem Model Fields
    File: central-service/models/room.go

Room model now has RoomCode field, but the Problem model is missing Slug and Difficulty fields that are being used in:

problem.go: FindProblemBySlug() function
Frontend: Displaying problem difficulty
Extension: Filtering by difficulty
Impact: Problem queries will fail when trying to access slug and difficulty.

  1. Firebase Token Not Extracted from Authorization Header
    Files: bsg-frontend/apps/extension/pages/room-choice.tsx, central-service/controllers/room.go

The backend changed from extracting auth via Firebase to expecting userAuthID as a string in context:

// OLD: c.Get("authToken").(*auth.Token).UID
// NEW: c.Get("userAuthID").(string)
But the middleware that sets userAuthID in context is not shown in this PR. The middleware is missing or not updated to extract the token from Authorization header properly.

Impact: All room operations will crash with type assertion panic.

  1. Room/Round Signature Mismatch
    File: central-service/services/room.go (line 101-107)

CreateRound() signature changed from:

CreateRound(params *RoundCreationParameters, roomID string)

to:

CreateRound(params *RoundCreationParameters, roomID uuid.UUID)
But in the same file (line 349), it's called with the result of FindRoomByCode() which returns a UUID. However, there's implicit UUID->string->UUID conversion that won't compile:

parsedRoomID, err := uuid.Parse(roomID) // roomID is a string
if err != nil {
// Try to find by code...
}
// Then later: newRound, err := controller.roomService.CreateRound(&roundCreationParams, parsedRoomID)
The UUID is being passed correctly, but the service method signature expects it. This WILL fail in the data layer.

  1. ChatManager Room Storage Key Type Mismatch
    File: rtc-service/chatmanager/manager.go (line 65-69)

Changed from storing rooms as:

sm.Rooms[room] = true // room is *Room pointer (wrong key type!)

to:

sm.Rooms[room.RoomID] = room // room.RoomID is string
But Rooms map is defined as map[*Room]bool and now trying to store with string key. Type mismatch - won't compile.

  1. Kafka Disabled But Still Called
    File: central-service/services/submission-queue.go

All Kafka code is commented out with // Kafka produce disabled, but main.go still calls:

ingressQueue.MessageDeliveryHandler() // Spawned in goroutine
This will start an empty goroutine that does nothing. Submissions won't be queued for worker processing.

  1. Extension Backend Sync Missing Auth Middleware Hookup
    File: bsg-frontend/extension/background.js

New SUBMISSION_SUCCESS message handler tries to POST to /api/submissions/ with Authorization header, but there's no guarantee the middleware to extract this token exists in the central service.

Impact: Submission reporting endpoint will fail auth checks.

Summary
This PR has 7 critical failures that will prevent it from functioning:

3 compilation errors (type mismatches)
2 missing/incomplete middleware implementations
2 logic flow breaks (Kafka disabled, RTC mismatch)
Recommend: DO NOT MERGE without fixing auth middleware, model fields, and RTC service integration.

ts from copilot, 10k changes are a lot, if you can resolve all of these, and then show me it runs and succeeds, then show me how to run it on my local, then i'll merge

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

Comments