Skip to content

fix: enforce catalog integrity for order item creation#59

Open
dharapandya85 wants to merge 1 commit intofuzziecoder:mainfrom
dharapandya85:fix/enforce-catalog-integrity
Open

fix: enforce catalog integrity for order item creation#59
dharapandya85 wants to merge 1 commit intofuzziecoder:mainfrom
dharapandya85:fix/enforce-catalog-integrity

Conversation

@dharapandya85
Copy link

@dharapandya85 dharapandya85 commented Mar 4, 2026

Fixes #18

Changes:

  • computes total server-side
  • prevents client from overriding financial values
  • rejects unknown products

Summary by CodeRabbit

  • Bug Fixes
    • Order validation has been strengthened to reject invalid field submissions, ensuring data integrity in order requests.

@vercel
Copy link

vercel bot commented Mar 4, 2026

@dharapandya85 is attempting to deploy a commit to the Revon Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link

coderabbitai bot commented Mar 4, 2026

📝 Walkthrough

Walkthrough

The createOrder function in the backend database module now validates incoming order items by rejecting any that include name, unitPrice, or total fields, ensuring these server-computed values cannot be overridden by client input.

Changes

Cohort / File(s) Summary
Order Validation
backend/db.js
Added validation guard in createOrder to reject order items containing name, unitPrice, or total fields, enforcing server-side computation from catalog data.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

Poem

🐰 A guard stands tall at order's gate,
No sneaky names shall override our fate,
The catalog speaks, the truth rings clear,
Only trusted values venture here! 🛡️

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly reflects the main change: enforcing catalog integrity for order item creation by rejecting client-supplied financial fields.
Linked Issues check ✅ Passed The changes address all acceptance criteria from issue #18: rejecting unknown productIds, deriving item values from catalog, and preventing client-provided price overrides.
Out of Scope Changes check ✅ Passed All changes are directly scoped to validating order item creation against catalog requirements; no extraneous modifications were introduced.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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

Copy link

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/db.js`:
- Around line 244-247: The map callback used to build parsedItems currently uses
the 'in' operator on item which can throw a TypeError for
null/undefined/primitives and also checks prototype properties; before accessing
'in' replace that with a type guard that ensures item is a non-null object
(e.g., typeof item === 'object' && item !== null) and then use
Object.prototype.hasOwnProperty.call(item, 'name') / 'unitPrice' / 'total' to
check only own properties; update the items.map callback to validate and throw
the existing Error when those own properties are present, and otherwise continue
parsing so malformed payloads produce a controlled validation error instead of a
runtime TypeError.

ℹ️ Review info
Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0a9875a5-d430-4829-8be2-4625fef04d23

📥 Commits

Reviewing files that changed from the base of the PR and between 7c7156f and 455386d.

📒 Files selected for processing (1)
  • backend/db.js

Comment on lines 244 to +247
const parsedItems = items.map((item) => {
if ('name' in item || 'unitPrice' in item || 'total' in item) {
throw new Error('Do not provide name, unitPrice, or total. These are derived from catalog. ')
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

JavaScript in operator behavior with null undefined primitives TypeError

💡 Result:

In JavaScript, the in operator requires its right-hand operand to be an Object. Per the ECMAScript spec, evaluating prop in rhs does:

  • evaluate rhs to a value rVal
  • if rVal is not an Object, throw TypeError
  • otherwise return HasProperty(rVal, ToPropertyKey(prop)) (checks own + prototype chain) [1]

So these all throw, because the RHS is not an Object (including null, undefined, and all primitives like strings/numbers/booleans/bigints/symbols):

"x" in null        // TypeError
"x" in undefined   // TypeError
"length" in "abc"  // TypeError

This is the same error described by MDN (“right-hand side of 'in' should be an object”) and it explicitly calls out null/undefined and primitives as causes [2].

How to avoid the TypeError

1) Guard against nullish values (most common):

if (obj != null && ("x" in obj)) { ... }  // obj is not null/undefined

2) If you intentionally want “wrap primitives” behavior:

"x" in Object(maybeValue)   // never throws for null/undefined; primitives get boxed

(Be aware this changes semantics vs throwing—for null/undefined it becomes {}, for strings it becomes a String object wrapper.)

3) If you just want a safe property read (not in):
Use optional chaining for access:

const v = obj?.x; // undefined if obj is null/undefined

[3]

Sources: ECMAScript spec (RelationalExpression in) [1], MDN error reference for in with non-objects [2], MDN optional chaining [3].


🌐 Web query:

JavaScript in operator prototype chain inheritance check

💡 Result:

In JavaScript, the in operator returns true if a property exists either as an own property or anywhere on the object’s prototype chain:

const proto = { x: 1 };
const obj = Object.create(proto);

"x" in obj;          // true  (found on prototype)
Object.hasOwn(obj,"x"); // false (not an own property)

Key points:

  • prop in obj checks existence, not value—so it can be true even if obj[prop] === undefined. [1]
  • It includes inherited properties from prototypes, which is why it’s often not the right choice for “own property only” checks; use Object.hasOwn(obj, prop) (or hasOwnProperty.call) for that. [1]
  • If what you really want is an inheritance/prototype-chain relationship check (not a property check), use:
    • someProto.isPrototypeOf(obj) to test whether someProto appears in obj’s prototype chain, or
    • obj instanceof Ctor (which checks against Ctor.prototype). [2]

Sources:
[1] MDN — in operator (prototype chain behavior, Object.hasOwn recommendation) (developer.mozilla.org)
[2] MDN — Object.prototype.isPrototypeOf() (prototype chain relationship; note about instanceof) (developer.mozilla.org)

Citations:


🏁 Script executed:

# Find and examine the backend/db.js file around the changed lines
find . -name "db.js" -path "*/backend/*" | head -5

Repository: fuzziecoder/Brocode-Party-Update-App

Length of output: 95


🏁 Script executed:

# Read the broader context around lines 244-247 in backend/db.js
fd "db.js" backend | xargs wc -l

Repository: fuzziecoder/Brocode-Party-Update-App

Length of output: 97


🏁 Script executed:

# Read the backend/db.js file with line numbers, focusing on the function context around lines 244-247
sed -n '230,260p' backend/db.js | cat -n

Repository: fuzziecoder/Brocode-Party-Update-App

Length of output: 1364


🏁 Script executed:

# Read more context above createOrder to see if there's any upstream validation
sed -n '200,260p' backend/db.js | cat -n

Repository: fuzziecoder/Brocode-Party-Update-App

Length of output: 2620


🏁 Script executed:

# Check the broader function to see if items is validated anywhere before createOrder is called
sed -n '1,100p' backend/db.js | grep -A5 -B5 "createOrder\|items" | head -30

Repository: fuzziecoder/Brocode-Party-Update-App

Length of output: 997


Add type guard before using in operator on item; can throw TypeError on malformed payloads.

At line 246, the in operator throws a TypeError if item is null, undefined, or a primitive value. This can occur with malformed client input and will cause an unhandled runtime error instead of a proper validation error. Additionally, in checks the prototype chain; use Object.prototype.hasOwnProperty.call() to validate only own properties.

Suggested fix
   const parsedItems = items.map((item) => {
+    if (!item || typeof item !== 'object' || Array.isArray(item)) {
+      throw new Error('Each order item must be an object with productId and a positive integer quantity');
+    }
-    if ('name' in item || 'unitPrice' in item || 'total' in item) {
-      throw new Error('Do not provide name, unitPrice, or total. These are derived from catalog. ')
-    }
+    if (
+      Object.prototype.hasOwnProperty.call(item, 'name') ||
+      Object.prototype.hasOwnProperty.call(item, 'unitPrice') ||
+      Object.prototype.hasOwnProperty.call(item, 'total')
+    ) {
+      throw new Error('Do not provide name, unitPrice, or total. These are derived from catalog.');
+    }
📝 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 parsedItems = items.map((item) => {
if ('name' in item || 'unitPrice' in item || 'total' in item) {
throw new Error('Do not provide name, unitPrice, or total. These are derived from catalog. ')
}
const parsedItems = items.map((item) => {
if (!item || typeof item !== 'object' || Array.isArray(item)) {
throw new Error('Each order item must be an object with productId and a positive integer quantity');
}
if (
Object.prototype.hasOwnProperty.call(item, 'name') ||
Object.prototype.hasOwnProperty.call(item, 'unitPrice') ||
Object.prototype.hasOwnProperty.call(item, 'total')
) {
throw new Error('Do not provide name, unitPrice, or total. These are derived from catalog.');
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/db.js` around lines 244 - 247, The map callback used to build
parsedItems currently uses the 'in' operator on item which can throw a TypeError
for null/undefined/primitives and also checks prototype properties; before
accessing 'in' replace that with a type guard that ensures item is a non-null
object (e.g., typeof item === 'object' && item !== null) and then use
Object.prototype.hasOwnProperty.call(item, 'name') / 'unitPrice' / 'total' to
check only own properties; update the items.map callback to validate and throw
the existing Error when those own properties are present, and otherwise continue
parsing so malformed payloads produce a controlled validation error instead of a
runtime TypeError.

@fuzziecoder
Copy link
Owner

@dharapandya85 there are some issues please fix it then let me know

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.

Validate order products against catalog

2 participants