Repository navigation
refactor: dedupe microsoft zone resolution and the email dispatch send tail - #4827
Merged
Merged
Conversation
The Graph zone fallback (IANA passthrough, Windows display-name lookup, UTC on failure) was copied byte-for-byte into the event normalizer and the cancelled-occurrences mapper as the recurrence-zone fixes landed. Move it to one microsoft-timezone module so a future zone rule changes in a single place. Also drop the "exception" instance branch in mapRecurrence: it is fully subsumed by the seriesMasterId branch directly below it and returns the same shape. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AF2JdyXsHsxqEk7KFTEoTn
The booking-host and welcome dispatch paths had each grown their own copy of the same tail: a skip closure, a mid-dispatch stop re-check, the isQueued claim guard, markSent, the email_sent capture, and a catch block that was byte-identical apart from its log prefix. Collapse both into #skipRow and #deliverRow, with each sequence passing only what differs: its stop re-check, its provider payload, and the welcome path's preview-loop follow-up. Behavior is unchanged; the welcome skip log now carries the same `reason` field the booking one already logged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AF2JdyXsHsxqEk7KFTEoTn
tyler-dane
marked this pull request as ready for review
October 25, 2026 10:20
tyler-dane
enabled auto-merge
October 25, 2026 10:21
Contributor
Author
Tech-debt sweep: 2026-10-18 → 2026-10-25Reviewed the 50 non-merge commits merged in the last 7 days. Two duplication clusters were worth a PR; both are in this one, as separate commits. Addressed here
Net on the email service: 164 lines removed, 146 added, and the retry/backoff policy now has one home instead of two that have to be kept in step. Inspected and deliberately left alone
Outcome: merged to Generated by Claude Code |
This was referenced Oct 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #
What and why
A debt sweep over the last 7 days of merged changes. Two duplication clusters grew out of recent fixes; both are behavior-preserving to collapse.
refactor(sync): share microsoft iana zone resolutionThe Graph zone fallback (IANA passthrough → Windows display-name lookup → UTC on failure) was copied byte-for-byte into
microsoft-event.normalizer.tsandmicrosoft-cancelled-occurrences.tsas the recurrence-zone fixes landed (#4794, #4797, #4805, #4824). It now lives once inmicrosoft-timezone.ts, so the next zone rule changes in a single place.Same commit drops the
item.type === "exception"branch inmapRecurrence: it was fully subsumed by theseriesMasterId && originalStartbranch immediately below it and returned an identical value.resolveIanaZoneinmicrosoft-recurrence.tsis deliberately left alone. It throwsUnsupportedRecurrenceErroron an unknown zone rather than falling back to UTC, so folding it in would turn skipped events into imported ones with a guessedUNTIL. That is a product call, not a refactor.refactor(backend): share the email dispatch send-and-retry tail#dispatchBookingHostRowand#dispatchWelcomeRowhad each grown their own copy of the same tail: askipclosure, the mid-dispatch stop re-check andisQueuedclaim guard added by #4788,markSent, theemail_sentcapture, and acatchblock that was byte-identical apart from its log prefix. Both now call#skipRowand#deliverRow, passing only what actually differs: the stop re-check, the provider payload, and the welcome path's preview-loop follow-up. 164 lines removed, 146 added, and the duplicated retry/backoff policy has one home.One intentional log change: the welcome skip log now carries the same
reasonfield the booking skip log already had.Verify
test:sync:fast(897 tests),type-check,lint, andknipall pass.test:backend:fastreports 618 pass / 13 fail, and all 13 are environmental, not this diff:GET /api/config(3) andSSE Server(10). This diff touches neither; it changes onlypackages/sync/src/providers/microsoft/*andpackages/backend/src/email/email-dispatch.service.ts./api/configreturns 500 and the SSE specs time out waiting foruserMetadataChanged;mongodb-memory-serverin the same sandbox fails withFailed to listen at ::. Addingcompass.yaml(cp compass.example.yaml compass.yamlplusbun dev:ports) does not change the count.CI decides.
Generated by Claude Code