home / skills / joncrangle / .dotfiles / prevention-patterns

This skill helps you prevent regressions by applying known bug patterns across frontend, backend, and general code health during reviews.

npx playbooks add skill joncrangle/.dotfiles --skill prevention-patterns

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
1.3 KB
---
name: PreventionPatterns
description: Known bug patterns and their fixes to prevent regression.
---

<skill_doc>
# Prevention Patterns

When reviewing code or debugging, check against these known issues.

## 🛡️ React/Frontend Patterns
- **Missing Dependency**: `useEffect` dependency array incomplete?
- **Stale Closures**: Using state in callbacks without refs or functional updates?
- **Key Props**: Using `index` as key in list rendering? (Bad for re-ordering).
- **Zod Schema mismatch**: Frontend types not aligned with Backend API responses?

## 🛡️ Node/Backend Patterns
- **Unhandled Promise**: Missing `.catch()` or `try/catch` in async handlers?
- **SQL Injection**: String concatenation in queries instead of parameters?
- **Env Vars**: Hardcoded secrets instead of `process.env`?
- **Race Conditions**: Parallel DB updates to the same record?

## 🛡️ General Code Health
- **Slop Variables**: `data`, `info`, `temp`, `obj`. Rename them.
- **Deep Nesting**: More than 3 levels of indentation? Refactor/Extract.
- **Dead Code**: Imports unused? Functions never called?

## 🧪 Post-Mortem Protocol
When a bug is fixed, ask:
1. "Could this have been caught by a type?"
2. "Could this have been caught by a test?"
3. "Could this have been caught by a lint rule?"
Add the answer here.
</skill_doc>

Overview

This skill catalogs known bug patterns and suggested fixes to prevent regressions across frontend, backend, and general code health. It helps reviewers and maintainers spot common issues quickly and standardize post-mortem checks. Use it to reduce repeat bugs and improve codebase reliability.

How this skill works

The skill highlights recurring anti-patterns (e.g., stale closures, unhandled promises, SQL injection risks) and recommends concrete preventive actions. It groups patterns by area (React/frontend, Node/backend, general code health) and provides a short post-mortem protocol to capture lessons learned after fixes. Apply the checks during code review, debugging, or writing tests.

When to use it

  • During code reviews to catch common regressions before merge
  • When debugging to quickly map symptoms to likely causes
  • When writing tests to target previously seen failure modes
  • During onboarding to teach new contributors common pitfalls
  • After fixing a bug to record root-cause prevention steps

Best practices

  • Validate useEffect dependency arrays and prefer refs or functional updates to avoid stale closures
  • Avoid using array index as React keys when list order can change
  • Always handle async errors with try/catch or .catch(), and await promises properly
  • Use parameterized queries or an ORM to prevent SQL injection
  • Replace vague variable names (data, temp, obj) with descriptive identifiers
  • Run lint rules and tests that enforce shallow nesting and remove dead code

Example use cases

  • A reviewer spots a useEffect missing a dependency and asks for a unit test that reproduces the stale update
  • A backend handler lacks .catch(), so add error handling and a test that simulates a DB failure
  • Refactor a deeply nested function into smaller units to reduce cognitive load and enable targeted tests
  • Add an integration test to ensure frontend Zod schemas match backend API responses
  • During a post-mortem, record whether the bug could have been caught by types, tests, or lints

FAQ

How do I decide if a pattern needs a lint rule?

If the pattern is frequent and easily detected statically (e.g., unused imports, excessive nesting), create or enable a lint rule; otherwise prefer tests or code review checklists.

What if a fix adds too much boilerplate?

Balance ergonomics and safety: use helper utilities, abstractions, or shared patterns so fixes stay consistent without repeating boilerplate.