Modh
AboutServicesWorkPlaybookResourcesBook a call
Book a call
Agent Skills/Backend / Infrastructure/Code Quality Audit
Backend / Infrastructureadvanced6 min

search-code Code Quality Audit

Systematic audit and remediation of a route or module to production-grade quality. Use when auditing for SOLID violations, missing error handling, type safety gaps, dead code, duplicated patterns, or insufficient test coverage. Also use when remediating code to gold-standard clean architecture.

Install this skill

git submodule add https://github.com/modh-labs/playbook.git .playbook

One submodule installs all 17 skills. Reference .playbook/skills/code-quality-audit/SKILL.md from your AGENTS.md.


Code Quality Audit

Systematic audit and remediation to production-grade quality: SOLID architecture, clean separation of concerns, observability, type safety, test coverage, and DRY code.

When to Use

  • Module has fat files doing too many things (>500 lines)
  • Cross-layer violations (actions calling database directly, skipping the repository/service layer)
  • as any type casts, @ts-nocheck, console.error instead of structured logging
  • Missing or wrong-domain error captures
  • <50% test coverage on business-critical paths
  • Duplicated patterns across 3+ files
  • Dead code lingering from past refactors

Step 0 (BEFORE anything else): Detect Parallel Systems

Before splitting or refactoring, check if a gold-standard implementation already exists elsewhere.

Many codebases evolve a second system alongside the original. The new system has proper architecture; the old has active consumers. Splitting the old code into smaller files of still-bad code is wasted effort.

Detection checklist

# Check for parallel action/handler directories
ls {module}/actions/ {module}/_actions/ {module}/handlers/ {module}/_handlers/ 2>/dev/null

# Compare exports - find overlapping functionality
grep "^export" {module}/old-system/*.ts {module}/new-system/*.ts

# Find who actually imports from the old system
grep -rn "from.*old-system" {module}/ --include="*.tsx" | grep -v __tests__

Decision tree

  1. Old code has equivalent in new system -> Migrate consumer to new version, delete old code
  2. Old code has no equivalent -> Move to new system directory, upgrade to gold-standard patterns
  3. Old code is unused -> Delete immediately (verify with grep first)

The lesson: Don't polish bad code. Find the good code and route consumers to it.


Audit Checklist

For every action/handler file in the module, check:

CheckWhat to look for
Tracing wrapperIs the export wrapped with a tracing function?
Domain-specific error captureUses the correct domain capture, not bare exception handlers or borrowed captures?
Structured loggingUses a module logger, not console.error/log?
Input validationValidated with a schema (Zod, etc.) before any operations?
Cache/state invalidationUses a helper or consistent pattern after mutations?
Type safetyNo as any, no @ts-nocheck?
PII safetyNo emails/phones in error tags (only in non-indexed metadata)?
Test coverageHas tests with auth, validation, happy path, and error cases?
Dead codeNo COMPAT blocks, unused vars, stale imports, dangling JSDoc?

SOLID & Clean Architecture Audit

S - Single Responsibility

Each file should have ONE reason to change.

SmellFix
File >500 linesSplit into focused files, one per operation
Function does DB + business logic + notifications + cacheExtract to service layer or use repository pattern
Component renders + fetches + manages complex stateSplit into data layer + presentation layer

O - Open/Closed

Extend behavior without modifying existing code.

PatternExample
Error capture factoryNew domain = new file, zero changes to factory
Tracing wrapperNew tracing = wrap function, zero changes to business logic
Tag/metric registriesNew domain = add constants, existing domains untouched

L - Liskov Substitution

SmellFix
as any to force-fit a typeUse type guards, proper narrowing, or generics
@ts-nocheck to skip type checkingRemove, fix each error with targeted assertions
Function returns different shapes per branchDefine union return type or normalize to consistent shape

I - Interface Segregation

SmellFix
Params object with 20+ optional fieldsSplit into focused param types
Component props with 15+ fieldsUse compound component pattern
Function that accepts options it ignoresRemove unused params or split into focused functions

D - Dependency Inversion

Actions -> Services -> Repositories -> Database    CORRECT
Actions -> database.query("table")                 WRONG (skipping layers)
Module -> generic captureException                 WRONG (should use domain capture)
Module -> wrong-domain captureException            WRONG (cross-domain coupling)

Clean Architecture Layers

UI Layer (pages, components)     Fetch data, handle interactions
Action Layer (mutations)         Orchestrate: validate -> service/repo -> invalidate cache
Service Layer (business logic)   Complex logic spanning multiple repositories
Repository Layer (data access)   Single-table CRUD, typed returns
External (DB, APIs)              Never accessed directly above repository layer

Rules:

  • Dependencies point DOWN only
  • Cross-cutting concerns (logging, tracing, error capture) are injected via wrappers, not scattered inline

Business Logic & JTBD Validation

This is the most important audit. Clean code means nothing if the feature doesn't do what it's supposed to do.

Step 1: Understand the Job-to-be-Done

  1. Who is the user?
  2. What job are they hiring this code for?
  3. What's the critical path? (3-5 steps that MUST work)
  4. What's the failure mode? (lost revenue? missed follow-up? data corruption?)

Step 2: Trace the critical path end-to-end

User action
  -> Validate input
  -> Call service/repository
  -> Process result
  -> Trigger side effects (notifications, webhooks, audit log)
  -> Invalidate cache
  -> Return fresh data to UI

At each step: What if this fails? Is the error caught? Does the user see a meaningful message? Is the system left in a consistent state?

Business Logic Red Flags

  • Validates input but doesn't verify ownership (authorization bypass)
  • Mutation succeeds but doesn't invalidate related caches (stale UI)
  • Side effects fire before DB commit (data inconsistency)
  • No idempotency on retryable operations (duplicates)
  • Status transition allows invalid states
  • Financial calculation uses floating point instead of integer cents
  • Return type says success but operation was never awaited

Remediation Steps (in order)

  1. Detect parallel systems - Find and migrate before splitting
  2. Domain error capture - Create/use domain-specific capture function
  3. Wrap with tracing - Add tracing wrapper to all exports
  4. Security audit - No PII in error tags, proper authorization
  5. Type safety - Eliminate as any, use type guards
  6. DRY extraction - Consolidate patterns duplicated in 3+ files
  7. Unit tests - Auth, validation, happy path, error handling
  8. Verify - Typecheck, lint, all tests pass

Validating Against Production Data

Before removing "legacy" format handling:

  1. Query production to verify zero records in old format
  2. Check if writers still produce old format - recent records matter more than count
  3. If old format still being written - fix the writer first, then remove reader fallbacks
-- Example: verify no legacy format data exists
SELECT COUNT(*) FROM records
WHERE data IS NOT NULL
  AND data != '{}'::jsonb
  AND jsonb_typeof(data) = 'object';
-- Must return 0 before removing object-format handling

Common Mistakes

MistakeFix
Splitting a god file without checking for parallel systemsDetect gold-standard equivalents before any refactoring
Using as any to "fix" JSONB typesUse type guards or as Record<string, unknown>
Removing "legacy" handling without checking production dataRun verification queries - data may still exist
Adding tracing without updating existing testsTests need mock for tracing wrapper
Moving search from in-memory to DB without fixing paginationIn-memory search after pagination misses results on other pages

Related Skills

webhook

SOLID Webhook Architecture

Enforce SOLID principles in webhook architecture for maintainability and extensibility. Use when creating webhook routes, adding event handlers, building handler registries, or refactoring webhook code. Enforces registry pattern, single responsibility, and dependency injection.

Backend / Infrastructure
heart-pulse

Cron Monitor Check-Ins

A cron monitor is only as real as the check-ins that feed it. Vercel's Sentry integration auto-registers a monitor per cron that EXPECTS check-ins; if the route never calls captureCheckIn, the monitor reports "missed check-in" on every tick forever — a permanent phantom outage that trains your team to ignore alerts. Use when adding/auditing any scheduled job (Vercel cron, GitHub Action schedule, k8s CronJob) wired to a heartbeat monitor (Sentry Crons, Cronitor, Healthchecks.io, Better Stack).

Backend / Infrastructure
fingerprint

Dedup Key Completeness

A de-duplication, idempotency, or uniqueness guard must key on every dimension that makes two records legitimately distinct. A missing dimension silently collapses separate records into one (a lost write with no error). Use when writing an upsert, an onConflict target, a unique constraint, a "have we seen this already?" time window, or any "skip if it exists" guard — and when a bug report says "my second booking/order/ticket disappeared or merged into the first."

Backend / Infrastructure
←Back to Agent Skills