Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@steven-tey
Copy link
Collaborator

@steven-tey steven-tey commented Nov 20, 2025

Summary by CodeRabbit

Release Notes

  • Refactor
    • Consolidated event tracking infrastructure to use single Tinybird API endpoints, removing deprecated dual-path migration code and legacy integrations.
    • Simplified analytics ingestion logic by eliminating redundant parallel requests and migration wrappers across all event types.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link
Contributor

vercel bot commented Nov 20, 2025

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

Project Deployment Preview Updated (UTC)
dub Ready Ready Preview Nov 20, 2025 5:49am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 20, 2025

Walkthrough

This pull request removes the legacy Tinybird dual-write migration pattern across nine ingestion modules and related consumers. All deprecated tbOld client usage, waitUntil-wrapped async wrappers, and legacy endpoint variants are eliminated, consolidating all Tinybird event ingestion to the current tb client only.

Changes

Cohort / File(s) Summary
Tinybird Client Foundation
apps/web/lib/tinybird/client.ts
Removed the tbOld client export that previously used TINYBIRD_API_KEY_OLD, leaving only the primary tb client.
Tinybird Ingestion Endpoints
apps/web/lib/tinybird/log-conversion-events.ts, log-import-error.ts, record-click-zod.ts, record-lead.ts, record-sale.ts, record-webhook-event.ts
Removed tbOld imports and waitUntil wrappers; consolidated dual-write endpoints into single direct tb.buildIngestEndpoint exports. Renamed public endpoints by dropping TB/TBOld suffixes.
Tinybird Ingestion with Extended Schema
apps/web/lib/tinybird/log-conversion-events.ts
Added new event schema fields: link_id, path, body, and error (with appropriate defaults) alongside existing workspace_id.
Tinybird Ingestion with Timestamp Support
apps/web/lib/tinybird/record-lead.ts, record-sale.ts
Renamed recordLeadTB/recordSaleTB to recordLead/recordSale; introduced new recordLeadWithTimestamp and recordSaleWithTimestamp exports using tb.buildIngestEndpoint with timestamp schema. Removed old timestamped wrapper variants.
Tinybird Single-Endpoint Path Consolidation
apps/web/lib/tinybird/record-click.ts, record-link.ts
Removed dual-write fetch paths; retained only the current Tinybird ingest (record-click also removed old API key constant).
Audit Log Recording
apps/web/lib/api/audit-logs/record-audit-log.ts
Removed tbOld import and old ingest call; now uses only tb for recordAuditLogTB ingestion. Removed waitUntil wrapper.
Cron Job Batch Operation
apps/web/app/(ee)/api/cron/framer/backfill-leads-batch/route.ts
Removed second fetchWithRetry call that posted click data to old Tinybird URL with TINYBIRD_API_KEY_OLD.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Extra attention areas:
    • Verify that public API endpoint renamings (e.g., recordLeadTB β†’ recordLead, recordSaleTB β†’ recordSale) have corresponding updates in all calling code throughout the codebase
    • Review the expanded event schema in log-conversion-events.ts (new fields: link_id, path, body, error) to ensure Tinybird datasource accepts these additional fields and that callers provide them correctly
    • Confirm that removal of waitUntil from Vercel Functions doesn't affect request lifecycle guarantees in the affected modules (audit logs, ingestion endpoints)

Possibly related PRs

Suggested reviewers

  • devkiran

Poem

🐰 Old paths pruned, new leaves grow tall,
Dual writes fade to one true call,
No more keys split in twilight's keep,
Tinybird flows where codebases sleep!
Clean and swift, the query hops throughβ€”
Migration's dance now bids adieu. πŸŒ™

Pre-merge checks and finishing touches

βœ… Passed checks (3 passed)
Check name Status Explanation
Description Check βœ… Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check βœ… Passed The title clearly and specifically summarizes the main change: removing the legacy tbOld Tinybird client and completing the migration to the new Tinybird endpoint.
Docstring Coverage βœ… Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • πŸ“ Generate docstrings
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch remove-tb-old

πŸ“œ Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between cfe364a and 7703653.

πŸ“’ Files selected for processing (11)
  • apps/web/app/(ee)/api/cron/framer/backfill-leads-batch/route.ts (0 hunks)
  • apps/web/lib/api/audit-logs/record-audit-log.ts (1 hunks)
  • apps/web/lib/tinybird/client.ts (0 hunks)
  • apps/web/lib/tinybird/log-conversion-events.ts (2 hunks)
  • apps/web/lib/tinybird/log-import-error.ts (1 hunks)
  • apps/web/lib/tinybird/record-click-zod.ts (2 hunks)
  • apps/web/lib/tinybird/record-click.ts (0 hunks)
  • apps/web/lib/tinybird/record-lead.ts (1 hunks)
  • apps/web/lib/tinybird/record-link.ts (1 hunks)
  • apps/web/lib/tinybird/record-sale.ts (1 hunks)
  • apps/web/lib/tinybird/record-webhook-event.ts (1 hunks)
πŸ’€ Files with no reviewable changes (3)
  • apps/web/lib/tinybird/client.ts
  • apps/web/app/(ee)/api/cron/framer/backfill-leads-batch/route.ts
  • apps/web/lib/tinybird/record-click.ts
🧰 Additional context used
🧠 Learnings (4)
πŸ“š Learning: 2025-10-02T22:46:22.739Z
Learnt from: steven-tey
Repo: dubinc/dub PR: 2924
File: apps/web/lib/api/conversions/track-lead.ts:7-7
Timestamp: 2025-10-02T22:46:22.739Z
Learning: In apps/web/lib/api/conversions/track-lead.ts, lead events are cached in Redis for 5 minutes (keys: `leadCache:${customer.id}` and `leadCache:${customer.id}:${stringifiedEventName}`) to provide immediate data availability while Tinybird ingestion happens asynchronously. This caching pattern allows for async-only recording without breaking "wait" mode semantics.

Applied to files:

  • apps/web/lib/tinybird/log-conversion-events.ts
  • apps/web/lib/tinybird/record-lead.ts
πŸ“š Learning: 2025-07-17T06:41:45.620Z
Learnt from: devkiran
Repo: dubinc/dub PR: 2637
File: apps/web/app/(ee)/api/singular/webhook/route.ts:0-0
Timestamp: 2025-07-17T06:41:45.620Z
Learning: In the Singular integration (apps/web/app/(ee)/api/singular/webhook/route.ts), the event names in the singularToDubEvent object have intentionally different casing: "Copy GAID" and "copy IDFA". This casing difference is valid and should not be changed, as these are the correct event names expected from Singular.

Applied to files:

  • apps/web/lib/tinybird/log-conversion-events.ts
πŸ“š Learning: 2025-10-17T08:18:19.278Z
Learnt from: devkiran
Repo: dubinc/dub PR: 0
File: :0-0
Timestamp: 2025-10-17T08:18:19.278Z
Learning: In the apps/web codebase, `@/lib/zod` should only be used for places that need OpenAPI extended zod schema. All other places should import from the standard `zod` package directly using `import { z } from "zod"`.

Applied to files:

  • apps/web/lib/tinybird/log-conversion-events.ts
  • apps/web/lib/tinybird/record-click-zod.ts
πŸ“š Learning: 2025-06-06T07:59:03.120Z
Learnt from: devkiran
Repo: dubinc/dub PR: 2177
File: apps/web/lib/api/links/bulk-create-links.ts:66-84
Timestamp: 2025-06-06T07:59:03.120Z
Learning: In apps/web/lib/api/links/bulk-create-links.ts, the team accepts the risk of potential undefined results from links.find() operations when building invalidLinks arrays, because existing links are fetched from the database based on the input links, so matches are expected to always exist.

Applied to files:

  • apps/web/lib/tinybird/record-link.ts
🧬 Code graph analysis (6)
apps/web/lib/tinybird/log-import-error.ts (1)
apps/web/lib/tinybird/client.ts (1)
  • tb (3-6)
apps/web/lib/tinybird/log-conversion-events.ts (1)
apps/web/lib/tinybird/client.ts (1)
  • tb (3-6)
apps/web/lib/tinybird/record-sale.ts (1)
apps/web/lib/tinybird/client.ts (1)
  • tb (3-6)
apps/web/lib/tinybird/record-webhook-event.ts (1)
apps/web/lib/tinybird/client.ts (1)
  • tb (3-6)
apps/web/lib/tinybird/record-click-zod.ts (1)
apps/web/lib/tinybird/client.ts (1)
  • tb (3-6)
apps/web/lib/tinybird/record-lead.ts (2)
apps/web/lib/tinybird/client.ts (1)
  • tb (3-6)
apps/web/lib/zod/schemas/leads.ts (1)
  • leadEventSchemaTB (98-107)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
πŸ”‡ Additional comments (15)
apps/web/lib/api/audit-logs/record-audit-log.ts (4)

1-9: Clean removal of legacy Tinybird imports.

The import changes correctly remove the legacy tbOld client and waitUntil wrapper, consolidating to the current tb client only. This aligns perfectly with the PR objective to complete the Tinybird migration.


13-45: Transformation logic looks solid.

The transformAuditLogTB function correctly handles:

  • Header extraction (user-agent)
  • Zod schema validation
  • Field mapping with appropriate fallbacks for optional values
  • JSON serialization for complex fields

47-73: Main function correctly implements the migration.

The recordAuditLog function:

  • Correctly uses Next.js 15's async headers() API (line 48)
  • Properly handles both single and array inputs
  • Implements appropriate IP address resolution with fallback
  • Uses "best effort" error handling (logs but doesn't throw) which is appropriate for audit logging that shouldn't fail primary operations

75-79: Tinybird endpoint definition is appropriate.

The tb.buildIngestEndpoint configuration with wait: true ensures that audit log ingestion completes before the function returns, which is important for audit trail reliability. This replaces the previous waitUntil pattern with Tinybird's built-in synchronous ingestion behavior.

apps/web/lib/tinybird/record-link.ts (3)

4-4: LGTM! Import correctly simplified to use only the current Tinybird client.

The removal of tbOld and waitUntil imports aligns with the PR objective to complete the Tinybird migration and eliminate the dual-write pattern.


46-86: LGTM! Successfully consolidated to single Tinybird ingestion path.

The function now uses only recordLinkTB (built from the current tb client), correctly handling both single link and batch scenarios. The removal of the legacy dual-write pattern simplifies the codebase while maintaining the same public API.


4-4: Migration is completeβ€”no legacy code remains.

The verification confirms that all tbOld references have been successfully removed from the codebase. The waitUntil pattern detected in record-click.ts is standard Vercel async handling, not a legacy dual-write pattern. The migration across all affected modules appears complete and clean.

apps/web/lib/tinybird/record-click-zod.ts (1)

2-2: Consolidated click ingest endpoint matches Tinybird pattern

Using tb.buildIngestEndpoint with datasource: "dub_click_events", event: recordClickZodSchema, and wait: true aligns with the new single-endpoint Tinybird pattern and keeps the event shape unchanged. No issues spotted.

Also applies to: 39-43

apps/web/lib/tinybird/record-sale.ts (1)

3-15: Sale ingestion endpoints migrated cleanly to the new Tinybird client

recordSale and recordSaleWithTimestamp both use tb.buildIngestEndpoint against dub_sale_events, reusing saleEventSchemaTB and extending it with a timestamp field where needed. The refactor removes legacy paths without changing the visible event shape.

apps/web/lib/tinybird/log-conversion-events.ts (1)

2-2: Conversion event logging now uses a single Tinybird ingest endpoint

logConversionEvent is correctly wired to dub_conversion_events_log with the existing zod schema, eliminating the old dual-endpoint/wrapper setup without altering the payload structure.

Also applies to: 13-16

apps/web/lib/tinybird/record-webhook-event.ts (1)

2-7: Webhook event ingestion simplified to a single endpoint

recordWebhookEvent now directly uses tb.buildIngestEndpoint with datasource: "dub_webhook_events" and webhookEventSchemaTB minus timestamp, matching the simplified, single-endpoint Tinybird pattern in this PR.

apps/web/lib/tinybird/log-import-error.ts (1)

2-7: Tinybird migration verified as complete; no legacy artifacts remain

Verification confirms the migration is finished: no tbOld or TBOld references exist anywhere in the codebase. The extensive waitUntil() calls found are standard Vercel Edge Function and Server Action patterns used throughout the app for deferring background work (logging, webhooks, analytics), not legacy Tinybird wrappers. The change to logImportError correctly uses the modern tb.buildIngestEndpoint API.

apps/web/lib/tinybird/record-lead.ts (3)

1-3: LGTM: Clean import consolidation.

The removal of tbOld and waitUntil imports correctly completes the migration to the single tb client.


10-15: Code change verified and approved.

All consumers of the old recordLeadWithTimestampTB and recordLeadWithTimestampTBOld functions have been successfully updated to use the new recordLeadWithTimestamp function. No dangling references remain in the codebase. The schema extension adding timestamp: z.string() is correct.


5-8: Verification confirmedβ€”all consumers updated successfully.

The refactoring is complete. No references to the old recordLeadTB function remain, and all consumers across the codebase have been properly updated to use the new recordLead and recordLeadWithTimestamp exports. The code changes are correct and safe to merge.

Tip

πŸ“ Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests β€” including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. πŸ“ Description β€” Summarize the main change in 50–60 words, explaining what was done.
  2. πŸ““ References β€” List relevant issues, discussions, documentation, or related PRs.
  3. πŸ“¦ Dependencies & Requirements β€” Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. πŸ“Š Contributor Summary β€” Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. βœ”οΈ Additional Notes β€” Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


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.

@steven-tey steven-tey merged commit fd6d0ea into main Nov 20, 2025
8 of 10 checks passed
@steven-tey steven-tey deleted the remove-tb-old branch November 20, 2025 16:08
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.

2 participants