<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hazem Kastouri</title>
    <description>The latest articles on DEV Community by Hazem Kastouri (@kastouri_hazem).</description>
    <link>https://dev.to/kastouri_hazem</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2784355%2F1615d94b-b2cd-4c5c-b0b6-92f6eb5c1285.jpg</url>
      <title>DEV Community: Hazem Kastouri</title>
      <link>https://dev.to/kastouri_hazem</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kastouri_hazem"/>
    <language>en</language>
    <item>
      <title>How a Single MongoDB Typo Wiped My Production Database (3 Times!) – And How to Avoid It</title>
      <dc:creator>Hazem Kastouri</dc:creator>
      <pubDate>Fri, 27 Jun 2025 15:18:21 +0000</pubDate>
      <link>https://dev.to/kastouri_hazem/how-a-single-mongodb-typo-wiped-my-production-database-7-times-and-how-to-avoid-it-4f3g</link>
      <guid>https://dev.to/kastouri_hazem/how-a-single-mongodb-typo-wiped-my-production-database-7-times-and-how-to-avoid-it-4f3g</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;When User.remove(userId) silently deletes everything, and why MongoDB won't warn you&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I stared at my empty users collection in horror. For the seventh time. My 'minor bug fix' had just nuked every customer account in production – and MongoDB didn't even blink. Here's how a missing {} cost me days of recovery work, and how you can bulletproof your database.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;The Silent Killer&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// What I wrote (DANGER):
await User.remove(userId); 

// What I meant (SAFE):
await User.remove({ _id: userId });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Why This Happened (3 Times!)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;No Query Validation:&lt;/strong&gt; MongoDB prioritizes flexibility over safety&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production Blindspots:&lt;/strong&gt; No backups → no quick recovery&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assumption Trap:&lt;/strong&gt; "It's just a delete, how bad could it be?"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;My 3-Part Survival Kit&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Backup Armor&lt;/strong&gt;&lt;br&gt;
Automated backups every 15 minutes (shoutout to mongodump cron jobs)&lt;br&gt;
Pro Tip: Test your restore process before disaster strikes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Paranoid Sanitization&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Safety Wrapper Example
const safeDelete = async (collection, id) =&amp;gt; {
  if (!id || typeof id !== 'string') throw new Error("Invalid ID format");
  return collection.deleteOne({ _id: new ObjectId(id) }); // Explicit is better
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Nuclear Option Prevention&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Renamed collections to users_prod/users_staging&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Added middleware logging all bulk deletions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Switched to deleteOne() for explicit single-doc ops&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why MongoDB "Allows" This&lt;/strong&gt;&lt;br&gt;
MongoDB's philosophy:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Flexible queries &amp;gt; strict validation&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Historic behavior (changing would break legacy code)&lt;/p&gt;

&lt;p&gt;Your responsibility: Validate inputs&lt;/p&gt;

&lt;p&gt;Key Takeaways&lt;br&gt;
✅ Always wrap IDs in query objects: { _id: value }&lt;br&gt;
✅ Prefer deleteOne() over deleteMany() for this kind of cases&lt;br&gt;
✅ Backup like your business depends on it (because it does)&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
