Skip to content

feat(events-crawler): per-source adapters + BiblioCommons (Vancouver PL) - #84

Merged
ltanafranca1004 merged 2 commits into
mainfrom
feat/events-crawler-adapters
Jul 31, 2026
Merged

feat(events-crawler): per-source adapters + BiblioCommons (Vancouver PL)#84
ltanafranca1004 merged 2 commits into
mainfrom
feat/events-crawler-adapters

Conversation

@ltanafranca1004

@ltanafranca1004 ltanafranca1004 commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

What & why

Second of four Phase-2 PRs. Splits the 735-line single-file crawler into a source registry, shared helpers and per-source adapters, then lands the second adapter (BiblioCommons → Vancouver Public Library) on top of it.

The Tribe extraction is verbatim — same fetch shape, same mapping, same three image tiers — so the five live orgs are unaffected. Verified by dry-running every source and comparing row counts:

source rows
mosaic 25 cap
burnaby-nh 24
success 14
centre-canada 0 expected — empty upcoming calendar, documented in the registry
pirs 2
westvan-library 5 disabled, relevance-filtered
vpl 25 disabled, 25 of 112 in-window-and-relevant

🛑 The Burnaby catch — why BPL is not in this PR

The plan called for VPL and Burnaby PL. Burnaby is deliberately absent, and the dry-run harness is the reason it was caught before merge rather than after deploy:

bpl on BiblioCommons is BOSTON Public Library. It returns a completely healthy feed — "Cover Letter 101", "Citizenship Exam Prep Class", "Legal Clinic for Immigration Assistance with Rian Immigrant Center", at "Central Library in Copley Square". Every one of those is topically perfect for a newcomer app and geographically useless in Metro Vancouver, and nothing in a log would have looked wrong.

Burnaby's real tenant is burnaby, which answers "The Events feature is not available at Burnaby Public Library". Its own bpl.bc.ca/events page is a client-rendered SPA with nothing server-side to read. Burnaby PL cannot be crawled by any approach in this plan and is dropped from scope; the adapter now carries a caution about tenant slugs and index.ts records why it's absent.

Decisions baked in

Full pagination, client-side sort. BiblioCommons supports no date filtering and no sorting — startDate, endDate, from/to, start/end, minDate, after, dateRange, sort, sortBy are all silently ignored (count stays at the full catalog size), the order is arbitrary, and limit caps at 100. So "the soonest 25 in the window" isn't expressible as a query: the adapter pages the whole catalog (VPL 1,997 events / 20 pages, 4 concurrent), filters and sorts client-side, then caps. Taking only the first few pages would be far cheaper but would yield an arbitrary subset with no way to tell from the result. A MAX_PAGES backstop bounds catalog growth and logs when it truncates, so a partial crawl never reads as a complete one.

Images resolve only for the final 25. The three-tier resolver does a HEAD probe per image; probing every candidate would dominate the run. BiblioCommons featuredImages tagged EventType are shared category placeholders (the same activities-and-games.png across dozens of unrelated events), so those are skipped in favour of a topic-matched Pexels photo.

Relevance filter (lib/relevance.ts) — grouped keyword terms, matched against the accent-folded title only. Folding is load-bearing: Surrey publishes "WorkBC Résumé Clinic" and NVDPL "Tech Café", neither of which matches a plain ASCII term. Descriptions are deliberately not matched — library blurbs routinely close with "newcomer families welcome", which pulls in every storytime. The five settlement agencies are never filtered.

// @ts-nocheck dropped from the crawler, so CI's deno check genuinely type-checks it. Confirmed the gate now bites: an injected const x: number = "str" fails TS2322 with exit 1, where the same probe previously exited 0.

Changes

  • supabase/functions/events-crawler/lib/constants, types, text, dates, images, genre, relevance.
  • supabase/functions/events-crawler/adapters/tribe.ts (extracted), bibliocommons.ts (new).
  • index.ts — registry + handler only; ADAPTERS is a Record<SourceKind, Adapter> so a new kind without an implementation is a compile error.
  • dryrun.ts — read-only preview harness. No write path and no --apply flag: it never imports or constructs a Supabase client. It imports the real adapter modules rather than copying their logic, so preview and production cannot drift.
  • next.config.ts — allowlist vpl.bibliocommons.com.

⚠️ Coordination

Nothing changes in production. New sources stay enabled: false; no migration, cron job, Vault secret or DB object was touched; the function was not deployed; no writes to shared prod. Activation needs both a deploy and an enabled flip, each gated on Savar's sign-off.

Verification

Check Result
deno check (incl. dryrun.ts) clean
deno check with injected type error fails TS2322, exit 1 — gate is real
npx tsc --noEmit clean
npx eslint next.config.ts clean
dryrun.ts × 7 sources counts in the table above
migrations/backfills guard empty

Run the harness yourself: deno run --allow-net --allow-env=PEXELS_API_KEY supabase/functions/events-crawler/dryrun.ts --source vpl

Reviewer notes

  • Known genre quirk, deliberately not fixed here: West Van's "Device Clinic" classifies as Health, because the shared GENRE_RULES Health pattern includes clinic. Correcting it would change classification for the five live orgs, which doesn't belong in this PR. Worth a follow-up; harmless meanwhile since West Van is disabled.
  • dryrun.ts duplicates the SOURCES literal because index.ts calls Deno.serve at module scope — importing it would start a server. Adding a source means adding it in both places; the harness's --list makes a drift obvious.
  • lib/dates.ts gains offsetIsoToUtc alongside toIsoUtc: BiblioCommons' indexStart carries a Z, and feeding an offset-bearing string to the offset-less parser would silently shift the time.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added event listings from BiblioCommons-powered library catalogs.
    • Added support for additional WordPress event calendars.
    • Events now include improved categories, descriptions, locations, links, and cover images.
    • Added relevance filtering to highlight settlement-related programs.
  • Improvements
    • Improved date and timezone handling for more accurate event windows.
    • Improved handling of cancelled, invalid, duplicate, and out-of-range events.
    • Event collection now continues gracefully when individual sources are unavailable.

Splits the 735-line single-file crawler into a source registry, shared helpers and
per-source adapters, then adds the second adapter. The Tribe extraction is verbatim —
same fetch shape, same mapping, same image tiers — so the five live orgs are unaffected;
verified by dry-running each and comparing row counts (mosaic 25, burnaby-nh 24,
success 14, centre-canada 0 as documented, pirs 2).

Layout:
  lib/{constants,types,text,dates,images,genre,relevance}.ts
  adapters/{tribe,bibliocommons}.ts
  index.ts  — registry + handler only
  dryrun.ts — read-only preview harness

BiblioCommons supports no date filtering and no sorting: startDate, endDate, from/to,
start/end, minDate, after, dateRange, sort and sortBy are all silently ignored, the
returned order is arbitrary, and `limit` caps at 100. "The soonest 25 events in the
window" therefore cannot be expressed as a query, so the adapter pages the whole catalog
(VPL: 1,997 events over 20 pages, 4 concurrent), filters and sorts client-side, then caps.
Images resolve only for the final 25 — probing thousands would dominate the run. A
MAX_PAGES backstop bounds a growing catalog and logs when it truncates, so a partial
crawl never looks complete.

Burnaby Public Library is NOT included, and the dry-run harness is why. `bpl` on
BiblioCommons is BOSTON Public Library: it returns a healthy feed of Copley Square,
Allston Brighton CDC and Rian Immigrant Center events that would have looked entirely
plausible in a log while putting Massachusetts events into a BC newcomer app. Burnaby's
real tenant is `burnaby`, which answers "The Events feature is not available", and
bpl.bc.ca/events is a client-rendered SPA with nothing server-side to read. The adapter
now carries a caution about tenant slugs, and index.ts records why Burnaby is absent.

Adds the settlement-relevance filter for library sources (lib/relevance.ts): grouped
keyword terms matched against the accent-folded title only. Accent folding is
load-bearing — Surrey publishes "WorkBC Résumé Clinic" and NVDPL "Tech Café", neither of
which matches a plain ASCII term. Descriptions are deliberately not matched: library
blurbs routinely end "newcomer families welcome", which pulls in every storytime. The
five settlement agencies are never filtered. Measured keep-rates: West Van 8/50,
VPL 112/1997 in-window-and-relevant.

Drops `// @ts-nocheck` from the crawler, so CI's `deno check` genuinely type-checks it.
Confirmed the gate now bites: an injected `const x: number = "str"` fails with TS2322
(exit 1), where previously it exited 0.

Everything new stays `enabled: false`. No migration, cron, or DB object touched; nothing
deployed; no writes to shared prod.

Verification:
  deno check (incl. dryrun.ts)  → clean
  npx tsc --noEmit              → clean
  npx eslint next.config.ts     → clean
  dryrun all 7 sources          → counts above; vpl 25 of 112 relevant
  git diff --name-only origin/main | grep -E 'migrations|backfills'  → empty

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
web-app Ready Ready Preview Jul 31, 2026 7:32pm

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ltanafranca1004, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 40 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: bc2f61b4-d6d5-472e-a36c-cc2feb9703c0

📥 Commits

Reviewing files that changed from the base of the PR and between f8da1b2 and 85be8c8.

📒 Files selected for processing (5)
  • supabase/functions/events-crawler/adapters/bibliocommons.ts
  • supabase/functions/events-crawler/adapters/tribe.ts
  • supabase/functions/events-crawler/dryrun.ts
  • supabase/functions/events-crawler/index.ts
  • supabase/functions/events-crawler/lib/sources.ts

Walkthrough

The events crawler now supports typed source adapters for Tribe and BiblioCommons. Shared modules provide date, text, genre, relevance, and image processing. The crawler shares run context across sources, and a dry-run harness previews adapter output without database writes.

Changes

Events crawler expansion

Layer / File(s) Summary
Shared crawler contracts and normalization
supabase/functions/events-crawler/lib/types.ts, lib/constants.ts, lib/dates.ts, lib/text.ts, lib/genre.ts, lib/relevance.ts
Adds typed source and event-row contracts, shared limits, timezone-aware date utilities, text normalization, genre classification, and settlement relevance filtering.
Shared cover-image resolution
supabase/functions/events-crawler/lib/images.ts
Adds source-image validation, cached Pexels lookup, and deterministic Unsplash fallback resolution.
Tribe adapter implementation
supabase/functions/events-crawler/adapters/tribe.ts
Adds bounded Tribe API fetching, event validation, filtering, venue mapping, description and address conversion, image resolution, and normalized row production.
BiblioCommons adapter implementation
supabase/functions/events-crawler/adapters/bibliocommons.ts
Adds paginated BiblioCommons fetching, entity resolution, event filtering, chronological sorting, result limits, and normalized row production.
Source registry and crawler execution
supabase/functions/events-crawler/index.ts, supabase/functions/events-crawler/dryrun.ts, next.config.ts
Replaces inline Tribe processing with source dispatch and shared run state. Adds the read-only preview harness and allowlists new crawler image hosts. Existing authorization and upsert behavior remains unchanged.

Estimated code review effort: 4 (Complex) | ~75 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 78.95% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: per-source crawler adapters and BiblioCommons support for Vancouver Public Library.
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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/events-crawler-adapters

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.

@ltanafranca1004

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
supabase/functions/events-crawler/lib/relevance.ts (1)

22-76: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add unit tests for the new shared crawler utilities. These five modules are pure functions with subtle, load-bearing edge-case logic (regex precedence, date-rollover math, entity decoding, deterministic hashing), and none of them ship with tests in this PR. A single silent regression in rule order or an off-by-one in date math would be hard to catch without dedicated coverage.

  • supabase/functions/events-crawler/lib/relevance.ts#L22-L76: add tests for isSettlementRelevant, covering accent-folded terms (e.g. "Résumé") and the documented exclusions (bare orientation, health, family, community).
  • supabase/functions/events-crawler/lib/genre.ts#L46-L67: add tests for genreForEvent asserting the documented rule-order dependencies (Employment before Language/Family, Housing's word-boundary against "Belkin House").
  • supabase/functions/events-crawler/lib/dates.ts#L37-L62: add tests for windowEndInTimezone, including the documented month-overflow case (Oct 31 + 4 months → Mar 3).
  • supabase/functions/events-crawler/lib/text.ts#L18-L93: add tests for decodeEntities's out-of-range numeric entities and isOnlineVenueName's whole-name-match behavior.
  • supabase/functions/events-crawler/lib/images.ts#L35-L67: add tests for hashStr/fallbackImage determinism and pexelsQueryForEvent's keyword-ordering.
🤖 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 `@supabase/functions/events-crawler/lib/relevance.ts` around lines 22 - 76, Add
unit coverage for the shared crawler utilities: in
supabase/functions/events-crawler/lib/relevance.ts:22-76, test
isSettlementRelevant with accent folding and exclusions for bare orientation,
health, family, and community; in
supabase/functions/events-crawler/lib/genre.ts:46-67, test genreForEvent rule
ordering and Housing’s boundary against “Belkin House”; in
supabase/functions/events-crawler/lib/dates.ts:37-62, test windowEndInTimezone
including October 31 plus four months rolling to March 3; in
supabase/functions/events-crawler/lib/text.ts:18-93, test out-of-range numeric
entity decoding and whole-name matching in isOnlineVenueName; and in
supabase/functions/events-crawler/lib/images.ts:35-67, test deterministic
hashStr/fallbackImage results and keyword ordering in pexelsQueryForEvent. Use
the repository’s existing test conventions and assert the documented edge-case
behavior.
🤖 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.

Inline comments:
In `@supabase/functions/events-crawler/adapters/bibliocommons.ts`:
- Around line 99-119: Update fetchEvents to track pages where fetchPage returns
null during pagination, incrementing the failure count for each failed page.
Include that count in the completion summary or emit a console.warn when
nonzero, while preserving the existing MAX_PAGES truncation reporting.
- Around line 134-136: Update the title handling in the event processing flow to
run the relevance check on the full cleaned value before applying
MAX_TITLE_CHARS truncation. Preserve the empty-title skip, then truncate the
accepted title for storage and keep the existing source.relevanceFilter and
isSettlementRelevant behavior.
- Around line 196-212: Deduplicate the accumulated candidates by event id before
sorting and applying MAX_PER_ORG in the catalog-fetch flow. Update the logic
after candidatesFromPage aggregation to retain only one candidate per id, then
sort and slice the deduplicated collection so duplicates cannot consume slots or
trigger repeated cover resolution.

In `@supabase/functions/events-crawler/adapters/tribe.ts`:
- Around line 162-165: Update the event-row aggregation around tribeEventToRow
to use Promise.allSettled instead of Promise.all, then retain only fulfilled
results whose values are non-null EventRow entries. Preserve the existing
MAX_PER_ORG limit and ensure a rejected per-event conversion is ignored without
causing fetchEvents to return an empty source-wide result.

In `@supabase/functions/events-crawler/dryrun.ts`:
- Around line 32-82: Extract the duplicated crawler wiring into side-effect-free
shared modules: create lib/sources.ts containing the SOURCES registry and
ADAPTERS map, and create a shared context factory for the AdapterContext
construction. In supabase/functions/events-crawler/dryrun.ts lines 32-82, remove
the local definitions and import the shared symbols; at lines 126-133, replace
the inline context literal with the factory. In
supabase/functions/events-crawler/index.ts lines 159-174, remove the duplicated
registry, adapter map, and context construction, importing and using the shared
definitions instead.

---

Outside diff comments:
In `@supabase/functions/events-crawler/lib/relevance.ts`:
- Around line 22-76: Add unit coverage for the shared crawler utilities: in
supabase/functions/events-crawler/lib/relevance.ts:22-76, test
isSettlementRelevant with accent folding and exclusions for bare orientation,
health, family, and community; in
supabase/functions/events-crawler/lib/genre.ts:46-67, test genreForEvent rule
ordering and Housing’s boundary against “Belkin House”; in
supabase/functions/events-crawler/lib/dates.ts:37-62, test windowEndInTimezone
including October 31 plus four months rolling to March 3; in
supabase/functions/events-crawler/lib/text.ts:18-93, test out-of-range numeric
entity decoding and whole-name matching in isOnlineVenueName; and in
supabase/functions/events-crawler/lib/images.ts:35-67, test deterministic
hashStr/fallbackImage results and keyword ordering in pexelsQueryForEvent. Use
the repository’s existing test conventions and assert the documented edge-case
behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c326baed-7cf0-436a-8323-80d623e34545

📥 Commits

Reviewing files that changed from the base of the PR and between e9c01dd and f8da1b2.

📒 Files selected for processing (12)
  • next.config.ts
  • supabase/functions/events-crawler/adapters/bibliocommons.ts
  • supabase/functions/events-crawler/adapters/tribe.ts
  • supabase/functions/events-crawler/dryrun.ts
  • supabase/functions/events-crawler/index.ts
  • supabase/functions/events-crawler/lib/constants.ts
  • supabase/functions/events-crawler/lib/dates.ts
  • supabase/functions/events-crawler/lib/genre.ts
  • supabase/functions/events-crawler/lib/images.ts
  • supabase/functions/events-crawler/lib/relevance.ts
  • supabase/functions/events-crawler/lib/text.ts
  • supabase/functions/events-crawler/lib/types.ts

Comment thread supabase/functions/events-crawler/adapters/bibliocommons.ts
Comment thread supabase/functions/events-crawler/adapters/bibliocommons.ts Outdated
Comment thread supabase/functions/events-crawler/adapters/bibliocommons.ts Outdated
Comment thread supabase/functions/events-crawler/adapters/tribe.ts Outdated
Comment thread supabase/functions/events-crawler/dryrun.ts Outdated
All five findings applied; each was clearly correct and small.

1. Extract lib/sources.ts (Major, maintainability). index.ts calls Deno.serve at module
   scope, which is why dryrun.ts had been copying the registry, adapter map and context
   construction — a drift risk that would quietly stop the preview predicting a real run.
   The wiring now lives in one side-effect-free module both import, with makeContext() as
   the single context factory. This was called out as a known trade-off in the PR body;
   CodeRabbit was right that it is simply fixable.

2. Use Promise.allSettled for per-event mapping (Major, stability). The row mappers await
   network work (cover HEAD probe, Pexels lookup). Under Promise.all a single rejection
   rejected the whole batch, hit the outer catch and returned [] — one transient image
   failure would have discarded every event of that source for the entire weekly run.
   Applied to both adapters; a failed row is logged and skipped.

3. Run the relevance filter on the full title, then truncate (Minor, correctness). The
   title was sliced to MAX_TITLE_CHARS before filtering, so a keyword past the cutoff was
   invisible and the event silently dropped. Both adapters.

4. Dedupe BiblioCommons candidates by event id before capping (Minor, data integrity).
   The catalog has no stable order and is read over ~20 round trips, so a shift
   mid-pagination can surface one event on two pages; a duplicate would consume a
   MAX_PER_ORG slot and pay for a redundant cover probe.

5. Count and report failed page fetches (Trivial). A failed page shrinks the candidate
   pool invisibly — the summary log looked identical to a complete crawl. Now warns, the
   same way MAX_PAGES truncation already did.

Behaviour is unchanged: all seven sources return exactly the same row counts as before
(25/24/14/0/2, westvan 5, vpl 25), and vpl now additionally reports 112 unique of 112.

Verification:
  deno check (incl. dryrun.ts)  → clean
  npx tsc --noEmit / eslint     → clean
  dryrun × 7 sources            → counts unchanged
  migrations/backfills guard    → empty

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ltanafranca1004

Copy link
Copy Markdown
Collaborator Author

Applied all five findings in 85be8c8 — each was clearly correct and small, so no follow-up questions.

  1. Extract lib/sources.ts — the registry, adapter map and makeContext() now live in one side-effect-free module that both index.ts and dryrun.ts import. This was flagged as a known trade-off in the PR body; you were right that it's simply fixable, and the drift risk is now gone entirely.
  2. Promise.allSettled in both adapters — a single rejected cover lookup no longer rejects the batch, hits the outer catch and discards the whole source for the week.
  3. Relevance filter before truncation in both adapters — a keyword past MAX_TITLE_CHARS was invisible to the filter.
  4. Dedupe BiblioCommons by event id before sort/cap.
  5. Failed page fetches counted and warned, matching the existing MAX_PAGES truncation reporting.

Behaviour is unchanged — all seven sources return identical row counts (25/24/14/0/2, westvan 5, vpl 25); vpl's summary now also reports 112 unique of 112.

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

@ltanafranca1004 Review requested for the updates in 85be8c8.

The changes address the reported failure handling, filter ordering, BiblioCommons deduplication, page-fetch reporting, and shared source registry.

🐇 ✅

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant