Conversation
… for /events to get the backend running
WalkthroughRemoved Assignment exports/endpoints from the backend, expanded Event payload with scheduling fields, introduced TimeSlot and migrated time fields from string to TimeSlot, added React Query provider, wired task creation to a mutation with query invalidation, and updated frontend services and components to sync tasks/events. Changes
Sequence Diagram(s)sequenceDiagram
participant Modal as TimeSelectionModal
participant Hook as useCreateTask
participant QC as QueryClient
participant API as Backend /api/scheduler/tasks
participant DB as Database
Modal->>Hook: mutate(TaskPayload)
Hook->>API: POST /api/scheduler/tasks
API->>DB: persist Task
DB-->>API: created
API-->>Hook: success response
Hook->>QC: invalidate "tasks" query (onSettled)
QC->>Hook: trigger refetch
Hook-->>Modal: onSuccess callback
Modal->>Modal: reset state, close modal, call onTimeConfirmed
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
rise-dc-app/src/shared/types/index.ts (1)
3-3: Unused import that shadows the localEventinterface.The
Eventimport from@mui/icons-materialis unused and creates a naming conflict with the localEventinterface defined at line 101. Remove this import.-import { Event } from "@mui/icons-material";rise-dc-app/src/scheduling_components/TimeSelectionModal.tsx (1)
204-208: Redundant double.padStart(2, "0")call.The minute value has
.padStart(2, "0")called twice. Remove the duplicate.value={time.minute .toString() - .padStart(2, "0") - .toString() .padStart(2, "0")}
🧹 Nitpick comments (6)
rise-dc-app/src/services/service.ts (1)
11-11: Consider using environment variables for deployment flexibility.The empty string works in dev via the Vite proxy, but the TODO suggests future deployment needs. Using
import.meta.env.VITE_API_URL || ""would allow environment-based configuration without code changes.-const API_URL = ""; // TODO: change this to be actual backend URL once deployed +const API_URL = import.meta.env.VITE_API_URL || "";rise-dc-app/src/shared/types/index.ts (1)
101-103: Incomplete Event interface with typo in comment.The TODO comment has a typo ("comrpising" → "comprising") and the comment appears to be cut off. Consider completing the interface or the TODO description.
export interface Event extends Task { - steps: string[]; // TODO: turn this into it's own mini type, likely comrpising of + steps: string[]; // TODO: turn this into its own mini type, likely comprising of step details }rise-dc-app/src/scheduling_components/PlanYourDayButton.tsx (2)
11-15: Consider using the shared TimeSlot type.
EventData.startTimeandEventData.endTimeduplicate theTimeSlotstructure. Consider importing and reusingTimeSlotfor consistency.+import { Task, TimeSlot } from "../shared/types"; -import { Task } from "../shared/types"; type EventData = { name: string; - startTime: { hour: number; minute: number; period: "AM" | "PM" }; - endTime: { hour: number; minute: number; period: "AM" | "PM" }; + startTime: TimeSlot; + endTime: TimeSlot; };
33-49: Duplicate sorting logic should be extracted to a helper function.The 12-hour to 24-hour time conversion and sorting logic is duplicated in the
useEffect(lines 33-49) andaddEvent(lines 78-93). Extract to a reusable helper.// Add helper function before the component const to24Hour = (time: { hour: number; period: "AM" | "PM" }) => { if (time.period === "PM" && time.hour !== 12) return time.hour + 12; if (time.period === "AM" && time.hour === 12) return 0; return time.hour; }; const sortByStartTime = (events: EventData[]) => [...events].sort((a, b) => { const aHour24 = to24Hour(a.startTime); const bHour24 = to24Hour(b.startTime); if (aHour24 !== bHour24) return aHour24 - bHour24; return a.startTime.minute - b.startTime.minute; });Also applies to: 78-93
rise-dc-app/src/scheduling_components/TimeSelectionModal.tsx (1)
126-129: Move query invalidation toonSuccessinstead ofonSettled.
onSettledruns after both success and error. Invalidating the cache on error triggers an unnecessary refetch when the task wasn't actually created.onSuccess: (data) => { console.log("Task created successfully:", data); + // Refresh the tasks list + queryClient.invalidateQueries({ queryKey: ["tasks"] }); + // Reset and close the modal onTimeConfirmed?.(startTime, endTime); setCurrentStep("START_TIME"); onClose(); }, onError: (error) => { console.error("Failed to create task:", error); alert("Failed to create task. Please try again."); }, - onSettled: () => { - // Refresh the tasks list - queryClient.invalidateQueries({ queryKey: ["tasks"] }); - }, });backend/src/routes/scheduler.ts (1)
127-133: Consider removingtaskAssignmentIdfrom the Feedback interface if deprecated.Hardcoding
taskAssignmentId: ""works as a stopgap after removing Assignment references, but theFeedbackinterface still requires this field. If assignments are being phased out, consider updating the interface to make this field optional or remove it entirely to avoid confusion and maintain type consistency.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
backend/src/cosmos.ts(0 hunks)backend/src/routes/scheduler.ts(3 hunks)rise-dc-app/src/main.tsx(1 hunks)rise-dc-app/src/scheduling_components/PlanYourDayButton.tsx(3 hunks)rise-dc-app/src/scheduling_components/TimeSelectionModal.tsx(8 hunks)rise-dc-app/src/services/service.ts(1 hunks)rise-dc-app/src/services/taskService.ts(1 hunks)rise-dc-app/src/shared/types/index.ts(1 hunks)rise-dc-app/vite.config.js(1 hunks)
💤 Files with no reviewable changes (1)
- backend/src/cosmos.ts
🧰 Additional context used
🧬 Code graph analysis (5)
rise-dc-app/src/main.tsx (2)
rise-dc-app/src/shared/constants/query.ts (1)
queryClient(4-4)rise-dc-app/src/shared/state/FavoritesContext.tsx (1)
FavoritesProvider(30-87)
rise-dc-app/src/services/taskService.ts (3)
rise-dc-app/src/shared/types/index.ts (3)
Image(45-49)TimeSlot(83-87)Task(89-99)rise-dc-app/src/scheduling_components/quiet_hobbies/types.ts (1)
TaskCategory(33-39)rise-dc-app/src/services/service.ts (3)
postJSON(31-37)getJSON(26-29)delJSON(39-42)
rise-dc-app/src/scheduling_components/TimeSelectionModal.tsx (4)
rise-dc-app/src/shared/constants/query.ts (1)
queryClient(4-4)rise-dc-app/src/hooks/useTask.ts (1)
useCreateTask(11-15)rise-dc-app/src/services/taskService.ts (1)
TaskPayload(5-13)rise-dc-app/src/scheduling_components/quiet_hobbies/types.ts (1)
TaskCategory(33-39)
rise-dc-app/src/scheduling_components/PlanYourDayButton.tsx (2)
rise-dc-app/src/hooks/useTask.ts (1)
useAllTasks(4-9)rise-dc-app/src/scheduling_components/quiet_hobbies/types.ts (1)
Task(26-31)
backend/src/routes/scheduler.ts (2)
rise-dc-app/src/shared/types/index.ts (2)
Event(101-103)Feedback(114-119)rise-dc-app/src/scheduling_components/quiet_hobbies/types.ts (1)
TaskCategory(33-39)
🔇 Additional comments (8)
rise-dc-app/vite.config.js (1)
12-12: LGTM!The proxy target change to
localhost:3000aligns with the backend server configuration and works correctly with the emptyAPI_URLinservice.ts.rise-dc-app/src/main.tsx (1)
9-16: LGTM!Correct React Query integration with proper provider hierarchy.
QueryClientProviderwrappingFavoritesProviderensures query functionality is available throughout the app.rise-dc-app/src/shared/types/index.ts (1)
83-98: LGTM on the TimeSlot type definition.The
TimeSlotstructure and its integration into theTaskinterface is well-designed, properly representing 12-hour time format with AM/PM periods.rise-dc-app/src/services/taskService.ts (1)
15-30: LGTM on the API endpoint updates.The task service endpoints have been correctly updated to use the
/api/scheduler/tasksnamespace, aligning with the backend route changes.rise-dc-app/src/scheduling_components/PlanYourDayButton.tsx (1)
24-52: LGTM on the task synchronization logic.The
useEffectcorrectly synchronizes remote tasks to local state with proper dependency tracking and success-gate check.rise-dc-app/src/scheduling_components/TimeSelectionModal.tsx (1)
277-296: LGTM on the loading state and button behavior.Good UX to disable the button and show "Creating Task..." during the mutation pending state.
backend/src/routes/scheduler.ts (2)
92-99: LGTM on the Event payload expansion.The destructuring and defaults for
userId,steps, and other new fields align with the updated Event model. The rename fromtaskstostepsmatches the interface definition in shared types.
15-16: > Likely an incorrect or invalid review comment.
| const handleFinish = () => { | ||
| onTimeConfirmed?.(startTime, endTime); | ||
| setCurrentStep("START_TIME"); | ||
| onClose(); | ||
| // TODO: Get specific userId, icon, and category | ||
| const taskPayload: TaskPayload = { | ||
| userId: "", | ||
| name: selectedEvent, | ||
| icon: "", | ||
| startTime: startTime, | ||
| endTime: endTime, | ||
| category: TaskCategory.Misc, | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's understand the repository structure
git ls-files | head -20Repository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 228
🏁 Script executed:
# Look for backend directory structure
fd -type d -name backend | head -10Repository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 256
🏁 Script executed:
# Search for Task/Event model definitions and validation
rg -n "userId.*required|userId.*validation|interface Task|type Task" --type ts --type js -A 3Repository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 1927
🏁 Script executed:
# Check for scheduler route handlers
fd -type f -name "*scheduler*" | grep -E "\.(ts|js)$"Repository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 256
🏁 Script executed:
# Get full TaskPayload definition and surrounding context
cat -n rise-dc-app/src/services/taskService.ts | head -50Repository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 1209
🏁 Script executed:
# Search for createTask mutation and how it's used
rg -n "createTask|useCreateTask" rise-dc-app/src --type ts --type tsx -B 2 -A 5Repository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 113
🏁 Script executed:
# Look for any validation logic in task-related files
rg -n "userId.*empty|validate|required" rise-dc-app/src -B 2 -A 2Repository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 1997
🏁 Script executed:
# Check if there's a backend directory anywhere
find . -maxdepth 3 -type d -name "*backend*" -o -name "*server*" -o -name "*api*" 2>/dev/null | grep -v node_modulesRepository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 119
🏁 Script executed:
# Explore backend structure
ls -la backend/Repository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 578
🏁 Script executed:
# Look for Task model/schema and validation
fd . backend -type f \( -name "*task*" -o -name "*model*" -o -name "*schema*" \) | head -20Repository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 256
🏁 Script executed:
# Search for the /api/scheduler/tasks endpoint handler
rg -n "scheduler/tasks|TaskPayload|userId" backend/ -B 2 -A 5Repository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 2905
🏁 Script executed:
# Check for validation middleware or rules
rg -n "validate|required|empty" backend/ -i | head -30Repository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 68
🏁 Script executed:
# Check how tasks are retrieved/filtered
rg -n "listTasks|GET.*tasks|userId" backend/src/routes/scheduler.ts -B 2 -A 5Repository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 916
Empty userId and icon will be persisted without validation, breaking task ownership.
The backend's POST /tasks endpoint (line 28, 30 in backend/src/routes/scheduler.ts) accepts and stores userId and icon without validation. Tasks created with empty strings will lack user association, making it impossible to filter tasks by user. This breaks core functionality.
Either retrieve the actual userId before creating the task, add backend validation to reject empty values, or handle the error gracefully when these are unavailable.
| @@ -1,31 +1,31 @@ | |||
| import { TaskCategory } from "../scheduling_components/quiet_hobbies/types"; | |||
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify TaskCategory definitions and usages across the codebase
echo "=== TaskCategory in quiet_hobbies/types.ts ==="
find rise-dc-app -name "quiet_hobbies" -type d 2>/dev/null | head -1
rg -n "TaskCategory" rise-dc-app/src/scheduling_components/quiet_hobbies/types.ts 2>/dev/null || echo "File not found or no matches"
echo -e "\n=== TaskCategory in shared/types ==="
find rise-dc-app/src/shared/types -type f -name "*.ts" 2>/dev/null | head -5
rg -n "TaskCategory" rise-dc-app/src/shared/types/ 2>/dev/null || echo "No matches in shared/types"
echo -e "\n=== All TaskCategory imports ==="
rg -n "import.*TaskCategory" rise-dc-app/src/ 2>/dev/null || echo "No imports found"
echo -e "\n=== Repository structure check ==="
ls -la rise-dc-app/src/ 2>/dev/null | head -20Repository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 1666
🏁 Script executed:
#!/bin/bash
echo "=== quiet_hobbies/types.ts - TaskCategory definition ==="
sed -n '30,40p' rise-dc-app/src/scheduling_components/quiet_hobbies/types.ts
echo -e "\n=== shared/types/index.ts - TaskCategory definition ==="
sed -n '105,120p' rise-dc-app/src/shared/types/index.ts
echo -e "\n=== Full context in quiet_hobbies/types.ts (lines 25-45) ==="
sed -n '25,45p' rise-dc-app/src/scheduling_components/quiet_hobbies/types.ts
echo -e "\n=== Full context in shared/types/index.ts (lines 100-125) ==="
sed -n '100,125p' rise-dc-app/src/shared/types/index.tsRepository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 1671
🏁 Script executed:
#!/bin/bash
echo "=== taskService.ts full content ==="
cat -n rise-dc-app/src/services/taskService.ts
echo -e "\n=== Check where taskService functions are called ==="
rg -n "taskService\|from.*taskService" rise-dc-app/src/ -A 2 | head -40Repository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 1299
🏁 Script executed:
#!/bin/bash
echo "=== Task interface in shared/types ==="
rg -n "export interface Task" rise-dc-app/src/shared/types/index.ts -A 10Repository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 355
Fix TaskCategory import to use shared/types enum consistently.
taskService.ts imports TaskCategory from quiet_hobbies/types, which defines it as a union type with "Quiet Hobbies" (with space) and "Miscellaneous". However, the Task interface from shared/types uses the TaskCategory enum with QuietHobbies (no space) and Misc as the key. This causes a type mismatch in createTask(): the function accepts TaskPayload with the union type but returns Task with the enum type, creating incompatible string literal values.
Update the import to use the TaskCategory enum from shared/types:
-import { TaskCategory } from "../scheduling_components/quiet_hobbies/types";
+import { TaskCategory } from "../shared/types";📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import { TaskCategory } from "../scheduling_components/quiet_hobbies/types"; | |
| import { TaskCategory } from "../shared/types"; |
🤖 Prompt for AI Agents
In rise-dc-app/src/services/taskService.ts around line 1, the file currently
imports TaskCategory from quiet_hobbies/types (a union of string literals like
"Quiet Hobbies" and "Miscellaneous") which conflicts with the Task interface
that expects the TaskCategory enum from shared/types (QuietHobbies, Misc).
Replace the import to pull TaskCategory from shared/types (the enum) and update
any usages in createTask() (and related payload typing) to use the enum values
rather than the union string literals so the returned Task matches the
shared/types TaskCategory enum.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
backend/src/routes/scheduler.ts (1)
92-104: Add input validation for event creation.The endpoint accepts multiple fields but doesn't validate required fields like
name. Consider adding validation to ensure the request body contains all necessary data before creating an event.Example validation:
if (!name) { return res.status(400).json({ error: "name is required" }); } if (!icon) { return res.status(400).json({ error: "icon is required" }); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
backend/src/routes/scheduler.ts(3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
backend/src/routes/scheduler.ts (2)
rise-dc-app/src/shared/types/index.ts (2)
Event(101-103)Feedback(114-119)rise-dc-app/src/scheduling_components/quiet_hobbies/types.ts (1)
TaskCategory(33-39)
🔇 Additional comments (2)
backend/src/routes/scheduler.ts (2)
101-102: TimeSlot defaults fixed correctly.The previous review comment about type mismatches has been addressed. The defaults now correctly use
TimeSlotobjects instead of empty strings, which aligns with the PR objectives.
103-103:TaskCategory.Miscis valid and correctly defined.The original concern was incorrect.
TaskCategoryis an enum (not just a type alias) with aMiscproperty defined as"Miscellaneous"inrise-dc-app/src/shared/types/index.ts(line 111), soTaskCategory.Miscwill not cause a runtime error.However, there is a type safety issue: the frontend defines a separate
TaskCategorytype alias inrise-dc-app/src/scheduling_components/quiet_hobbies/types.tsthat includes the literal"Quiet Hobbies"(with a space), while the backend enum uses"QuietHobbies"(no space). The type assertion(category as TaskCategory)bypasses validation and could mask this mismatch if category values from the frontend don't align with the backend enum. Consider adding runtime validation to ensure the category value is one of the valid enum values.Likely an incorrect or invalid review comment.
| const { userId, name, icon, steps, image, startTime, endTime, category, complete } = req.body; | ||
| const event: Event = { | ||
| id: `event_${Date.now()}`, | ||
| userId: userId || "", |
There was a problem hiding this comment.
Consider requiring userId instead of defaulting to empty string.
Defaulting userId to an empty string could complicate user-based filtering, ownership tracking, and access control. If events must be associated with a user, validate that userId is provided and return a 400 error if missing.
Apply this diff to require userId:
- userId: userId || "",
+ userId,Then add validation before creating the event:
if (!userId) {
return res.status(400).json({ error: "userId is required" });
}🤖 Prompt for AI Agents
In backend/src/routes/scheduler.ts around line 95, the code currently defaults
userId to an empty string which hides missing-user errors; remove the defaulting
and require a userId value by validating before creating the event—if userId is
falsy return a 400 response with a JSON error { error: "userId is required"
}—then proceed to create the event using the provided userId.
| const feedback: Feedback = { | ||
| id: `feedback_${Date.now()}`, | ||
| taskAssignmentId, | ||
| taskAssignmentId: "", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's look at the scheduler.ts file around line 130
cat -n backend/src/routes/scheduler.ts | sed -n '115,145p'Repository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 1057
🏁 Script executed:
# Search for Feedback interface definition
fd -t f . | xargs rg -l 'interface Feedback'Repository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 228
🏁 Script executed:
# Search for taskAssignmentId usage patterns throughout the codebase
rg -n 'taskAssignmentId' --type=ts -C 2Repository: Hack4Impact-UMD/microsoft-hackathon-fall25
Length of output: 1080
taskAssignmentId is hardcoded to an empty string despite being a required field.
The Feedback interface explicitly requires taskAssignmentId: string (line 116 in rise-dc-app/src/shared/types/index.ts), but line 130 hardcodes it to an empty string without accepting it from the request body. This violates the interface contract and will create records with missing assignment tracking.
Either extract taskAssignmentId from the request body at line 127, or update the Feedback and FeedbackPayload interfaces to make this field optional if it's not yet implemented.
🤖 Prompt for AI Agents
In backend/src/routes/scheduler.ts around line 130 (and where the request body
is read at ~line 127), taskAssignmentId is hardcoded to "" which violates the
Feedback interface; update the code to extract taskAssignmentId from the
incoming request body (add it to the destructured fields or read
req.body.taskAssignmentId), validate it (ensure it's a string / non-empty if
required), and assign that value to taskAssignmentId instead of the empty
string; if this field genuinely may be absent, alternatively update the Feedback
and FeedbackPayload interfaces to make taskAssignmentId optional and adjust
downstream code accordingly.
Overview
Connected the tasks creation and display in the Scheduler page to the Cosmos database with TanStack Query. New tasks created are added to the database and exisiting tasks are fetched from the database.
Changes
Demo
Screen.Recording.2025-12-01.at.5.22.44.PM.mp4
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.