<?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>Forem: Abdelghani El Mouak</title>
    <description>The latest articles on Forem by Abdelghani El Mouak (@kemora_13conf).</description>
    <link>https://forem.com/kemora_13conf</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%2F1974256%2F4d6b11b0-9513-4ba8-b4a5-a903d83f14ab.jpg</url>
      <title>Forem: Abdelghani El Mouak</title>
      <link>https://forem.com/kemora_13conf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kemora_13conf"/>
    <language>en</language>
    <item>
      <title>A New Sharp but built with Rust x10 Faster.</title>
      <dc:creator>Abdelghani El Mouak</dc:creator>
      <pubDate>Thu, 11 Dec 2025 09:52:46 +0000</pubDate>
      <link>https://forem.com/kemora_13conf/a-new-sharp-but-built-with-rust-x10-faster-4a0a</link>
      <guid>https://forem.com/kemora_13conf/a-new-sharp-but-built-with-rust-x10-faster-4a0a</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/aissam_irhir_1e776f7ef2ac/build-a-10x-faster-image-upload-api-in-15-minutes-with-bun-16m7" class="crayons-story__hidden-navigation-link"&gt;Build a 10x Faster Image Upload API in 15 Minutes with Bun&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/aissam_irhir_1e776f7ef2ac" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2170398%2Fce45b7cb-7844-4f3a-b04b-c0ea6156e07f.png" alt="aissam_irhir_1e776f7ef2ac profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/aissam_irhir_1e776f7ef2ac" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Aissam Irhir
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Aissam Irhir
                
              
              &lt;div id="story-author-preview-content-3099377" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/aissam_irhir_1e776f7ef2ac" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2170398%2Fce45b7cb-7844-4f3a-b04b-c0ea6156e07f.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Aissam Irhir&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/aissam_irhir_1e776f7ef2ac/build-a-10x-faster-image-upload-api-in-15-minutes-with-bun-16m7" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Dec 11 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/aissam_irhir_1e776f7ef2ac/build-a-10x-faster-image-upload-api-in-15-minutes-with-bun-16m7" id="article-link-3099377"&gt;
          Build a 10x Faster Image Upload API in 15 Minutes with Bun
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/javascript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;javascript&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/bunjs"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;bunjs&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/api"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;api&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/aissam_irhir_1e776f7ef2ac/build-a-10x-faster-image-upload-api-in-15-minutes-with-bun-16m7" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;6&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/aissam_irhir_1e776f7ef2ac/build-a-10x-faster-image-upload-api-in-15-minutes-with-bun-16m7#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              3&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            6 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
      <category>javascript</category>
      <category>bunjs</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>Hacking Mongoose: How I Built a Global Plugin to Stop Data Leaks 🛡️</title>
      <dc:creator>Abdelghani El Mouak</dc:creator>
      <pubDate>Wed, 10 Dec 2025 22:47:47 +0000</pubDate>
      <link>https://forem.com/kemora_13conf/hacking-mongoose-how-i-built-a-global-plugin-to-stop-data-leaks-3gnc</link>
      <guid>https://forem.com/kemora_13conf/hacking-mongoose-how-i-built-a-global-plugin-to-stop-data-leaks-3gnc</guid>
      <description>&lt;p&gt;Data leaks are the nightmare of every backend developer. You forget one &lt;code&gt;.select('-password')&lt;/code&gt; in a new endpoint, and suddenly your user's sensitive data is exposed.&lt;/p&gt;

&lt;p&gt;In this deep dive, I'm going to show you how &lt;strong&gt;FieldShield&lt;/strong&gt; solves this problem by hacking into the Mongoose middleware chain to enforce security at the database abstraction level.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture Problem
&lt;/h2&gt;

&lt;p&gt;In a typical Express/Mongoose app, security is often handled in the &lt;strong&gt;Controller&lt;/strong&gt; layer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Controller&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;safeUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;omit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toObject&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ssn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt; &lt;span class="c1"&gt;// Manual filtering&lt;/span&gt;
&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;safeUser&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is prone to human error. If you access the database from a background job, a script, or a different controller, you have to remember to apply the same filter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security should be defined where the data is defined: in the Schema.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter FieldShield
&lt;/h2&gt;

&lt;p&gt;FieldShield is a native Mongoose plugin that allows you to define per-field access roles directly in your schema definition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UserSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;shield&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;public&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;shield&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;owner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;shield&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;shield&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Hidden from everyone&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Under the Hood: The &lt;code&gt;pre('find')&lt;/code&gt; Hook
&lt;/h3&gt;

&lt;p&gt;The magic happens in how we intercept Mongoose queries. When you install &lt;code&gt;FieldShield&lt;/code&gt;, we patch the Mongoose &lt;code&gt;Query&lt;/code&gt; prototype to accept a context (roles).&lt;/p&gt;

&lt;p&gt;Then, we register a global &lt;code&gt;pre&lt;/code&gt; hook that inspects the query before it's sent to MongoDB.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Simplified logic from src/query.ts&lt;/span&gt;
&lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;find&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;roles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_shieldRoles&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Passed via .role('admin')&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allowedFields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;calculateAllowedFields&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;modelName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// We force a projection on the query&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allowedFields&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means the database &lt;strong&gt;only returns what you are allowed to see&lt;/strong&gt;. The sensitive data never even enters your Node.js process memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge: Aggregation Pipelines
&lt;/h2&gt;

&lt;p&gt;Simple queries are easy. But what about &lt;code&gt;Model.aggregate()&lt;/code&gt;? Aggregations allow arbitrary stages that can reshape documents, making it hard to track fields.&lt;/p&gt;

&lt;p&gt;FieldShield solves this by injecting a &lt;code&gt;$project&lt;/code&gt; stage dynamically.&lt;/p&gt;

&lt;p&gt;We analyze your pipeline and insert a protection stage right after the initial &lt;code&gt;$match&lt;/code&gt;, ensuring that indexes are used efficiently but data is filtered before it flows through the rest of your pipeline (e.g., into &lt;code&gt;$group&lt;/code&gt; or &lt;code&gt;$lookup&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Input&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="c1"&gt;// ... more stages&lt;/span&gt;
&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;role&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;public&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Actual Pipeline Executed&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$project&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// Injected by FieldShield&lt;/span&gt;
  &lt;span class="c1"&gt;// ... more stages&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  New in v2.2: Recursive Shield Inheritance 🔄
&lt;/h2&gt;

&lt;p&gt;One of the tough technical challenges we just solved in v2.2 was &lt;strong&gt;Nested Object and Array Inheritance&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In MongoDB, &lt;code&gt;preferences.theme&lt;/code&gt; is a distinct path from &lt;code&gt;preferences&lt;/code&gt;. If you hide &lt;code&gt;preferences.notifications&lt;/code&gt;, does the user still see the &lt;code&gt;preferences&lt;/code&gt; object?&lt;/p&gt;

&lt;p&gt;We implemented a recursive parser that synthesizes parent permissions based on their children.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If &lt;strong&gt;any&lt;/strong&gt; child is visible, the parent field is visible.&lt;/li&gt;
&lt;li&gt;If &lt;strong&gt;all&lt;/strong&gt; children are hidden, the parent is hidden.&lt;/li&gt;
&lt;li&gt;The parent inherits the &lt;strong&gt;union&lt;/strong&gt; of all child roles.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures you don't have to manually effectively duplicate shield configs on parent objects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance Verification 🚀
&lt;/h2&gt;

&lt;p&gt;Because FieldShield uses native MongoDB projections, it's actually &lt;strong&gt;faster&lt;/strong&gt; than fetching the full document and filtering it in JavaScript.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Network I/O:&lt;/strong&gt; Reduced (smaller payloads).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory:&lt;/strong&gt; Reduced (fewer objects created).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CPU:&lt;/strong&gt; Reduced (MongoDB handles the filtering in C++).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  We Need You! 🫵
&lt;/h2&gt;

&lt;p&gt;FieldShield is fully open source, and we have big plans for v3.0, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🛡️ Advanced wildcard policies&lt;/li&gt;
&lt;li&gt;🔍 GraphQL integration&lt;/li&gt;
&lt;li&gt;⚡ Caching for policy calculation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are looking for contributors! Whether you're a TypeScript wizard, a Mongoose expert, or just want to write better docs, we'd love your help.&lt;/p&gt;

&lt;h3&gt;
  
  
  Good First Issues
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Add more unit tests for edge cases&lt;/li&gt;
&lt;li&gt;Improve documentation examples&lt;/li&gt;
&lt;li&gt;Create a benchmark suite&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Star the repo and check out the issues:&lt;/strong&gt;&lt;br&gt;
👉 &lt;a href="https://github.com/kemora13conf/wecon-mongoose-field-shield" rel="noopener noreferrer"&gt;github.com/kemora13conf/wecon-mongoose-field-shield&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's build the standard for Mongoose security together.&lt;/p&gt;

</description>
      <category>mongoose</category>
      <category>security</category>
      <category>mongodb</category>
      <category>node</category>
    </item>
    <item>
      <title>Seeking Feedback: My React Project Structure for Scalability and Maintainability</title>
      <dc:creator>Abdelghani El Mouak</dc:creator>
      <pubDate>Sun, 24 Nov 2024 19:00:51 +0000</pubDate>
      <link>https://forem.com/kemora_13conf/seeking-feedback-my-react-project-structure-for-scalability-and-maintainability-5f64</link>
      <guid>https://forem.com/kemora_13conf/seeking-feedback-my-react-project-structure-for-scalability-and-maintainability-5f64</guid>
      <description>&lt;p&gt;Hey Devs! I'm working on a new React project and have put a lot of thought into structuring it for long-term scalability and maintainability. I'd love to get your feedback and hear any suggestions you might have.&lt;/p&gt;

&lt;p&gt;I've opted for a primarily feature-based structure, centered around the concept of pages, to maximize component reuse and minimize code duplication. Here's a simplified overview:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;src/&lt;br&gt;
├── App/                 # Application entry and providers&lt;br&gt;
│   ├── Providers/      # Context providers (Theme, I18N)&lt;br&gt;
│   ├── Routes/         # Routing configuration&lt;br&gt;
│   └── Stores/         # Global state management (using Zustand/Redux/etc.)&lt;br&gt;
├── Config/             # Application-wide configurations&lt;br&gt;
├── Core/                # Core functionalities (Auth, Error handling)&lt;br&gt;
├── Features/           # Page-based features&lt;br&gt;
│   ├── Home/           # Home page feature&lt;br&gt;
│   │   ├── Api/       # API calls related to Home&lt;br&gt;
│   │   ├── Components/ # Components specific to Home&lt;br&gt;
│   │   ├── I18N/      # Internationalization for Home&lt;br&gt;
│   │   ├── Pages/     # Page-level components&lt;br&gt;
│   │   │   └── index.tsx   # Main Home page component.&lt;br&gt;
│   │   │   └── SuperAdminHome.tsx  # Role Specific variant&lt;br&gt;
│   │   └── Stores/    # State management for Home (if needed)&lt;br&gt;
│   ├── Profile/        # Profile page feature (similar structure)&lt;br&gt;
│   └── Users/         # Users management feature&lt;br&gt;
│       ├── Api/       # API interactions&lt;br&gt;
│       ├── Components/ # Components (potentially subdivided)&lt;br&gt;
│       ├── Hooks/      # Custom Hooks&lt;br&gt;
│       ├── I18N/      # Internationalization&lt;br&gt;
│       ├── Pages/     # Page components&lt;br&gt;
│       │    ├── List/         # User list pages, Role based folder organization&lt;br&gt;
│       │    │   ├── index.tsx     # Main users list component&lt;br&gt;
│       │    │   └── SuperAdminListActions.tsx   # Variation if need be&lt;br&gt;
│       │    └── Create/       # Create user pages&lt;br&gt;
│       │        ├── index.tsx     # Main user create component&lt;br&gt;
│       │        └── SuperAdminCreateUserForm.tsx  # Variation if need be&lt;br&gt;
│       └── Stores/    # User-related state&lt;br&gt;
├── Layout/             # Layout components (Header, Sidebar)&lt;br&gt;
├── Shared/             # Shared components and utilities&lt;br&gt;
│   ├── Assets/&lt;br&gt;
│   ├── Components/&lt;br&gt;
│   └── Utils/&lt;br&gt;
└── ...&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Key Decisions and Considerations:&lt;/p&gt;

&lt;p&gt;Page-centric Features: Organizing features around pages promotes component reuse and simplifies navigation.&lt;/p&gt;

&lt;p&gt;Role-based Variations: Role-specific variations are handled within the page's folder (e.g., separate components or conditional rendering) to keep related logic together.&lt;/p&gt;

&lt;p&gt;Clear Separation of Concerns: Dedicated folders for API calls, components, hooks, I18N, and stores enhance maintainability.&lt;/p&gt;

&lt;p&gt;Shared for Reusability: Reusable components and utility functions live in the Shared directory.&lt;/p&gt;

&lt;p&gt;Questions for the Community:&lt;/p&gt;

&lt;p&gt;What are your thoughts on this structure? Do you see any potential drawbacks or areas for improvement?&lt;/p&gt;

&lt;p&gt;How would you handle more complex role-based variations within this structure?&lt;/p&gt;

&lt;p&gt;Any best practices or alternative approaches you would recommend?&lt;/p&gt;

&lt;p&gt;Is there anything I've overlooked or could be done differently to further improve scalability and maintainability?&lt;/p&gt;

&lt;p&gt;Thanks in advance for your insights! I'm eager to learn from your experiences and improve my project architecture.&lt;/p&gt;

&lt;h1&gt;
  
  
  reactjs #architecture #projectstructure #webdev #discuss
&lt;/h1&gt;

</description>
      <category>architecture</category>
      <category>javascript</category>
      <category>react</category>
      <category>boilerplate</category>
    </item>
  </channel>
</rss>
