static analysis · orm patterns · zero runtime

Catch silent AI-shenanigans before they hit production.

You ship fast with AI. Your database quietly pays for it. queryaware scans your codebase and finds the expensive query mistakes — before your users do.

↗ view on npm see how it works →
~ queryaware scan
$ npx @catisho/queryaware scan ./src
queryaware scanning ./src...
• static detector: running
• call-graph tracer: running
scan complete in 1197ms
queryaware scan results
──────────────────────────────────────
18 issues in 3 files · High: 12 Medium: 6
src/maintenance/maintenance.service.ts (4)
✖ Unsafe raw query :17 $executeRawUnsafe() [High]
Impact: SQL injection risk — user input reaches DB unescaped
Fix: use $queryRaw/$executeRaw with Prisma.sql bound variables
...
──────────────────────────────────────
✖ 18 issues found High: 12 Medium: 6
queryaware path analysis
──────────────────────────────────────
routes traced: 144 • DB access: 75 files
top ops: prisma.sql.$executeRawUnsafe, prisma.sql.$queryRaw, prisma.user.findMany
run with --verbose to see full file list and call paths

The Problem

AI writes code fast.
It doesn't know your DB
has 50,000 rows.

It'll generate this pattern without blinking — and your app will crawl under real traffic.

✖ what AI writes
const files = await prisma.file
  .findMany();

for (const file of files) {
  // 1 DB call per file 😬
  const owner = await
    prisma.user.findUnique({
      where: { id: file.ownerId }
    });
}

// 20 files  → 21 queries
// 1000 files → 1001 queries
✔ what it should be
const files = await prisma.file
  .findMany();

const ids = files.map(f => f.ownerId);

// 1 call for all owners ✓
const owners = await
  prisma.user.findMany({
    where: { id: { in: ids } }
  });

// always 2 queries. always.

Detection Rules

Eight patterns.
All silent. All expensive.

Now includes cross-file signal quality via call-graph tracing and raw-query safety checks.

// 01 · N+1
N+1 Queries

Detects Prisma calls inside loops. One query becomes N queries. Scales linearly with your data. Silent until it isn't.

High Severity
// 02 · UNSCOPED
Unscoped findMany

Flags findMany with no where clause. Full table scans and potential data leaks in multi-tenant setups. A security and performance risk in one.

High Severity
// 03 · WRITES
Sequential Writes

Catches create, upsert, and update calls inside loops. N writes where one transaction would do. Kills throughput under load.

Medium Severity
// 04 · RAW UNSAFE
Unsafe Raw Query

Flags $queryRawUnsafe and $executeRawUnsafe usage where input handling can introduce injection risk.

High Severity
// 05 · FRAG INJECT
Prisma.raw Fragment Injection

Detects risky Prisma.raw() fragment composition patterns that can bypass safe parameterization boundaries.

High Severity
// 06 · SELECT *
Raw SELECT *

Catches wildcard column fetches in raw SQL that over-read data and increase payload, CPU, and query cost.

Medium Severity
// 07 · DELETE
Raw DELETE without WHERE

Flags unbounded DELETE statements in raw SQL before they can wipe entire tables by mistake.

High Severity
// 08 · UPDATE
Raw UPDATE without WHERE

Flags unbounded UPDATE statements in raw SQL that can mass-modify rows and create production incidents.

High Severity

Framework Coverage

One matcher model.
Multiple framework families.

queryaware normalizes all supported route styles into one route-entry model, then traces call graphs across layers.


Get Started

One command.
No config. No runtime.

Pure static analysis. Prisma support is live today. Additional ORM adapters are in active development.

install
npm install --save-dev @catisho/queryaware
scan
npx @catisho/queryaware scan ./src
pre-commit
npx @catisho/queryaware scan ./src # .husky/pre-commit

"I found 17 of these patterns in my own production codebase. I built queryaware so you don't have to find them the hard way."
— Faizan · builder of Tawtheeq
Roadmap · v0.2.0

Beyond call graphs.
Next depth layer.

Call-graph support is now shipped. Next focus: broader framework adapters, richer SQL analysis, and stronger risk scoring.

01
Expanded Route Adapters

Nuxt/Nitro, Remix loaders/actions, and tRPC procedures so route discovery covers more real-world Node and TypeScript stacks.

02
Raw SQL Detection

Catches anti-patterns inside Prisma.sql tagged templates — missing WHERE, SELECT *, and unsafe interpolation in raw queries.

03
Security Scanning

Flags $queryRawUnsafe with string interpolation. Detects injection risks before they reach your production database.

04
More ORM Adapters

Drizzle, TypeORM, Sequelize. Same detection engine, pluggable adapters. Built ORM-agnostic from day one.


Your codebase has problems it doesn't know about yet.

Run queryaware and find out. 10 seconds to scan.
The fix might save you hours of debugging at 2am.

↗ view on npm
free · open source · no sign-up
Coming Soon

More API surfaces.
Same route-entry model.

Planned matcher coverage and entrypoint models currently in backlog.

Nuxt 3 / Nitro server routes Remix loaders/actions tRPC procedures as virtual routes AdonisJS route matchers Hono & Edge runtime routers Bare http/custom dispatchers Queue/worker entrypoints GraphQL resolver-level fanout