-
Notifications
You must be signed in to change notification settings - Fork 0
refactor: reduce boilerplate in event-processor with generic helper #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Create formatCreate and formatDelete formatters in webhook-events.ts - Add processEvent generic helper method to encapsulate common pattern - Refactor all 10 event handlers to use processEvent helper - Remove redundant processing logs (centralized in processEvent) - Export EventType union from constants for type safety - Simplify Promise.allSettled pattern in polling-service.ts Result: Reduced event-processor.ts from ~570 to 236 lines (-390 lines) All handlers now 5-8 lines instead of 45-55 lines each Eliminates ~450 lines of duplicated boilerplate code 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
WalkthroughThis PR introduces a cohesive set of type system improvements and event handling refactoring across multiple modules. It adds a derived Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/github-app/event-processor.ts (1)
49-101: Fix eventTypes filtering: substring and “all” semantics are incorrect
interestedChannelscurrently uses:const interestedChannels = channels.filter(ch => ch.eventTypes.includes(eventType) );Given
eventTypesis stored as a comma‑separated string (e.g."pr,issues,commits,releases"or"all"), this has two problems:
"all"will not match any specificeventType, so webhook subscribers who chose “all events” won’t receive anything here.- Substring matches can be wrong, e.g. a subscription of
"review_comments"will also match the"comments"event type because"review_comments".includes("comments")is true.You should align this logic with the polling service’s semantics by tokenizing and handling
"all"explicitly. For example:- // Filter by event preferences - const interestedChannels = channels.filter(ch => - ch.eventTypes.includes(eventType) - ); + // Filter by event preferences (supports comma-separated lists and "all") + const interestedChannels = channels.filter(ch => { + const types = ch.eventTypes; + if (!types || types === "all") return true; + return types + .split(",") + .map(t => t.trim()) + .includes(eventType); + });This keeps webhook behavior consistent with
isEventTypeMatchin the polling service and avoids subtle misrouting.
🧹 Nitpick comments (3)
src/utils/oauth-helpers.ts (1)
21-27: Confirm non‑ephemeral OAuth prompt behaviorWith the ephemeral option removed, the OAuth prompt (including a user-specific auth URL) will now be posted to the whole channel rather than just the requesting user. If the intent was to keep these prompts private and reduce channel noise, consider keeping them ephemeral or switching to a DM-style flow instead.
src/formatters/webhook-events.ts (1)
208-230: Create/Delete formatter behavior and consistencyThe new
formatCreate/formatDeletehelpers look correct and match the existing formatting style (short, Markdown-friendly, usingrepository.full_nameand backticked ref). Two optional polish ideas:
- Consider adding a
🔗prefix before${repository.html_url}to match other formatters likeformatWatch/formatWorkflowRun.- If you ever want to special-case repository-level create events, you could use
repository.full_nameinstead of"unknown"whenrefis null andref_type === "repository".src/services/polling-service.ts (1)
329-354: isEventTypeMatch semantics look sound (tiny edge‑case nit)The helper correctly treats
null/undefined/"all"subscription types as “match everything” and maps short names viaEVENT_TYPE_MAPbefore comparing against the GitHub event type, which fixes the previous ad‑hoc filtering. One minor edge case: an empty string""forsubscriptionTypesis currently treated like “all”; if that can occur due to DB defaults or bad input, you may want to special‑case it instead of folding it into “match all”.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/constants.ts(1 hunks)src/formatters/webhook-events.ts(2 hunks)src/github-app/event-processor.ts(9 hunks)src/services/polling-service.ts(5 hunks)src/utils/oauth-helpers.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
src/formatters/webhook-events.ts (1)
src/types/webhooks.ts (2)
CreatePayload(24-24)DeletePayload(25-25)
src/services/polling-service.ts (1)
src/constants.ts (1)
EventType(27-27)
src/github-app/event-processor.ts (3)
src/constants.ts (1)
EventType(27-27)src/types/webhooks.ts (6)
PullRequestPayload(14-14)PushPayload(16-16)CreatePayload(24-24)DeletePayload(25-25)ForkPayload(26-26)WatchPayload(27-27)src/formatters/webhook-events.ts (11)
formatPullRequest(21-44)formatPush(73-103)formatIssue(46-71)formatRelease(105-121)formatWorkflowRun(123-140)formatIssueComment(142-158)formatPullRequestReview(160-180)formatCreate(208-218)formatDelete(220-230)formatFork(182-191)formatWatch(193-206)
🔇 Additional comments (6)
src/formatters/webhook-events.ts (1)
6-18: Typed Create/Delete payload imports look goodWiring in
CreatePayloadandDeletePayloadfrom../types/webhookskeeps formatter signatures aligned with the webhook type layer and avoids stringly-typed payloads. No issues here.src/constants.ts (1)
24-28: EventType alias is clean and future‑proofDeriving
EventTypefromALLOWED_EVENT_TYPESis the right approach to keep the union synced with the source list and avoid drift. Looks good.src/services/polling-service.ts (3)
8-32: Typed EVENT_TYPE_MAP strengthens event handlingImporting
EventTypeand constrainingEVENT_TYPE_MAPtoRecord<EventType, string>nicely ensures every allowed short name is mapped and prevents accidental extra keys. This makes the event filtering logic more robust and self-documenting.
241-250: Safer PR number extraction from repo eventsThe additional guards on
event.payload("number" in event.payloadandtypeof event.payload.number === "number") make the PR prefetch step more resilient to unexpected payload shapes. This avoids adding invalid IDs toprNumbersand is a good hardening change.
295-307: Consolidated channel sends with Promise.allSettledSwitching to a single
Promise.allSettledoverchannelsForEventkeeps all sends in flight while still surfacing per-channel failures via the index back intochannelsForEvent. This is a solid pattern here, and the logging looks correct.src/github-app/event-processor.ts (1)
103-236: Generic processEvent helper and handler refactor look solidThe new
processEventhelper cleanly centralizes logging, subscriber lookup, formatting, and parallel sending withPromise.allSettled, and the individualon*handlers now read as small, declarative mappings from payload → (EventType, formatter, log context). This significantly reduces duplication and should make future event additions straightforward once the filtering semantics above are corrected.
Result: Reduced event-processor.ts from ~570 to 236 lines (-390 lines) All handlers now 5-8 lines instead of 45-55 lines each Eliminates ~450 lines of duplicated boilerplate code
🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
New Features
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.