Skip to content

created api for restaurant owner - #4

Merged
abeeraqureshi189-sudo merged 1 commit into
mainfrom
development
Jul 25, 2026
Merged

created api for restaurant owner#4
abeeraqureshi189-sudo merged 1 commit into
mainfrom
development

Conversation

@abeeraqureshi189-sudo

@abeeraqureshi189-sudo abeeraqureshi189-sudo commented Jul 25, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Added real account registration, login, session restoration, and logout handling.
    • Added restaurant creation and profile updates, including image uploads for owners.
    • Added booking creation, cancellation, booking history, and status updates.
    • Added owner views for managing restaurant bookings.
    • Added admin tools for reviewing restaurants, approving or rejecting listings, and viewing platform statistics.
    • Added improved authentication and role-based access controls across protected features.

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds a shared client API layer, connects authentication and owner actions to backend endpoints, introduces booking and admin APIs, adds owner image uploads, converts server modules to CommonJS, updates Mongoose models, mounts new routers, and adds database seeding.

Changes

Quick-Dine API integration

Layer / File(s) Summary
Client API and workflow integration
client/lib/api.ts, client/src/context/AppContext.tsx, client/src/components/owner/*, client/src/assets/assets.ts, client/src/components/{admin,booking,home,restaurant}/*, client/src/components/AuthModal.tsx
The client adds Axios authorization handling, uses backend authentication and owner endpoints, persists returned state, and removes embedded restaurant data.
Backend runtime and authentication
server/config/db.js, server/controllers/authControllers.js, server/controllers/restaurantController.js, server/middlewares/auth.js, server/models/user.js, server/routes/{authRoutes,restaurantRoutes}.js, server/server.js
Server modules use CommonJS exports, authentication and role middleware are wired, auth handlers are updated, and API routers are mounted during startup.
Booking persistence and routes
server/models/Booking.js, server/controllers/bookingControllers.js, server/routes/bookingRoutes.js
Booking validation, capacity checks, ownership checks, cancellation, populated responses, and booking identifier generation are implemented behind protected routes.
Owner and admin workflows
server/config/multer.js, server/controllers/{ownerControllers,adminControllers}.js, server/models/Restaurant.js, server/routes/{ownerRoutes,adminRoutes}.js, server/package.json
Owner restaurant and booking management, Multer-backed image uploads, Cloudinary integration, admin approval/statistics endpoints, and protected route wiring are added.
Database seed workflow
server/seed.js
The seed script resets collections, creates default users, inserts approved restaurants, and handles MongoDB cleanup and failures.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant api
  participant AuthAPI
  participant OwnerAPI
  participant Database
  Client->>api: Authenticate and attach token
  api->>AuthAPI: POST /auth/login or /auth/register
  AuthAPI->>Database: Read or create user
  Database-->>AuthAPI: Return user
  AuthAPI-->>Client: Return token and user data
  Client->>OwnerAPI: Submit restaurant or booking update
  OwnerAPI->>Database: Validate and persist change
  Database-->>OwnerAPI: Return updated record
  OwnerAPI-->>Client: Return API response
Loading

Possibly related PRs

Suggested reviewers: abeeraqureshi

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: adding owner-focused API endpoints and related backend support.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch development

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

@abeeraqureshi189-sudo
abeeraqureshi189-sudo merged commit b1d5ea2 into main Jul 25, 2026
1 check was pending

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 18

🧹 Nitpick comments (2)
server/controllers/adminControllers.js (1)

43-52: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Parallelize the five independent queries.

All five are independent, so the dashboard endpoint currently pays five sequential round trips.

⚡ Proposed refactor
-        const totalUsers = await User.countDocuments({ role: 'user' });
-        const totalOwners = await User.countDocuments({ role: 'owner' });
-        const totalBookings = await Booking.countDocuments({});
-        const totalRestaurants = await Restaurant.countDocuments({});
-
-        const latestBookings = await Booking.find({})
-            .populate('user', 'name email')
-            .populate('restaurant', 'name')
-            .sort({ createdAt: -1 })
-            .limit(10);
+        const [totalUsers, totalOwners, totalBookings, totalRestaurants, latestBookings] = await Promise.all([
+            User.countDocuments({ role: 'user' }),
+            User.countDocuments({ role: 'owner' }),
+            Booking.countDocuments({}),
+            Restaurant.countDocuments({}),
+            Booking.find({})
+                .populate('user', 'name email')
+                .populate('restaurant', 'name')
+                .sort({ createdAt: -1 })
+                .limit(10)
+        ]);
🤖 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 `@server/controllers/adminControllers.js` around lines 43 - 52, Update the
dashboard query flow containing totalUsers, totalOwners, totalBookings,
totalRestaurants, and latestBookings to execute all five independent database
operations concurrently, such as by awaiting a single Promise.all while
preserving each result’s existing assignment and latestBookings query options.
server/server.js (1)

36-43: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Consider failing fast on DB connection failure.

If connectDB() throws, the error is only logged; nothing stops the server from continuing to start (once app.listen is added), leaving it running with a broken DB layer. Exiting the process (as shown above) lets your process manager/orchestrator restart it instead of silently serving broken requests.

🤖 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 `@server/server.js` around lines 36 - 43, Update startServer so its connectDB
catch block terminates the process after logging the connection error, ensuring
the server does not continue startup when connectDB fails and allowing the
process manager to restart it.
🤖 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 `@client/lib/api.ts`:
- Around line 3-8: Remove the manual multipart Content-Type override from the
FormData request in RestaurantWizard, while keeping the shared api configuration
unchanged. Let Axios/the browser set the multipart Content-Type and boundary
automatically for that request.

In `@client/src/assets/assets.ts`:
- Line 103: Update the featured export that currently constructs `[undefined,
undefined, undefined]` from `dummyRestaurant` so it contains no undefined
entries; preserve the legacy `dummyRestaurant` export as an empty value or
migrate/remove its consumers, including the export around line 222.

In `@client/src/components/owner/OwnerBookings.tsx`:
- Around line 16-18: Update the booking status action in OwnerBookings to track
the in-flight booking ID and disable both status controls immediately while its
request is pending, preventing conflicting updates for the same booking. After a
successful api.put, synchronize local state from the server response or refetch
the booking data instead of relying only on the requested newStatus.

In `@client/src/context/AppContext.tsx`:
- Line 4: The API client imports point to nonexistent src/lib locations; update
the imports in client/src/context/AppContext.tsx:4,
client/src/components/owner/OwnerBookings.tsx:5,
client/src/components/owner/OwnerProfileDetails.tsx:5, and
client/src/components/owner/RestaurantWizard.tsx:5 to use ../../lib/api.ts for
AppContext and ../../../lib/api.ts for each owner component.

In `@server/config/multer.js`:
- Around line 5-8: Update the multer configuration in the upload definition to
add a fileFilter that accepts only image MIME types and rejects all other
uploads before they are streamed to Cloudinary. Preserve the existing storage
configuration and 5 MB file-size limit.

In `@server/controllers/adminControllers.js`:
- Line 3: Use consistent casing for the User model imports: update
server/controllers/adminControllers.js lines 3-3 and server/seed.js lines 5-5 to
reference the lowercase user model filename, or rename the model file to User.js
and update both imports accordingly.

In `@server/controllers/authControllers.js`:
- Around line 48-51: Update the catch blocks in generateUser, loginUser, and
getMe to avoid returning raw error.message values; respond with a generic
client-safe message instead. Preserve the handlers’ expected 400 responses for
validated client errors, but classify unexpected failures such as database
errors as 500 responses.
- Around line 1-3: Update the User model import to use the lowercase module path
in server/controllers/authControllers.js (lines 1-3),
server/controllers/restaurantController.js (lines 1-2), and
server/middlewares/auth.js (lines 1-2), while leaving the User symbol usage
unchanged.

In `@server/controllers/bookingControllers.js`:
- Around line 27-55: Update the booking flow around existingBookings,
availableSeats, and Booking.create to reserve the restaurant/time-slot capacity
with an atomic conditional counter update, and create the booking within the
same database transaction. Ensure the reservation succeeds only when enough
seats remain, rolls back the counter if booking creation fails, and returns the
existing capacity error when the conditional update cannot reserve the requested
guests.

In `@server/controllers/ownerControllers.js`:
- Around line 45-51: Update the restaurant creation flow in ownerControllers to
remove the pre-write Restaurant.findOne slug check, rely on the unique index,
and handle duplicate-key errors in its catch block by returning HTTP 409 with
the existing duplicate-name message. Ensure slug generation produces a
non-empty, valid fallback for names containing no ASCII alphanumeric characters,
such as “寿司”.

In `@server/models/Booking.js`:
- Around line 23-27: Update the guests field in the Booking schema to validate
that values are whole numbers in addition to remaining required and at least 1;
add the integer validator at this schema boundary so fractional guest counts
such as 1.5 are rejected.
- Around line 51-54: Update the bookingId generation in the BookingSchema
pre-save hook to use substantially more random entropy than the current
four-byte value, while preserving the GR- prefix and uppercase hexadecimal
format.

In `@server/package.json`:
- Line 16: Add multer to the dependencies in server/package.json and regenerate
server/package-lock.json so the declared dependency and lockfile stay
synchronized. The existing server/config/multer.js site requires no direct
change; it is the consumer exposing the missing dependency.

In `@server/routes/adminRoutes.js`:
- Line 3: Update the controller imports in server/routes/adminRoutes.js lines
3-3 and server/routes/ownerRoutes.js lines 4-4 to use the existing plural module
paths adminControllers and ownerControllers, respectively, while preserving the
imported symbols and router behavior.

In `@server/routes/authRoutes.js`:
- Line 2: Update the require path in authRoutes.js to reference the existing
../controllers/authControllers.js module, preserving the imported generateUser,
loginUser, and getMe symbols so server startup can load the router successfully.

In `@server/routes/bookingRoutes.js`:
- Line 3: Update the controller import in bookingRoutes to reference the
existing bookingControllers module filename, preserving the createBooking,
getMyBookings, and cancelBooking destructured imports so the router loads
successfully.

In `@server/seed.js`:
- Around line 163-199: Remove the duplicate restaurant objects for slugs
l-essence and terraza-cielo from the seed data array so each slug appears only
once before insertMany runs. Preserve the existing unique restaurant records and
ensure the seeding process can insert the full dataset without an E11000
duplicate-key failure.

In `@server/server.js`:
- Around line 36-45: Update startServer to call app.listen using the existing
port after connectDB succeeds, and preserve the current database-connection
error handling so the server does not bind when connection setup fails. Use the
existing app and port symbols and ensure the startup flow makes mounted routers
reachable.

---

Nitpick comments:
In `@server/controllers/adminControllers.js`:
- Around line 43-52: Update the dashboard query flow containing totalUsers,
totalOwners, totalBookings, totalRestaurants, and latestBookings to execute all
five independent database operations concurrently, such as by awaiting a single
Promise.all while preserving each result’s existing assignment and
latestBookings query options.

In `@server/server.js`:
- Around line 36-43: Update startServer so its connectDB catch block terminates
the process after logging the connection error, ensuring the server does not
continue startup when connectDB fails and allowing the process manager to
restart it.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6cf1adac-153b-4e2a-81c7-cfa50c327226

📥 Commits

Reviewing files that changed from the base of the PR and between 3a98ed6 and 5832eb8.

⛔ Files ignored due to path filters (1)
  • server/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (33)
  • client/lib/api.ts
  • client/src/assets/assets.ts
  • client/src/components/AuthModal.tsx
  • client/src/components/admin/AdminApprovals.tsx
  • client/src/components/admin/AdminStats.tsx
  • client/src/components/booking/BookingForm.tsx
  • client/src/components/booking/BookingSuccess.tsx
  • client/src/components/booking/BookingSummary.tsx
  • client/src/components/home/CuisineBrowse.tsx
  • client/src/components/owner/OwnerBookings.tsx
  • client/src/components/owner/OwnerProfileDetails.tsx
  • client/src/components/owner/RestaurantWizard.tsx
  • client/src/components/restaurant/BookingWidget.tsx
  • client/src/context/AppContext.tsx
  • server/config/db.js
  • server/config/multer.js
  • server/controllers/adminControllers.js
  • server/controllers/authControllers.js
  • server/controllers/bookingControllers.js
  • server/controllers/ownerControllers.js
  • server/controllers/restaurantController.js
  • server/middlewares/auth.js
  • server/models/Booking.js
  • server/models/Restaurant.js
  • server/models/user.js
  • server/package.json
  • server/routes/adminRoutes.js
  • server/routes/authRoutes.js
  • server/routes/bookingRoutes.js
  • server/routes/ownerRoutes.js
  • server/routes/restaurantRoutes.js
  • server/seed.js
  • server/server.js

Comment thread client/lib/api.ts
Comment on lines +3 to +8
const api = axios.create({
baseURL: import.meta.env.VITE_API_URL || 'http://localhost:5000/api',
headers: {
'Content-Type': 'application/json'
}
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm owner image uploads build FormData and use the shared API client.
ast-grep outline client/src/components/owner/RestaurantWizard.tsx --items all
rg -n -C4 --type tsx 'FormData|api\.(post|put)\(' client/src/components/owner/RestaurantWizard.tsx

Repository: abeeraqureshi189-sudo/Quick-Dine

Length of output: 587


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## client/lib/api.ts\n'
cat -n client/lib/api.ts

printf '\n## client/src/components/owner/RestaurantWizard.tsx (outline)\n'
ast-grep outline client/src/components/owner/RestaurantWizard.tsx --items all

printf '\n## client/src/components/owner/RestaurantWizard.tsx (FormData/api usage)\n'
python3 - <<'PY'
from pathlib import Path
path = Path("client/src/components/owner/RestaurantWizard.tsx")
for i, line in enumerate(path.read_text().splitlines(), 1):
    if "FormData" in line or "api." in line or "append(" in line or "headers" in line:
        start = max(1, i-4)
        end = min(len(path.read_text().splitlines()), i+6)
        print(f"\n--- lines {start}-{end} ---")
        for j, l in enumerate(path.read_text().splitlines()[start-1:end], start):
            print(f"{j:4}: {l}")
PY

printf '\n## server/routes/ownerRoutes.js\n'
cat -n server/routes/ownerRoutes.js

Repository: abeeraqureshi189-sudo/Quick-Dine

Length of output: 10683


🌐 Web query:

Axios request headers override instance defaults Content-Type multipart/form-data precedence

💡 Result:

In Axios, headers follow a defined merge order of precedence, where request-specific configurations override instance-level defaults, which in turn override library defaults [1][2]. However, the behavior regarding the Content-Type header when using FormData is specialized and often automatic [3]. ### Header Precedence When Axios processes a request, it merges headers in the following order of precedence, with each level overriding the previous one [2][4]: 1. Library defaults (defined in lib/defaults/index.js) [2] 2. Instance defaults (defined during axios.create or via instance.defaults) [1][2] 3. Per-request configuration (passed directly in the request method call) [1][2] ### multipart/form-data and Content-Type Axios automatically detects FormData objects and is designed to set the Content-Type header appropriately, including the required boundary parameter [3][5]. * Automatic Handling: When you pass a FormData object as the request data, Axios (and the underlying runtime, such as the browser or Node.js) must calculate the boundary. For this reason, you should generally not manually set the Content-Type header to multipart/form-data [3]. * Overriding: If you manually set Content-Type: multipart/form-data in your request configuration, you may inadvertently strip or override the necessary boundary information, causing the request to fail on the server side [6][5]. * Preventing Automatic Headers: If you need to suppress Axios's automatic header management (for example, to let the browser handle it entirely or to avoid conflicts), you can set the header to false in your request config [7][8]: javascript axios.post('/upload', formData, { headers: { 'Content-Type': false // Allows the runtime to set the correct multipart header + boundary } }); Recent updates (such as PR #10980) have improved how helper methods like postForm handle this, ensuring that they no longer force a bare Content-Type: multipart/form-data header that lacks a boundary, thereby allowing the adapter to set it correctly [5]. If you find that manual headers are causing issues, ensure you are not explicitly setting a Content-Type that conflicts with the boundary required by your FormData object [5].

Citations:


🌐 Web query:

Axios FormData request headers multipart/form-data boundary manual Content-Type browser

💡 Result:

When using FormData with Axios in a browser environment, you should not manually set the Content-Type header [1][2]. If you manually set Content-Type: multipart/form-data, you will often interfere with the browser's ability to automatically generate and append the required multipart boundary [3]. The browser-native FormData implementation automatically handles the setting of the correct Content-Type header, including the necessary boundary parameter, when the request is sent [4][2]. If you provide the header manually, some adapters may fail to append this boundary, causing the server to reject the request [3][5]. Best practices for Axios and FormData: 1. Do not set the Content-Type header manually when sending a FormData object; let Axios/the browser handle it [1][2]. 2. If you need to initiate a multipart request easily, use the provided shortcut methods like axios.postForm, axios.putForm, or axios.patchForm, which automatically configure the Content-Type header [4][6][7]. 3. If you are using automatic object serialization (introduced in v0.27.0), where you pass a plain JavaScript object instead of a FormData instance, you may set the Content-Type to multipart/form-data, and Axios will serialize the object into FormData for you [1][4][6].

Citations:


Remove the manual multipart header

client/src/components/owner/RestaurantWizard.tsx:88-91
The shared Content-Type: application/json default is overridden here. The real issue is the per-request Content-Type: multipart/form-data, which can drop the multipart boundary; let Axios/browser set it for the FormData request.

🤖 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 `@client/lib/api.ts` around lines 3 - 8, Remove the manual multipart
Content-Type override from the FormData request in RestaurantWizard, while
keeping the shared api configuration unchanged. Let Axios/the browser set the
multipart Content-Type and boundary automatically for that request.

updatedAt: "2026-06-17T13:40:21.828Z",
},
];
export const dummyRestaurant = [];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Prevent undefined entries in the featured export.

With dummyRestaurant empty, Line 222 exports [undefined, undefined, undefined]. Consumers that render featured restaurant properties will fail. Keep the legacy export empty or remove/migrate its consumers.

Proposed fix
-export const dummyFeaturedRestaurants = [dummyRestaurant[0], dummyRestaurant[1], dummyRestaurant[2]];
+export const dummyFeaturedRestaurants = dummyRestaurant.slice(0, 3);

Also applies to: 222-222

🤖 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 `@client/src/assets/assets.ts` at line 103, Update the featured export that
currently constructs `[undefined, undefined, undefined]` from `dummyRestaurant`
so it contains no undefined entries; preserve the legacy `dummyRestaurant`
export as an empty value or migrate/remove its consumers, including the export
around line 222.

Comment on lines +16 to +18
await api.put(`/owner/bookings/${bookingId}/status`, {status: newStatus});
setBookings((prev)=>prev.map((b)=>b._id === bookingId ? {...b, status:newStatus} : b));
toast.success(`Booking status updated to ${newStatus}`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Prevent conflicting status updates for the same booking.

The buttons remain actionable until the request resolves. A quick “Complete” then “Cancel” submits conflicting writes; response order can leave local state different from the persisted status. Track the in-flight booking ID, disable both actions immediately, and update from the server response or refetch after success.

🤖 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 `@client/src/components/owner/OwnerBookings.tsx` around lines 16 - 18, Update
the booking status action in OwnerBookings to track the in-flight booking ID and
disable both status controls immediately while its request is pending,
preventing conflicting updates for the same booking. After a successful api.put,
synchronize local state from the server response or refetch the booking data
instead of relying only on the requested newStatus.

/* eslint-disable react-refresh/only-export-components */
import React, { createContext, useContext, useState, useEffect } from "react";
import { dummyUser } from "../assets/assets.js";
import api from "../lib/api.ts";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "API client files:"
fd -a '^api\.ts$' client

echo "Current API imports:"
rg -n 'from ["'\''].*lib/api(\.ts)?["'\'']' client/src

Repository: abeeraqureshi189-sudo/Quick-Dine

Length of output: 573


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Client tree (api-related):"
find client -maxdepth 3 \( -path 'client/lib' -o -path 'client/src/lib' -o -name 'tsconfig*.json' -o -name 'vite.config.*' -o -name 'jsconfig.json' \) -print | sort

echo
echo "Client tsconfig/vite config snippets:"
for f in client/tsconfig.json client/tsconfig.app.json client/tsconfig.node.json client/vite.config.ts client/jsconfig.json; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    sed -n '1,220p' "$f"
  fi
done

echo
echo "API file locations:"
fd -a '^api\.ts$' client

echo
echo "Imports referencing lib/api:"
rg -n 'from ["'\''].*lib/api(\.ts)?["'\'']' client/src

Repository: abeeraqureshi189-sudo/Quick-Dine

Length of output: 1656


Fix the API client import paths

These imports resolve to client/src/lib/api.ts, but the shared client lives at client/lib/api.ts. Update them to point at the real file (../../lib/api.ts from client/src/context/AppContext.tsx, ../../../lib/api.ts from the owner components).

📍 Affects 4 files
  • client/src/context/AppContext.tsx#L4-L4 (this comment)
  • client/src/components/owner/OwnerBookings.tsx#L5-L5
  • client/src/components/owner/OwnerProfileDetails.tsx#L5-L5
  • client/src/components/owner/RestaurantWizard.tsx#L5-L5
🤖 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 `@client/src/context/AppContext.tsx` at line 4, The API client imports point to
nonexistent src/lib locations; update the imports in
client/src/context/AppContext.tsx:4,
client/src/components/owner/OwnerBookings.tsx:5,
client/src/components/owner/OwnerProfileDetails.tsx:5, and
client/src/components/owner/RestaurantWizard.tsx:5 to use ../../lib/api.ts for
AppContext and ../../../lib/api.ts for each owner component.

Comment thread server/config/multer.js
Comment on lines +5 to +8
const upload = multer({
storage,
limits: { fileSize: 5 * 1024 * 1024 } // 5MB limit
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Add a fileFilter so only images are accepted.

The size cap is enforced, but any content type is accepted and streamed to Cloudinary as a restaurant image.

🛡️ Proposed fix
 const upload = multer({
     storage,
-    limits: { fileSize: 5 * 1024 * 1024 } // 5MB limit
+    limits: { fileSize: 5 * 1024 * 1024 }, // 5MB limit
+    fileFilter: (req, file, cb) => {
+        if (/^image\/(jpeg|png|webp|avif)$/.test(file.mimetype)) return cb(null, true);
+        cb(new Error('Only JPEG, PNG, WebP or AVIF images are allowed'));
+    }
 });
📝 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
const upload = multer({
storage,
limits: { fileSize: 5 * 1024 * 1024 } // 5MB limit
});
const upload = multer({
storage,
limits: { fileSize: 5 * 1024 * 1024 }, // 5MB limit
fileFilter: (req, file, cb) => {
if (/^image\/(jpeg|png|webp|avif)$/.test(file.mimetype)) return cb(null, true);
cb(new Error('Only JPEG, PNG, WebP or AVIF images are allowed'));
}
});
🤖 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 `@server/config/multer.js` around lines 5 - 8, Update the multer configuration
in the upload definition to add a fileFilter that accepts only image MIME types
and rejects all other uploads before they are streamed to Cloudinary. Preserve
the existing storage configuration and 5 MB file-size limit.

@@ -0,0 +1,14 @@
const express = require('express');
const {adminOnly, protect} = require('../middlewares/auth');
const {getAllRestaurants, approveRestaurant, getAdminStats} = require('../controllers/adminController');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Both new routers import singular controller filenames that don't exist. The controllers are named adminControllers.js and ownerControllers.js (plural), so mounting either router throws MODULE_NOT_FOUND at startup.

  • server/routes/adminRoutes.js#L3-L3: change the require path to '../controllers/adminControllers'.
  • server/routes/ownerRoutes.js#L4-L4: change the require path to '../controllers/ownerControllers'.
📍 Affects 2 files
  • server/routes/adminRoutes.js#L3-L3 (this comment)
  • server/routes/ownerRoutes.js#L4-L4
🤖 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 `@server/routes/adminRoutes.js` at line 3, Update the controller imports in
server/routes/adminRoutes.js lines 3-3 and server/routes/ownerRoutes.js lines
4-4 to use the existing plural module paths adminControllers and
ownerControllers, respectively, while preserving the imported symbols and router
behavior.

import {getMe, loginUser, registerUser} from "../controllers/authControllers.js";
import {Protect} from "../middlewares/auth.js";
const express = require('express');
const {generateUser, loginUser, getMe} = require('../controllers/authController');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

git ls-files 'server/**' | sed -n '1,120p'

Repository: abeeraqureshi189-sudo/Quick-Dine

Length of output: 765


🏁 Script executed:

cat -n server/routes/authRoutes.js
printf '\n---\n'
cat -n server/controllers/authControllers.js
printf '\n---\n'
cat -n server/server.js

Repository: abeeraqureshi189-sudo/Quick-Dine

Length of output: 5859


Wrong require path — authController does not exist.

server/routes/authRoutes.js:2 imports ../controllers/authController, but the module is ../controllers/authControllers.js. server.js loads this router on startup, so this causes Cannot find module and prevents the app from starting.

🔧 Fix
-const {generateUser, loginUser, getMe} = require('../controllers/authController');
+const {generateUser, loginUser, getMe} = require('../controllers/authControllers');
📝 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
const {generateUser, loginUser, getMe} = require('../controllers/authController');
const {generateUser, loginUser, getMe} = require('../controllers/authControllers');
🤖 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 `@server/routes/authRoutes.js` at line 2, Update the require path in
authRoutes.js to reference the existing ../controllers/authControllers.js
module, preserving the imported generateUser, loginUser, and getMe symbols so
server startup can load the router successfully.

@@ -0,0 +1,10 @@
const express = require('express');
const { protect } = require('../middlewares/auth');
const { createBooking, getMyBookings, cancelBooking } = require('../controllers/bookingController');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Fix the controller module path.

The added file is server/controllers/bookingControllers.js, but this import requests bookingController. Loading this router throws MODULE_NOT_FOUND.

Proposed fix
-const { createBooking, getMyBookings, cancelBooking } = require('../controllers/bookingController');
+const { createBooking, getMyBookings, cancelBooking } = require('../controllers/bookingControllers');
📝 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
const { createBooking, getMyBookings, cancelBooking } = require('../controllers/bookingController');
const { createBooking, getMyBookings, cancelBooking } = require('../controllers/bookingControllers');
🤖 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 `@server/routes/bookingRoutes.js` at line 3, Update the controller import in
bookingRoutes to reference the existing bookingControllers module filename,
preserving the createBooking, getMyBookings, and cancelBooking destructured
imports so the router loads successfully.

Comment thread server/seed.js
Comment on lines +163 to +199
{
name: "L'Essence",
slug: "l-essence",
description:
"An intimate, Parisian-inspired fine dining chamber wrapped in dark velvet and soft golden candle glow. L'Essence specializes in meticulous plating of haute gastronomy, creating a rich sensory dialogue between modern culinary innovation and classic romance.",
cuisine: "French",
priceRange: "$$$$",
rating: 4.9,
reviewCount: 88,
location: "Manhattan, NY",
address: "115 Greenwich St, New York, NY 10006",
image: "/restaurant_5.png",
chef: "Jean-Luc Picard",
tags: ["Romantic", "Velvet Booths", "Candlelit", "Haute Cuisine"],
availableSlots: ["18:00", "19:00", "20:00", "21:00", "22:00"],
featured: true,
exclusive: false
},
{
name: "Terraza Cielo",
slug: "terraza-cielo",
description:
"A sun-drenched rooftop oasis celebrating Italian and Mediterranean lifestyles. Featuring floor-to-ceiling foliage, white marble bistro tables, and panoramic skyline views, Terraza Cielo serves hand-crafted pastas and coastal seafood paired with bright botanical cocktails.",
cuisine: "Italian",
priceRange: "$$$",
rating: 4.7,
reviewCount: 205,
location: "Manhattan, NY",
address: "244 Fifth Ave Rooftop, New York, NY 10001",
image: "/restaurant_3.jpg",
chef: "Elena Rossi",
tags: ["Rooftop", "Skyline Views", "Handmade Pasta", "Craft Cocktails"],
availableSlots: ["12:00", "13:00", "17:00", "18:00", "19:00", "20:00", "21:00"],
featured: true,
exclusive: false
},
];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🔴 Critical | ⚡ Quick win

Duplicate slugs will abort insertMany and leave the database half-seeded.

l-essence (line 165) and terraza-cielo (line 183) repeat the entries at lines 57 and 75, but slug is unique: true in server/models/Restaurant.js. insertMany is ordered by default, so it throws E11000 after inserting only the first six restaurants, then process.exit(1) leaves the seeded users behind with partial restaurant data.

🐛 Proposed fix
-            {
-                name: "L'Essence",
-                slug: "l-essence",
-                description:
-                    "An intimate, Parisian-inspired fine dining chamber wrapped in dark velvet and soft golden candle glow. L'Essence specializes in meticulous plating of haute gastronomy, creating a rich sensory dialogue between modern culinary innovation and classic romance.",
-                cuisine: "French",
-                priceRange: "$$$$",
-                rating: 4.9,
-                reviewCount: 88,
-                location: "Manhattan, NY",
-                address: "115 Greenwich St, New York, NY 10006",
-                image: "/restaurant_5.png",
-                chef: "Jean-Luc Picard",
-                tags: ["Romantic", "Velvet Booths", "Candlelit", "Haute Cuisine"],
-                availableSlots: ["18:00", "19:00", "20:00", "21:00", "22:00"],
-                featured: true,
-                exclusive: false
-            },
-            {
-                name: "Terraza Cielo",
-                slug: "terraza-cielo",
-                description:
-                    "A sun-drenched rooftop oasis celebrating Italian and Mediterranean lifestyles. Featuring floor-to-ceiling foliage, white marble bistro tables, and panoramic skyline views, Terraza Cielo serves hand-crafted pastas and coastal seafood paired with bright botanical cocktails.",
-                cuisine: "Italian",
-                priceRange: "$$$",
-                rating: 4.7,
-                reviewCount: 205,
-                location: "Manhattan, NY",
-                address: "244 Fifth Ave Rooftop, New York, NY 10001",
-                image: "/restaurant_3.jpg",
-                chef: "Elena Rossi",
-                tags: ["Rooftop", "Skyline Views", "Handmade Pasta", "Craft Cocktails"],
-                availableSlots: ["12:00", "13:00", "17:00", "18:00", "19:00", "20:00", "21:00"],
-                featured: true,
-                exclusive: false
-            },
         ];
📝 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
{
name: "L'Essence",
slug: "l-essence",
description:
"An intimate, Parisian-inspired fine dining chamber wrapped in dark velvet and soft golden candle glow. L'Essence specializes in meticulous plating of haute gastronomy, creating a rich sensory dialogue between modern culinary innovation and classic romance.",
cuisine: "French",
priceRange: "$$$$",
rating: 4.9,
reviewCount: 88,
location: "Manhattan, NY",
address: "115 Greenwich St, New York, NY 10006",
image: "/restaurant_5.png",
chef: "Jean-Luc Picard",
tags: ["Romantic", "Velvet Booths", "Candlelit", "Haute Cuisine"],
availableSlots: ["18:00", "19:00", "20:00", "21:00", "22:00"],
featured: true,
exclusive: false
},
{
name: "Terraza Cielo",
slug: "terraza-cielo",
description:
"A sun-drenched rooftop oasis celebrating Italian and Mediterranean lifestyles. Featuring floor-to-ceiling foliage, white marble bistro tables, and panoramic skyline views, Terraza Cielo serves hand-crafted pastas and coastal seafood paired with bright botanical cocktails.",
cuisine: "Italian",
priceRange: "$$$",
rating: 4.7,
reviewCount: 205,
location: "Manhattan, NY",
address: "244 Fifth Ave Rooftop, New York, NY 10001",
image: "/restaurant_3.jpg",
chef: "Elena Rossi",
tags: ["Rooftop", "Skyline Views", "Handmade Pasta", "Craft Cocktails"],
availableSlots: ["12:00", "13:00", "17:00", "18:00", "19:00", "20:00", "21:00"],
featured: true,
exclusive: false
},
];
];
🤖 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 `@server/seed.js` around lines 163 - 199, Remove the duplicate restaurant
objects for slugs l-essence and terraza-cielo from the seed data array so each
slug appears only once before insertMany runs. Preserve the existing unique
restaurant records and ensure the seeding process can insert the full dataset
without an E11000 duplicate-key failure.

Comment thread server/server.js
Comment on lines +36 to +45
const startServer = async () => {
try{
await connectDB();
}
catch(error) {
console.error("Database connection failed", error);
}
}

startServer();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Server never calls app.listen() — no requests can ever reach it.

The file has no app.listen(port, ...) call; port (line 16) is declared but unused. As written, the app connects to MongoDB but never binds to a port, so none of the mounted routers are reachable.

🔧 Suggested fix
 const startServer = async () => {
     try{
         await connectDB();
+        app.listen(port, () => {
+            console.log(`Server running on port ${port}`);
+        });
     }
     catch(error) {
         console.error("Database connection failed", error);
+        process.exit(1);
     }
 }
📝 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
const startServer = async () => {
try{
await connectDB();
}
catch(error) {
console.error("Database connection failed", error);
}
}
startServer();
const startServer = async () => {
try{
await connectDB();
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
}
catch(error) {
console.error("Database connection failed", error);
process.exit(1);
}
}
startServer();
🤖 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 `@server/server.js` around lines 36 - 45, Update startServer to call app.listen
using the existing port after connectDB succeeds, and preserve the current
database-connection error handling so the server does not bind when connection
setup fails. Use the existing app and port symbols and ensure the startup flow
makes mounted routers reachable.

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.

2 participants