Skip to content

Database Models#2

Open
GEORGELECHA wants to merge 1 commit intomainfrom
database-models
Open

Database Models#2
GEORGELECHA wants to merge 1 commit intomainfrom
database-models

Conversation

@GEORGELECHA
Copy link
Copy Markdown
Owner

@GEORGELECHA GEORGELECHA commented May 6, 2026

Summary by CodeRabbit

  • New Features

    • Event management system with automatic URL-friendly identifiers and timestamp normalization.
    • Booking functionality with email validation for user submissions.
    • Database integration with optimized, cached connection handling for improved reliability.
  • Documentation

    • Added comprehensive project documentation covering database models, architecture, and design decisions.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 6, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9f0097a3-84da-4e12-899e-650c71d0f18a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • ✅ Review completed - (🔄 Check again to review again)
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@database/booking.model.ts`:
- Around line 17-41: The schema currently only indexes eventId which allows
duplicate {eventId, email} bookings; update BookingSchema by removing the
single-field index on eventId and add a compound unique index on { eventId,
email } to enforce one booking per email per event (use BookingSchema.index({
eventId: 1, email: 1 }, { unique: true })). Ensure the new index is declared
after the schema definition so Mongoose applies it at model creation.

In `@database/event.model.ts`:
- Around line 55-66: The 12-hour parsing branch (the match12 result in
database/event.model.ts) currently accepts invalid inputs like "13:30 PM",
"00:30 AM", or minutes >59; add validation after parsing the captured groups to
ensure hours is between 1 and 12 and minutes is between 0 and 59 before applying
AM/PM conversion, and if invalid, reject/return an error or null instead of
continuing the conversion; update the logic around match12 handling (the
variables hours, minutes, period and the AM/PM conversion) to perform this guard
check first.

In `@lib/mongodb.ts`:
- Around line 52-64: dbConnect currently returns cached.conn unconditionally and
never clears cached.promise or cached.conn after a failed connect or later
disconnect; update dbConnect (and the cached handling around
cached.promise/cached.conn) to clear the cache on errors and on disconnects:
wrap the await of cached.promise in a try/catch and on catch set cached.promise
= null and cached.conn = null before rethrowing, and register a
mongoose.connection listener (e.g., 'disconnected' or 'close' and/or 'error')
that resets cached.conn and cached.promise to null so subsequent calls to
dbConnect will attempt a fresh mongoose.connect; reference cached.promise,
cached.conn, and the dbConnect function to locate the change.

In `@projectExplanation.md`:
- Line 1: Add a top-level H1 heading to the very start of projectExplanation.md
(above the existing first line "Zero type errors in the database/ files...") to
satisfy MD041; insert an H1 like "Project Explanation" as the first line so the
document has a primary title.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: abd4975d-0dfc-4496-b338-07cf285902a7

📥 Commits

Reviewing files that changed from the base of the PR and between d776c0f and 61b85dd.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • database/booking.model.ts
  • database/event.model.ts
  • database/index.ts
  • lib/mongodb.ts
  • package.json
  • projectExplanation.md

Comment thread database/booking.model.ts
Comment on lines +17 to +41
const BookingSchema = new Schema<IBooking>(
{
eventId: {
type: Schema.Types.ObjectId,
ref: "Event",
required: [true, "Event ID is required"],
// Index for fast lookups when querying bookings by event
index: true,
},
email: {
type: String,
required: [true, "Email is required"],
trim: true,
lowercase: true,
validate: {
validator: (v: string) => EMAIL_REGEX.test(v),
message: "Email must be a valid email address",
},
},
},
{
// Automatically adds createdAt and updatedAt fields
timestamps: true,
}
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Prevent duplicate bookings for the same event/email pair.

This schema currently allows multiple identical { eventId, email } documents. Since there is no quantity or ticket identifier on the record, retries and double-submits become indistinguishable duplicate bookings. Replace the single-field index with a compound unique index.

Proposed fix
     eventId: {
       type: Schema.Types.ObjectId,
       ref: "Event",
       required: [true, "Event ID is required"],
-      // Index for fast lookups when querying bookings by event
-      index: true,
     },
@@
 );
+
+BookingSchema.index({ eventId: 1, email: 1 }, { unique: true });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@database/booking.model.ts` around lines 17 - 41, The schema currently only
indexes eventId which allows duplicate {eventId, email} bookings; update
BookingSchema by removing the single-field index on eventId and add a compound
unique index on { eventId, email } to enforce one booking per email per event
(use BookingSchema.index({ eventId: 1, email: 1 }, { unique: true })). Ensure
the new index is declared after the schema definition so Mongoose applies it at
model creation.

Comment thread database/event.model.ts
Comment on lines +55 to +66
// Try matching "H:MM AM/PM" or "HH:MM AM/PM"
const match12 = trimmed.match(/^(\d{1,2}):(\d{2})\s*(AM|PM)$/);
if (match12) {
let hours = parseInt(match12[1], 10);
const minutes = parseInt(match12[2], 10);
const period = match12[3];

if (period === "PM" && hours !== 12) hours += 12;
if (period === "AM" && hours === 12) hours = 0;

return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Validate 12-hour inputs before converting them.

13:30 PM, 00:30 AM, and 10:75 PM all match this branch today and get normalized into impossible 24-hour values. Reject out-of-range hours/minutes before applying the AM/PM conversion.

Proposed fix
   const match12 = trimmed.match(/^(\d{1,2}):(\d{2})\s*(AM|PM)$/);
   if (match12) {
     let hours = parseInt(match12[1], 10);
     const minutes = parseInt(match12[2], 10);
     const period = match12[3];
+
+    if (hours < 1 || hours > 12 || minutes > 59) {
+      throw new Error(`Invalid time value: "${raw}"`);
+    }
 
     if (period === "PM" && hours !== 12) hours += 12;
     if (period === "AM" && hours === 12) hours = 0;
 
     return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@database/event.model.ts` around lines 55 - 66, The 12-hour parsing branch
(the match12 result in database/event.model.ts) currently accepts invalid inputs
like "13:30 PM", "00:30 AM", or minutes >59; add validation after parsing the
captured groups to ensure hours is between 1 and 12 and minutes is between 0 and
59 before applying AM/PM conversion, and if invalid, reject/return an error or
null instead of continuing the conversion; update the logic around match12
handling (the variables hours, minutes, period and the AM/PM conversion) to
perform this guard check first.

Comment thread lib/mongodb.ts
Comment on lines +52 to +64
if (cached.conn) {
return cached.conn;
}

// If no connection promise exists yet, start one.
if (!cached.promise) {
cached.promise = mongoose.connect(MONGODB_URI as string, {
bufferCommands: false,
});
}

// Await the pending connection and cache the result.
cached.conn = await cached.promise;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reset the cache when the connection is no longer usable.

dbConnect() currently treats any non-null cached.conn as healthy and never clears a rejected cached.promise. After a transient connect error or a later disconnect, every caller keeps reusing the same dead state until the process restarts.

Proposed fix
 async function dbConnect(): Promise<Mongoose> {
   // Return the existing connection if it's already established.
-  if (cached.conn) {
+  if (cached.conn?.connection.readyState === 1) {
     return cached.conn;
   }
+  if (cached.conn) {
+    cached.conn = null;
+    cached.promise = null;
+  }
 
   // If no connection promise exists yet, start one.
   if (!cached.promise) {
-    cached.promise = mongoose.connect(MONGODB_URI as string, {
-      bufferCommands: false,
-    });
+    cached.promise = mongoose
+      .connect(MONGODB_URI as string, {
+        bufferCommands: false,
+      })
+      .catch((error) => {
+        cached.conn = null;
+        cached.promise = null;
+        throw error;
+      });
   }
 
   // Await the pending connection and cache the result.
   cached.conn = await cached.promise;
   return cached.conn;
 }
📝 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.

Suggested change
if (cached.conn) {
return cached.conn;
}
// If no connection promise exists yet, start one.
if (!cached.promise) {
cached.promise = mongoose.connect(MONGODB_URI as string, {
bufferCommands: false,
});
}
// Await the pending connection and cache the result.
cached.conn = await cached.promise;
async function dbConnect(): Promise<Mongoose> {
// Return the existing connection if it's already established.
if (cached.conn?.connection.readyState === 1) {
return cached.conn;
}
if (cached.conn) {
cached.conn = null;
cached.promise = null;
}
// If no connection promise exists yet, start one.
if (!cached.promise) {
cached.promise = mongoose
.connect(MONGODB_URI as string, {
bufferCommands: false,
})
.catch((error) => {
cached.conn = null;
cached.promise = null;
throw error;
});
}
// Await the pending connection and cache the result.
cached.conn = await cached.promise;
return cached.conn;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/mongodb.ts` around lines 52 - 64, dbConnect currently returns cached.conn
unconditionally and never clears cached.promise or cached.conn after a failed
connect or later disconnect; update dbConnect (and the cached handling around
cached.promise/cached.conn) to clear the cache on errors and on disconnects:
wrap the await of cached.promise in a try/catch and on catch set cached.promise
= null and cached.conn = null before rethrowing, and register a
mongoose.connection listener (e.g., 'disconnected' or 'close' and/or 'error')
that resets cached.conn and cached.promise to null so subsequent calls to
dbConnect will attempt a fresh mongoose.connect; reference cached.promise,
cached.conn, and the dbConnect function to locate the change.

Comment thread projectExplanation.md
@@ -0,0 +1,18 @@
Zero type errors in the database/ files. All three files compile cleanly against Mongoose v9. Here's a summary of what was created:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add an H1 at the top of this document.

Line 1 starts with body text, which triggers MD041 and leaves the page without a primary title.

Proposed fix
-Zero type errors in the database/ files. All three files compile cleanly against Mongoose v9. Here's a summary of what was created:
+# Database model implementation notes
+
+Zero type errors in the database/ files. All three files compile cleanly against Mongoose v9. Here's a summary of what was created:
📝 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.

Suggested change
Zero type errors in the database/ files. All three files compile cleanly against Mongoose v9. Here's a summary of what was created:
# Database model implementation notes
Zero type errors in the database/ files. All three files compile cleanly against Mongoose v9. Here's a summary of what was created:
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@projectExplanation.md` at line 1, Add a top-level H1 heading to the very
start of projectExplanation.md (above the existing first line "Zero type errors
in the database/ files...") to satisfy MD041; insert an H1 like "Project
Explanation" as the first line so the document has a primary title.

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.

1 participant