From d680a61826429130e337f3000710fa095b2a219c Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 17:31:01 +0000 Subject: [PATCH] feat(backend): initialize specialized documentation for nodejs architecture Co-authored-by: beginwebdev2002 <102213457+beginwebdev2002@users.noreply.github.com> --- backend/nodejs/architecture.md | 115 ++++++++++++++++++++++ backend/nodejs/security-best-practices.md | 98 ++++++++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 backend/nodejs/architecture.md create mode 100644 backend/nodejs/security-best-practices.md diff --git a/backend/nodejs/architecture.md b/backend/nodejs/architecture.md new file mode 100644 index 0000000..64eb9c5 --- /dev/null +++ b/backend/nodejs/architecture.md @@ -0,0 +1,115 @@ +--- +technology: Node.js +domain: backend +level: Senior/Architect +version: "24+" +tags: [best-practices, nodejs, architecture, design-patterns, clean-code, scalable-code, system-design] +ai_role: Senior Node.js Architecture Expert +last_updated: 2026-03-24 +--- + +# 🟢 Node.js Architectural Patterns & Structuring + +## ⚙️ Context & Scope +This document strictly enforces the deterministic architectural boundaries and structural patterns for Node.js backend systems. + +```mermaid +graph TD + A["🟢 HTTP Interface Layer"] --> B["🔌 Controller / Route Layer"] + B --> C["⚙️ Core Business Logic (Services)"] + C --> D["🗄️ Data Access Layer (Repositories)"] + D --> E["💾 Persistent Storage"] + + %% Added Design Token Styles for Mermaid Diagrams + classDef default fill:#e1f5fe,stroke:#03a9f4,stroke-width:2px,color:#000; + classDef component fill:#e8f5e9,stroke:#4caf50,stroke-width:2px,color:#000; + classDef layout fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px,color:#000; + + class A layout; + class B component; + class C component; + class D component; + class E layout; +``` + +--- + +## 1. 🛑 Domain Coupling in Controllers +### ❌ Bad Practice +```javascript +// A controller handling HTTP request parsing, business logic, and database operations. +app.post('/api/users', async (req, res) => { + const { name, email } = req.body; + if (!email.includes('@')) return res.status(400).send('Invalid email'); + const user = await db.collection('users').insertOne({ name, email, createdAt: new Date() }); + await emailService.sendWelcome(email); + res.status(201).json(user); +}); +``` +### ⚠️ Problem +Tightly coupling business logic and database queries directly inside the HTTP transport layer (controllers) prevents unit testing and code reusability. It violates the Single Responsibility Principle, turning routes into unmaintainable monoliths. +### ✅ Best Practice +```javascript +// Controller delegating logic to the Service Layer +app.post('/api/users', async (req, res, next) => { + try { + const userDTO = await userService.createUser(req.body); + res.status(201).json(userDTO); + } catch (error) { + next(error); + } +}); +``` +### 🚀 Solution +Controllers MUST ONLY handle HTTP payload parsing and response formatting. Core business operations MUST be delegated to isolated Service classes. + +## 2. 🗂️ Dependency Inversion +### ❌ Bad Practice +```javascript +// Hardcoding a database dependency directly into a service +const db = require('../config/database'); + +class UserService { + async getUser(id) { + return db.query('SELECT * FROM users WHERE id = ?', [id]); + } +} +``` +### ⚠️ Problem +Hardcoding infrastructural dependencies directly into the service layer creates rigid code. It prevents dynamic swapping of database adapters and blocks the use of isolated mock databases during unit testing. +### ✅ Best Practice +```javascript +// Injecting dependencies through the constructor +class UserService { + constructor(userRepository) { + this.userRepository = userRepository; + } + + async getUser(id) { + return this.userRepository.findById(id); + } +} +``` +### 🚀 Solution +STRICTLY apply Dependency Injection. Services MUST receive infrastructural dependencies via their constructor, enabling decoupled layers and testability. + +## 3. 🌐 Global State Mutation +### ❌ Bad Practice +```javascript +// Mutating global process.env during runtime +function setConfig(newPort) { + process.env.PORT = newPort; +} +``` +### ⚠️ Problem +Mutating global state variables like `process.env` during application runtime creates unpredictable, non-deterministic side effects across all imported modules. This leads to untraceable bugs in asynchronous execution. +### ✅ Best Practice +```javascript +// Using an immutable configuration object +const config = Object.freeze({ + port: process.env.PORT || 3000, + dbUrl: process.env.DATABASE_URL +}); +``` +### 🚀 Solution +Configuration objects MUST be locked and immutable after initialization. FORBID any runtime mutations to the global execution environment. diff --git a/backend/nodejs/security-best-practices.md b/backend/nodejs/security-best-practices.md new file mode 100644 index 0000000..3baecfd --- /dev/null +++ b/backend/nodejs/security-best-practices.md @@ -0,0 +1,98 @@ +--- +technology: Node.js +domain: backend +level: Senior/Architect +version: "24+" +tags: [security, best-practices, nodejs, clean-code, scalable-code, system-design] +ai_role: Senior Node.js Security Expert +last_updated: 2026-03-24 +--- + +# 🟢 Node.js Security Best Practices + +## ⚙️ Context & Scope +This document outlines the strict security configurations and anti-patterns that must be mitigated in a production Node.js environment. + +--- + +## 1. 🛑 Prototype Pollution +### ❌ Bad Practice +```javascript +// Unsafe recursive object merging +function merge(target, source) { + for (let key in source) { + if (typeof source[key] === 'object') { + if (!target[key]) target[key] = {}; + merge(target[key], source[key]); + } else { + target[key] = source[key]; + } + } + return target; +} +``` +### ⚠️ Problem +Unsafe object merging allows attackers to overwrite properties on the global `Object.prototype` (e.g., via `__proto__`). This Prototype Pollution leads to application-wide configuration manipulation, privilege escalation, or Remote Code Execution (RCE). +### ✅ Best Practice +```javascript +// Safe merging utilizing null-prototype objects and property validation +function safeMerge(target, source) { + for (let key in source) { + if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue; + if (typeof source[key] === 'object' && source[key] !== null) { + if (!target[key]) target[key] = {}; + safeMerge(target[key], source[key]); + } else { + target[key] = source[key]; + } + } + return target; +} +``` +### 🚀 Solution +STRICTLY filter reserved prototype keys (`__proto__`, `constructor`, `prototype`) during deep clone or merge operations. Alternatively, use robust, community-vetted libraries (like lodash.merge) that have built-in pollution defenses. + +## 2. 🔏 Hardcoded Secrets +### ❌ Bad Practice +```javascript +// Exposing secrets in code +const dbClient = new Database('postgres://admin:supersecretpassword@db.internal:5432/mydb'); +``` +### ⚠️ Problem +Embedding plaintext passwords or API keys directly in source code guarantees a critical security breach if the repository is compromised. Hardcoded secrets persist in Git history forever and expose backend infrastructure to attackers. +### ✅ Best Practice +```javascript +// Utilizing environment variables safely +const dbUrl = process.env.DATABASE_URL; +if (!dbUrl) throw new Error('MANDATORY DATABASE_URL config is missing'); + +const dbClient = new Database(dbUrl); +``` +### 🚀 Solution +MANDATORY injection of secrets via environment variables or secret management vaults (e.g., AWS Secrets Manager, HashiCorp Vault). NEVER commit sensitive material to version control. + +## 3. 🛡️ Regular Expression Denial of Service (ReDoS) +### ❌ Bad Practice +```javascript +// A vulnerable regex pattern evaluated on user input +const emailRegex = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/; +app.post('/validate', (req, res) => { + const isValid = emailRegex.test(req.body.email); + res.send({ isValid }); +}); +``` +### ⚠️ Problem +Using poorly optimized regular expressions with nested quantifiers (Catastrophic Backtracking) allows an attacker to send crafted payloads that block the Node.js event loop entirely. This causes a complete Denial of Service (ReDoS). +### ✅ Best Practice +```javascript +// Using a robust, vetted validation library +const validator = require('validator'); + +app.post('/validate', (req, res) => { + if (typeof req.body.email !== 'string') return res.status(400).send('Invalid format'); + const isValid = validator.isEmail(req.body.email); + res.send({ isValid }); +}); +``` +### 🚀 Solution +FORBID the use of complex, custom regular expressions on unconstrained user input. STRICTLY utilize established validation libraries and apply input length constraints before regex execution.