req/res usage, direct instantiation of low‑level resources, etc.) and produces a structured report with severity ratings and concrete remediation snippets you can drop into the codebase.
Below are the command context used while running the audit, trimmed audit prompt, a concise overview of the SOLID principles, a summary of how the audit checks each principle, an executive summary of the audit results, and targeted, code-level remediation examples that make the fixes incremental and testable.
Command context shown while running the audit:
Overview — SOLID principles (concise)
How the audit checks each principle (summary)
- SRP: Detects functions or files doing multiple distinct tasks (validation, DB access, encryption, token creation, response shaping).
- OCP: Flags switch/if chains and centralized conditionals that must change to add features.
- LSP: Looks for concrete
new/require usage inside higher-level modules (routes/services), blocking substitutability. - ISP: Finds handlers that accept whole Express
req/resobjects while using only a subset of fields. - DIP: Scans for direct instantiation and
process.envuse inside business logic rather than injected config/abstractions.
Executive summary
- Application: Express Login Demo
- Overall SOLID Compliance Score: 4/10
- Main issues found:
- Monolithic route handlers that combine validation, DB calls, crypto, and token creation.
- Hardcoded dependencies: DB client, crypto libs, JWT usage, and
process.envreads embedded in logic. - Lack of clear abstraction layers (repository pattern, service interfaces).
- Fat
req/resusage making handlers tightly coupled to Express.
- Priority remediation: Extract auth service, introduce repository abstractions, centralize configuration, and create pluggable auth strategies.
Detailed findings and concrete remediation
- Single Responsibility Principle (SRP)
- Violation: Monolithic auth route handler performing validation, DB access, password checks, JWT generation, and response formatting.
- Location:
routes/auth.js(e.g.,/loginroute, lines ~17–96) - Severity: HIGH (9/10)
- Why: Multiple concerns are combined into a single function, increasing fragility and reducing testability.
- Open/Closed Principle (OCP)
- Violation: Error handling via switch statements or centralized if chains that require editing core logic to add new error types.
- Severity: MEDIUM–HIGH (7/10)
errorHandlers instead of editing control flow.
- Liskov Substitution Principle (LSP)
- Violation: Direct instantiation of DB pool inside route modules prevents substituting mocks or alternative implementations.
- Location example:
routes/auth.jscontainsconst pool = require('../config/database'); - Severity: MEDIUM (6/10)
PostgresUserRepository in production; tests can inject a MockUserRepository.
- Interface Segregation Principle (ISP)
- Violation: Route handlers depend on full Express
req/resobjects, though only a few fields are used. - Severity: MEDIUM (6/10)
- Dependency Inversion Principle (DIP)
- Violation: High-level auth logic depends on low-level modules (DB pool,
bcrypt,jsonwebtoken,process.env), making swapping implementations or mocking in tests difficult. - Location examples:
routes/auth.jsimporting DB connection; services directly requiringbcryptorjsonwebtoken; business logic readingprocess.env.JWT_SECRET. - Severity: CRITICAL (10/10) for direct DB dependency; HIGH for env/crypto dependency.
authService or controllers rather than requiring them directly inside business logic.
Example controller wiring:
Priority remediation plan (phased, practical)
Code quality metrics observed (examples)
- Cyclomatic complexity: High (login function had 8+ decision points).
- Lines per function: Large (login function ~79 lines).
- Coupling: High (routes directly require DB, crypto, jwt).
- Testability: Poor (no DI; direct env and DB usage).
Run the SOLID audit early and often. Make controllers/routes thin and move logic into services that accept injected collaborators (repositories, crypto, jwt, config). This maximizes testability and extensibility while yielding quick return on refactoring efforts.
- The audit tool generated a markdown report (example above) and suggested an architecture:
controllers/authController.js(thin routing layer)services/authService.js,jwtService.js,configService.jsrepositories/userRepository.js(+ concrete DB implementations)strategies/authStrategies.jsmiddleware/validation.js,middleware/errorHandler.js

- Extract login logic into an
authServiceand injectuserRepositoryandjwtService. - Replace direct
process.envreads with aconfigServicethat can be overridden in tests. - Replace
require/newof DB/crypto in routes with injected abstractions. - Introduce small utility modules (
jwtService,cryptoService,errorHandlers) and wire them centrally in a startup file.
- The codebase has a working authentication flow but demonstrates strong coupling and several SOLID violations. Start with dependency inversion and single responsibility refactors: extract services, use repository abstractions, and centralize configuration. Those changes will immediately improve testability, reduce coupling, and make the codebase easier to extend without modifying core logic.