Skip to content

added requestoJoin controller#173

Open
div1681 wants to merge 2 commits intoswciitg:devfrom
div1681:div
Open

added requestoJoin controller#173
div1681 wants to merge 2 commits intoswciitg:devfrom
div1681:div

Conversation

@div1681
Copy link

@div1681 div1681 commented Feb 14, 2026

CodeAnt-AI Description

Add request-to-join bookings for travel posts and prevent admin homepage list sorting errors

What Changed

  • Users can send a "request to join" for a travel post; requests are saved as booking records and linked to the travel post
  • Duplicate requests are rejected and the travel-post owner receives an in-app notification when someone requests to join
  • Travel posts now store total seats, available seats, and a list of booking IDs so seat and booking information is persisted
  • Admin homepage list action ignores sort parameters to avoid sorting errors when viewing the single homepage entry
  • Reply notification call formatting fixed so replies trigger notifications reliably

Impact

✅ Can request to join travel posts
✅ Travel bookings are recorded and linked to posts
✅ Fewer admin list errors when viewing homepage

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@codeant-ai
Copy link

codeant-ai bot commented Feb 14, 2026

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai bot added the size:M This PR changes 30-99 lines, ignoring generated files label Feb 14, 2026
@codeant-ai
Copy link

codeant-ai bot commented Feb 14, 2026

Nitpicks 🔍

🔒 No security issues identified
⚡ Recommended areas for review

  • Seat availability / race condition
    The new requesttoJoin handler creates a booking and then pushes its id onto travelPost.bookings without checking or decrementing availableSeats. This allows overbooking and has a race condition because the two writes (creating booking and updating the post) are not atomic. Consider validating availableSeats and performing an atomic update (e.g. a single findOneAndUpdate with $inc and $push guarded by availableSeats > 0) to prevent lost updates and overbooking.

  • DB-level uniqueness / constraints
    The new TravelBookingSchema provides no unique index preventing duplicate bookings (e.g. same email for same travelPost). The controller checks for existing booking in application logic, but a DB-level unique index would enforce this invariant and avoid race conditions where two requests slip through concurrently.

  • Missing user null-check
    In sendPostReplyNotif the code fetches a user with onestopUserModel.findOne(...) and immediately calls sendToUser(user._id, ...) without confirming user exists. If the lookup returns null this will throw. Add a guard to ensure user is truthy before using _id.

  • Notification title / message construction
    In postReplyChat the notification title is built as Cab sharing reply: ${travelChatReply.message.substr(0, 1)} which captures only the first character of the message. That likely produces an unhelpful title. Confirm intended substring length or sanitize/trim content before using in a title.


await newBooking.save();

travelPost.bookings.push(newBooking._id);
Copy link

Choose a reason for hiding this comment

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

Suggestion: For existing travel posts that do not yet have a bookings array in the database, travelPost.bookings can be undefined, so calling .push on it will throw an error and break the join request flow. [null pointer]

Severity Level: Critical 🚨
- ❌ Join requests fail with 500 on posts lacking bookings field.
- ❌ Booking saved but not linked to travel post document.
- ⚠️ Users see failure despite their join request being stored.
Suggested change
travelPost.bookings.push(newBooking._id);
if (!Array.isArray(travelPost.bookings)) {
travelPost.bookings = [];
}
Steps of Reproduction ✅
1. Ensure there is a `TravelPostModel` document whose `bookings` field is not defined in
MongoDB (for example, an older travel post created before the bookings feature, or one
inserted directly without a `bookings` field).

2. Call `requesttoJoin` in `controllers/campusTravelController.js:37-79` with
`req.query.travelPostId` set to that travel post's `_id` and `req.body` containing a
unique `email` and `name` so that `existingBooking` at line 51 returns `null`.

3. In `requesttoJoin`, `TravelPostModel.findById(travelPostId)` at line 46 returns the
travel post, `new TravelBookingModel({...})` is created at lines 56-62, and `await
newBooking.save()` at line 64 successfully stores the booking.

4. Execution reaches `travelPost.bookings.push(newBooking._id);` at line 66; because
`travelPost.bookings` is `undefined` for that document, calling `.push` throws `TypeError:
Cannot read properties of undefined (reading 'push')`, the `catch` block at lines 76-78
returns HTTP 500, and the booking document remains saved but is not linked from the travel
post.
Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** controllers/campusTravelController.js
**Line:** 66:66
**Comment:**
	*Null Pointer: For existing travel posts that do not yet have a `bookings` array in the database, `travelPost.bookings` can be `undefined`, so calling `.push` on it will throw an error and break the join request flow.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
👍 | 👎

await sendToUser(user._id,NotificationCategories.cabSharing,title,`${replier} replied to your recent Travel Post on OneStop 🙌. Click to see!!`);
if (senderOutlook !== recieverOutlook) {
let user = await onestopUserModel.findOne({ outlookEmail: recieverOutlook });
await sendToUser(user._id, NotificationCategories.cabSharing, title, `${replier} replied to your recent Travel Post on OneStop 🙌. Click to see!!`);
Copy link

Choose a reason for hiding this comment

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

Suggestion: If no user is found for the given outlook email, onestopUserModel.findOne will return null and accessing user._id will throw a runtime error, preventing the notification from being sent and potentially crashing the request handler. [null pointer]

Severity Level: Major ⚠️
- ❌ Reply notification crashes when post owner has no user record.
- ⚠️ Unhandled promise rejection from `sendPostReplyNotif` during chat reply.
Suggested change
await sendToUser(user._id, NotificationCategories.cabSharing, title, `${replier} replied to your recent Travel Post on OneStop 🙌. Click to see!!`);
if (!user) {
return;
}
Steps of Reproduction ✅
1. Create a travel post via `postTravel` in `controllers/campusTravelController.js:13-26`
with `req.body.email` set to an address that does NOT have a corresponding user document
in `../models/userModel.js` (no `onestopUserModel` record with `outlookEmail` equal to
that email).

2. Send a reply to that travel post by invoking `postReplyChat` (exported from
`controllers/campusTravelController.js:202-220`) with `req.query.chatId` set to the travel
post's `chatId` and `req.body` containing `name`, `email` (the replier), and `message`.

3. Inside `postReplyChat` at line 209, `TravelPostModel.findOne({ chatId: id })` returns
the travel post; the `.then` callback calls `sendPostReplyNotif` at line 210 with
`recieverOutlook` set to `travelPost.email`.

4. In `sendPostReplyNotif` (`controllers/campusTravelController.js:195-200`),
`onestopUserModel.findOne({ outlookEmail: recieverOutlook })` returns `null` (no matching
user), and the subsequent `sendToUser(user._id, ...)` at line 198 attempts to access `_id`
on `null`, causing a `TypeError` and an unhandled promise rejection; the reply
notification is not sent.
Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** controllers/campusTravelController.js
**Line:** 198:198
**Comment:**
	*Null Pointer: If no user is found for the given outlook email, `onestopUserModel.findOne` will return `null` and accessing `user._id` will throw a runtime error, preventing the notification from being sent and potentially crashing the request handler.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
👍 | 👎


}, { timestamps: true });

const TravelBookingModel = mongoose.model("TravelBooking", TravelBookingSchema);
Copy link

Choose a reason for hiding this comment

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

Suggestion: The uniqueness check for one booking per user per travel post is implemented only at the application level, so two simultaneous join requests can both pass findOne and create duplicate bookings; a compound unique index is needed to enforce this constraint atomically. [race condition]

Severity Level: Major ⚠️
- ❌ Multiple TravelBooking docs per travelPost/email pair possible.
- ⚠️ Passenger counts derived from bookings can become inconsistent.
- ⚠️ Any logic assuming one booking per user may misbehave.
Suggested change
const TravelBookingModel = mongoose.model("TravelBooking", TravelBookingSchema);
TravelBookingSchema.index({ travelPost: 1, email: 1 }, { unique: true });
Steps of Reproduction ✅
1. Start the Node.js application (or a Node REPL) with the current PR code so that
`models/campusTravelModel.js` is loaded and `TravelBookingModel` (defined at
`models/campusTravelModel.js:50`) is registered with Mongoose.

2. In a script or REPL, import `{ TravelPostModel, TravelBookingModel }` from
`models/campusTravelModel.js` and create a `TravelPost` document using
`TravelPostModel.create(...)` so you have a valid `travelPost` ObjectId to reference
(schema at `models/campusTravelModel.js:3-19`).

3. Still in that script/REPL, call `Promise.all([...])` (or otherwise fire two parallel
`TravelBookingModel.create({ travelPost: <id>, email: "user@example.com", name: "User" })`
calls) using the same `travelPost` id and `email`. Because `TravelBookingSchema` at
`models/campusTravelModel.js:31-48` defines no unique index or constraint on `travelPost`
+ `email`, both inserts will succeed.

4. Query `TravelBookingModel.find({ travelPost: <id>, email: "user@example.com" })` and
observe that multiple booking documents exist for the same `travelPost`/`email` pair,
showing that the database layer does not prevent duplicate bookings; any application-level
`findOne` pre-check (if present elsewhere in the codebase) would be vulnerable to races
since the model itself is not enforcing uniqueness.
Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** models/campusTravelModel.js
**Line:** 50:50
**Comment:**
	*Race Condition: The uniqueness check for one booking per user per travel post is implemented only at the application level, so two simultaneous join requests can both pass `findOne` and create duplicate bookings; a compound unique index is needed to enforce this constraint atomically.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
👍 | 👎

@codeant-ai
Copy link

codeant-ai bot commented Feb 14, 2026

CodeAnt AI finished reviewing your PR.

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

Labels

size:M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants