Skip to content

feat: [performance improvement]#258

Open
anyulled wants to merge 1 commit into
mainfrom
bolt/optimize-job-offers-9847621779134285792
Open

feat: [performance improvement]#258
anyulled wants to merge 1 commit into
mainfrom
bolt/optimize-job-offers-9847621779134285792

Conversation

@anyulled
Copy link
Copy Markdown
Owner

@anyulled anyulled commented Jun 3, 2026

💡 What: Replaced O(NM) nested loop (array .filter() inside .forEach()) with O(N) hash map lookup for processing job offers per sponsor.
🎯 Why: To prevent the application from slowing down when matching job offers to sponsors during data fetching.
📊 Impact: Improves time complexity of matching offers from O(N
M) to O(N+M), reducing memory allocation and improving server data parsing speed.
🔬 Measurement: Observe reduction in data parsing time for getJobOffersForEdition.


PR created automatically by Jules for task 9847621779134285792 started by @anyulled

Summary by CodeRabbit

  • Refactor
    • Internal optimizations for improved performance in job offer retrieval.

Replaced O(N*M) nested loop with an O(N) hash map lookup when matching job offers to sponsors.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
devbcn-nextjs Error Error Jun 3, 2026 8:28am

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 3, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

Single-file refactoring in getJobOffersForEdition that groups job offers by sponsor ID using a Map for faster lookup, replacing per-sponsor filtering logic while maintaining the same downstream behavior.

Changes

Offer grouping optimization

Layer / File(s) Summary
Offer grouping via Map lookup
lib/supabase/public-queries.ts
The function builds offersBySponsor Map by iterating offers once and grouping by sponsor ID, then retrieves each sponsor's offers via offersBySponsor.get(sponsor.id) instead of repeated offers?.filter(...) calls.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Suggested labels

size/XXL

Poem

A rabbit hops through sponsor maps so bright,
Grouping offers once instead of per-light.
No filtering thrice, just lookups so fleet—
Performance and clarity, both neat and sweet! 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title uses vague, generic phrasing with '[performance improvement]' that doesn't clearly specify what was actually improved or which component was changed. It lacks specific details about the refactoring to use a hash map instead of nested filtering. Replace the generic '[performance improvement]' with a specific description like 'Use Map for job offers lookup instead of repeated filtering' to clearly convey the actual change made.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bolt/optimize-job-offers-9847621779134285792

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed: dependency version conflict. Check your lock file or package.json.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Optimize job offer matching with hash map lookup

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Replaced O(N*M) nested loop with O(N) hash map lookup
• Optimizes job offer matching to sponsors during data fetching
• Reduces time complexity from O(N*M) to O(N+M)
• Improves server data parsing performance for getJobOffersForEdition
Diagram
flowchart LR
  A["Fetch offers and sponsors"] --> B["Build hash map by sponsor_id"]
  B --> C["O(N) hash map lookup"]
  C --> D["Match offers to sponsors"]
  D --> E["Improved performance"]

Loading

Grey Divider

File Changes

1. lib/supabase/public-queries.ts Performance optimization +11/-1

Replace nested filter loop with hash map lookup

• Created offersBySponsor Map to group offers by sponsor_id in O(N) time
• Replaced .filter() call inside .forEach() with direct Map lookup
• Eliminates nested loop iteration over offers for each sponsor
• Maintains same functionality with improved time complexity

lib/supabase/public-queries.ts


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented Jun 3, 2026

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 🔗 Cross-repo conflicts (0)

Context used
✅ Compliance rules (platform): 11 rules

Grey Divider


Advisory comments

1. Loose Map value type 🐞 Bug ⚙ Maintainability
Description
offersBySponsor is typed as Map<string, typeof offers>, which (given Supabase data
conventions) can include null, even though the Map is only ever populated with arrays. This
weakens type-safety and makes future refactors riskier because get() can legally return null by
type even though downstream code treats values as arrays.
Code

lib/supabase/public-queries.ts[179]

Evidence
The Map is declared with typeof offers even though it is populated only with arrays ([o] and
existing.push(o)), and later consumed as an array (.length, .map). Supabase query data is
treated as nullable in this function (offers?.forEach), which is why typeof offers can include
null.

lib/supabase/public-queries.ts[165-200]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`offersBySponsor` is declared as `new Map<string, typeof offers>()`, but `offers` (Supabase `data`) is commonly typed as `T[] | null`. The Map never stores `null`, only arrays, so the current type is unnecessarily permissive and reduces type-safety.

### Issue Context
In `getJobOffersForEdition`, Map values are constructed via `[o]` and `existing.push(o)` (always arrays), and later read as arrays (`length`, `map`).

### Fix Focus Areas
- lib/supabase/public-queries.ts[179-190]

### Suggested fix
- Change the Map value type to exclude null/undefined, e.g.:
 - `const offersBySponsor = new Map<string, NonNullable<typeof offers>>();`
 - Or define a row type and use `Map<string, JobOfferRow[]>`.
- Optionally iterate with `for (const o of offers ?? [])` to avoid optional chaining and clarify the null-handling.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request optimizes the getJobOffersForEdition function by grouping job offers by sponsor ID using a Map before iterating over sponsors, improving performance from O(N * M) to O(N + M). The reviewer suggested typing the offersBySponsor map with NonNullable<typeof offers> instead of typeof offers to prevent null from being included in the map's value type, ensuring better type safety.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.


const companies: Company[] = [];

const offersBySponsor = new Map<string, typeof offers>();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The map offersBySponsor is typed using typeof offers, which includes null (since offers can be null if the query fails or returns no data). Since the map only stores actual arrays of offers and never null, typing it with typeof offers is semantically incorrect and can lead to unnecessary null-safety checks or potential compiler errors under strict null checking if the code is refactored.

Using NonNullable<typeof offers> ensures the map's value type is strictly the array type (e.g., JobOffer[]) without null.

Suggested change
const offersBySponsor = new Map<string, typeof offers>();
const offersBySponsor = new Map<string, NonNullable<typeof offers>>();

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
lib/supabase/public-queries.ts (1)

179-179: ⚡ Quick win

Make the Map type more explicit and self-documenting.

Using typeof offers for the Map value type is imprecise and not self-documenting. The offers variable includes null in its type union, but Map values are always non-nullable arrays. This obscures the intent and makes the code harder to understand.

As per coding guidelines, code must be self-documenting, and the guideline states to use strict TypeScript.

♻️ Proposed refactor for clearer typing
-  const offersBySponsor = new Map<string, typeof offers>();
+  const offersBySponsor = new Map<string, Array<NonNullable<typeof offers>[number]>>();

Or, better yet, if the offer type can be extracted:

-  const offersBySponsor = new Map<string, typeof offers>();
+  // Let TypeScript infer from usage, or define explicit type
+  const offersBySponsor = new Map<string, typeof offers extends Array<infer T> ? T[] : never>();

Or simplest, let TypeScript infer the value type from the .set() calls by omitting the type argument entirely:

-  const offersBySponsor = new Map<string, typeof offers>();
+  const offersBySponsor = new Map<string, Array<Exclude<typeof offers, null>[number]>>();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/supabase/public-queries.ts` at line 179, The Map declaration uses typeof
offers which is vague and includes null; update offersBySponsor to use an
explicit, non-nullable array type (or let TypeScript infer it) so values are
always Offer[] (or the concrete item type) rather than typeof offers. Locate the
offersBySponsor and offers symbols in this file and replace the Map<string,
typeof offers> typing with a clear Map<string, Offer[]> (or simply remove the
generic to let inference pick it up), and ensure any places that call .set() no
longer pass null by adjusting logic where offers can be null.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@lib/supabase/public-queries.ts`:
- Line 179: The Map declaration uses typeof offers which is vague and includes
null; update offersBySponsor to use an explicit, non-nullable array type (or let
TypeScript infer it) so values are always Offer[] (or the concrete item type)
rather than typeof offers. Locate the offersBySponsor and offers symbols in this
file and replace the Map<string, typeof offers> typing with a clear Map<string,
Offer[]> (or simply remove the generic to let inference pick it up), and ensure
any places that call .set() no longer pass null by adjusting logic where offers
can be null.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5368d2c5-4254-409d-bd79-5d33764c9cd2

📥 Commits

Reviewing files that changed from the base of the PR and between 0307ff3 and be7ca92.

📒 Files selected for processing (1)
  • lib/supabase/public-queries.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant