| Critical | .env:4:35 | Database connection string with password committed to source code |
| Critical | app/api/login/route.ts:21:18 | Passwords hashed with MD5 |
| Critical | app/api/login/route.ts:44:24 | JWT decoded without verifying its signature |
| Critical | lib/server.ts:14:5 | Shell command built by string interpolation in exec() |
| Critical | .env:9:1 | Secret exposed to the browser via NEXT_PUBLIC_ prefix: NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY |
| Critical | components/OrderCard.tsx:10:27 | Secret exposed to the browser via NEXT_PUBLIC_ prefix: NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY |
| Critical | components/OrderCard.tsx:10:27 | Server-only secret "NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY" referenced from a client component |
| High | lib/server.ts:8:3 | CORS allows any origin together with credentials |
| High | app/api/login/route.ts | No rate limiting found on 1 authentication-related endpoint |
| High | app/api/login/route.ts:14:23 | POST() reads request data without validating it |
| High | app/api/login/route.ts:28:31 | Math.random() used to generate a security-sensitive value |
| High | app/api/orders/[id]/route.ts:16:3 | SQL query built by string interpolation |
| High | app/api/orders/[id]/route.ts:24:23 | DELETE() modifies data without an authorization check |
| High | app/api/orders/[id]/route.ts:31:23 | PUT() reads request data without validating it |
| High | app/api/orders/[id]/route.ts:31:23 | PUT() modifies data without an authorization check |
| High | components/OrderCard.tsx:6 | Database client imported into 1 client-side file |
| High | lib/orders.ts:36:33 | Database query inside a for...of loop (N+1 query pattern) |
| High | lib/orders.ts:37:31 | Database query inside a for...of loop (N+1 query pattern) |
| Medium | Dockerfile:2 | Dockerfile runs the container as root |
| Medium | lib/orders.ts:13:23 | processOrderAndNotifyAndRender() has 2 maintainability problems at once |
| Medium | package.json | No test files found across 10 source files |
| Medium | app/api/login/route.ts:35:5 | Raw error details returned to the client in 3 places |
| Medium | app/api/login/route.ts:39:23 | GET() reads request data without validating it |
| Medium | app/api/orders/[id]/route.ts:12:23 | GET() reads request data without validating it |
| Medium | app/api/orders/[id]/route.ts:12:23 | GET() accesses data without an authorization check |
| Medium | app/api/orders/[id]/route.ts:12:23 | GET() has no error handling around its awaited calls |
| Medium | app/api/orders/[id]/route.ts:19:25 | Query returns every matching row with no limit |
| Medium | app/api/orders/[id]/route.ts:24:23 | DELETE() has no error handling around its awaited calls |
| Medium | app/api/orders/[id]/route.ts:31:23 | PUT() has no error handling around its awaited calls |
| Medium | lib/notifications.ts:14:21 | 2 of 2 server-side fetch() calls have no timeout |
| Medium | lib/orders.ts:31:35 | Query returns every matching row with no limit |
| Medium | lib/orders.ts:78 | formatCurrencyAmount() and displayMoney() appear to be two implementations of the same thing |
| Medium | lib/reports.ts:9:24 | Query returns every matching row with no limit |
| Medium | next.config.js | No security response headers are configured |
| Medium | components/OrderCard.tsx:18:12 | Unsanitised value rendered with dangerouslySetInnerHTML |
| Medium | prisma/schema.prisma | 2 fields filtered in queries but not indexed |
| Low | .env.example | No .env.example, but the code requires 1 environment variable |
| Low | Dockerfile:2:1 | Base image "node:latest" is not pinned to a version |
| Low | lib/utils.ts:23:3 | 4 unfinished-work markers across the codebase |
| Low | package.json | 2 different libraries are used for HTTP requests |
| Low | package.json | 2 different libraries are used for date handling |
| Low | README.md | No README file |
| Low | package.json | 1 declared dependency appears to be unused |