Code Review Inbox

Read-only snapshot across 4 repo(s) · generated 2026-09-30T06:49:10.884Z · 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 2 6
qualogy-solutions/qualogy-scraper 0 0 0 2
qualogy-solutions/qualogy-websites 1 0 4 10
qualogy-solutions/sales-insights-dashboard 1 0 0 1

🔺 Needs your review — across all repos (2)

QRAD-287: mobile UI fixes across onze-cases, diensten, homepage and other pages
qualogy-solutions/qualogy-websites · #33 by Prijanka Ramcharan · QRAD-287 → main · Open in Bitbucket →
medium

Large sprawling PR (146 files, ~2400 lines changed) touching almost every marketing/content page and shared component (hero sections, cases pages, homepage, footer, nav) for mobile UI fixes. No backend, auth, payments, or schema changes are involved, but the sheer breadth means a CSS/layout regression or a broken import (e.g. PullQuote component usage across dozens of files) could visually break many public-facing pages simultaneously.

  • <item>146 files changed across nearly all onze-cases pages, homepage, diensten, footer, nav, and shared UI components — very wide surface area</item> <item>Repeated structural changes (hero markup, spacing, new PullQuote component, image markup) applied consistently across many pages, increasing risk of a systemic layout bug affecting the whole site</item> <item>Includes a new client-side search/filter behavior (FilterWrapper using useSearchParams) which changes interactive behavior, not just styling</item> <item>Purely front-end/UI/content changes — no auth, database, payments, infra, or security-sensitive code touched, which caps this below 'high'</item> <item>Given the scale and cross-cutting nature of the diff, visual regressions could be broad even if each individual change is low-risk, warranting careful review rather than auto-approval</item> </reasons>

Large mechanical mobile-responsiveness PR touching mostly Tailwind classes, hero section layout, and refactoring inline quote blocks into a shared PullQuote component. The diff is very large but repetitive/low-risk in nature (styling adjustments, spacing, hero restructuring). I spotted a couple of correctness concerns worth a second look, but nothing that clearly breaks functionality; flagging as warnings rather than blocking issues, with one moderate one around the mainImage duplicate-check heuristic potentially hiding legitimate images.

apps/qualogy-web/app/[locale]/onze-cases/15-jaar-innovatie-bij-de-bekendste-supermarktketen-van-nederland/page.tsx:121 · warning
The intro image is now conditionally rendered only if `data.intro.mainImage !== data.hero.image`. If mainImage is intentionally the same as the hero image for design reasons (e.g. showing it twice), this will silently drop it. Consider a more explicit flag in the data model rather than an equality heuristic to control whether the intro image is shown.
apps/qualogy-web/app/[locale]/onze-cases/25-jaar-qualogy-tims-reis/page.tsx:55 · info
Hardcoded image path was replaced with `data.article.heroImage`, and the standalone hero image section above was removed. Double check `data.article.heroImage` renders correctly at the new aspect ratio/height (h-[320px] sm:h-[420px] md:h-[480px]) since the image was previously sized dynamically via width=0/height=0/sizes=100vw for full responsiveness; now it's fixed height with object-cover, which may crop differently across breakpoints. Worth a visual check across locales/images site-wide given this same fixed height/crop pattern is applied broadly for this refactor.
apps/qualogy-web/app/[locale]/onze-cases/de-gemeente-schiedam-verstrekt-rvv/page.tsx:74 · info
Two `bg-gradient-to-*` utility classes are combined on the same div (`bg-gradient-to-b ... bg-gradient-to-r ...`); only the last one wins in Tailwind since they set the same CSS property. This pattern repeats in several other files in this PR. Not a functional break, but likely unintended (probably meant to combine into a single diagonal gradient or accept that only one applies) — worth clarifying intent since it's copy-pasted across many hero sections and may confuse future maintainers about which gradient is actually applied of the two directions and stop color sets specified redundantly here (though it does not error, it makes the extra gradient in the class list dead code).
feat: replace Dupliceren with manual duplicate sets (QRAD-291)
qualogy-solutions/sales-insights-dashboard · #6 by Prijanka Ramcharan · QRA-291 → main · Open in Bitbucket →
medium

Replaces the "Dupliceren" (clone) feature with a manual duplicate-set linking mechanism, changing business logic and data flow for assignments (archiving/unlinking via is_active, superseded_by, alert_new_duplicate columns). Affects the Aanvragen list, detail pane, and pipeline view across the whole assignment workflow used by Sales, and reuses shared columns that also drive existing supersession/alert UI, so a bug could mis-archive or mis-link real aanvraag records.

  • Removes an existing feature (duplicateAssignment) and replaces with new bulk mutation logic touching shared DB columns (is_active, superseded_by, archived_at) used elsewhere in the app
  • Moderate-large diff (627+/329-) spanning 10 files including services, hooks, and multiple UI components
  • Business logic change affecting core Aanvragen workflow (archiving, unlinking, duplicate detection) with direct writes to production data via Supabase
  • Good test coverage included for new service functions, which reduces but doesn't eliminate risk
  • No schema migration or auth changes, keeping it out of 'high' territory, but affects a widely-used feature across list, detail, and pipeline views

Solid, well-documented change that replaces the "Dupliceren" clone feature with a manual duplicate-set linking mechanism, reusing existing supersession columns. Logic looks consistent with tests covering the new service functions. A few edge cases worth flagging, none blocking.

src/services/assignmentsService.ts:1534 · warning
markAssignmentsAsDuplicateSet does not validate that duplicateIds is non-empty. If called with an empty array, .in("id", []) will run an update with an empty match set; depending on the Supabase/PostgREST behavior this could be a no-op or could error, but it's worth guarding explicitly (and DuplicateSetDialog already prevents this via UI, but the service function itself is a public API used elsewhere).
src/services/assignmentsService.ts:1534 · warning
No transaction/atomicity between reading the primary's email_id and updating the duplicate rows. If another process changes the primary's email_id or deletes it between the two calls, the update could link duplicates to a stale/incorrect email_id. Low risk given single-user admin usage, but worth noting since this directly affects data integrity of the duplicate-set relationship.
src/components/aanvragen/AanvraagDuplicaten.tsx:68 · info
useLinkedDuplicateAssignments is called unconditionally on every aanvraag row rendered (e.g. in list contexts via useHasAanvraagDuplicaten), each with its own query key. This is fine functionally (react-query dedupes/caches), but for large lists this could mean many parallel network requests fired on mount when many rows want to know if they have duplicates. Worth confirming this scales for typical list sizes in Aanvragen.tsx and AssignmentPipelineView.tsx.
src/pages/Aanvragen.tsx:559 · info
selectedAssignments is recomputed via a filter on every render without memoization; fine given typical selection sizes, but could be wrapped in useMemo for consistency with other derived selectors in this file.
src/components/aanvragen/DuplicateSetDialog.tsx:63 · info
matches.length === 1 auto-selects a preferred broker as primary, but if the preferred-brokers query is still loading when the dialog opens (matches computed from empty preferredNames), primaryId will briefly be null then update once data resolves via the effect — this is handled by the effect re-running on `matches` change, but there's a brief flash where no broker looks preselected even when the query will eventually resolve to exactly one match. Not a bug, just a minor UX note.