Code Review Inbox

Read-only snapshot across 4 repo(s) · generated 2026-09-14T18:32:13.926Z · low-risk PRs with no critical finding are already auto-reviewed and auto-merged, nothing to do there

Repos (4)
RepoNeeds reviewMerge pendingAuto-mergedTotal tracked
qualogy-solutions/jira-ticket-analysis 0 0 1 2
qualogy-solutions/qualogy-scraper 0 0 0 0
qualogy-solutions/qualogy-websites 1 2 0 3
qualogy-solutions/sales-insights-dashboard 0 0 0 0

🔺 Needs your review — across all repos (1)

QRAD-51: Security & performance audit hardening
qualogy-solutions/qualogy-websites · #24 by Prijanka Ramcharan · QRAD-51 → main · Open in Bitbucket →
high

This PR adds a new Content-Security-Policy and other security headers globally via next.config.ts, and changes the rate-limiter API contract (limiter.check now returns an object with .success instead of a boolean) across all public-facing form/API routes (contact, apply, meeting, quote, coffee-call, ATS). If the CSP is too strict or misconfigured, it can silently break scripts, styles, images, or third-party integrations (GTM, Cookiebot, Turnstile, Supabase, Vercel Analytics) site-wide. If the rate-limiter contract change is inconsistent anywhere, requests could be incorrectly blocked or rate limiting could silently no-op, affecting all public lead-gen/application endpoints.

  • Adds global security headers (CSP, HSTS, X-Frame-Options, Permissions-Policy) in next.config.ts affecting every route/page site-wide
  • Changes the rate-limiter's public contract (boolean -> {success}) and updates call sites across 6+ public API routes (contact, apply/ats, apply/hardcoded, meeting, coffee-call, quote) - security-relevant logic touching abuse/spam protection
  • CSP misconfiguration is a classic source of silent breakage for scripts/analytics/embeds (GTM, Cookiebot, Turnstile, YouTube, Supabase) that is easy to miss in review/testing
  • Adds new third-party dependency (@vercel/speed-insights) and lockfile changes across the monorepo
  • Touches multiple independent public-facing API routes simultaneously, increasing scope of potential regression
  • New logging utility (logEvent) replacing console.error across routes - low risk itself but part of a broad, cross-cutting change
  • Large number of files changed (27) spanning config, API routes, new package module, and binary asset updates, increasing chance of an overlooked interaction

Overall a solid, low-risk hardening PR: adds structured logging via a shared logger, CSP/security headers, and Vercel Speed Insights. One notable inconsistency in apply/ats/route.ts where the rate limiter API usage differs from all sibling routes — worth confirming createRateLimiter's actual return type before merge. A few other minor points below.

apps/qualogy-web/app/api/apply/ats/route.ts:12 · warning
This route now calls `await limiter.check(ip)` and checks `.success`, while every other route in this PR (contact, meeting, coffee-call, ai-oplossingen, ai-trainingen, apply/hardcoded) still uses `if (!limiter.check(ip))` (presumably synchronous boolean). Confirm which is the actual current signature of `createRateLimiter().check` — if it's synchronous returning a boolean, this route will incorrectly await a boolean and access `.success` on it (always undefined, so `!rateLimit.success` is always true, blocking every request with a 429). If the API was changed to return a Promise<{success}> only here, the other six routes are now broken instead. This needs to be verified/fixed for correctness.
apps/qualogy-web/next.config.ts:37 · info
`script-src` includes `'unsafe-inline'`, which significantly weakens the CSP's XSS protection (allows inline <script> execution). This is likely needed for GTM/Cookiebot inline snippets, but consider using nonces or hashes for the known inline scripts (e.g. the GTM snippet in layout.tsx) instead of blanket 'unsafe-inline' if feasible in a future iteration.
packages/security/src/logger.ts:16 · info
logEvent logs error messages/meta as-is; callers pass `meta: { error: String(error) } }` which could include stack traces or potentially sensitive data (e.g., request payload details) if errors are constructed with such info. Worth double-checking that no PII/secrets end up in these log lines, since Vercel logs may be retained/searchable.