7.1 interaction logging - #23
Conversation
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (8)
WalkthroughAdds end-to-end interaction tracking: client utilities to compute device/scroll/context, client instrumentation (bookmark, share, source click, view logging), backend validation/normalization and centralized persistence, plus unrelated UI updates (bias meter, dashboard stats, user streak display). ChangesInteraction tracking (client + backend + wiring)
UI / Stats updates
Sequence DiagramsequenceDiagram
participant User
participant Client as Client UI
participant Lib as Tracking Lib<br/>(interaction-tracking.ts)
participant API as Convex Mutation<br/>(api.interactions)
participant Backend as Convex Backend<br/>(interactions.ts)
participant DB as Convex DB
User->>Client: interact (view / click / share / bookmark)
Client->>Lib: buildInteractionContextFromSources()
Client->>Lib: getClientDeviceType(), getScrollDepthPercentage()
Client->>API: logInteraction / toggleBookmark (with context & metadata)
API->>Backend: mutation handler
Backend->>Backend: normalizeMetadata(), resolveContext(), recordInteraction()
Backend->>DB: insert / patch interaction
DB-->>Backend: ack
Backend-->>API: success
API-->>Client: mutation result
Client->>User: toast / UI update
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Review rate limit: 0/1 reviews remaining, refill in 23 minutes and 27 seconds.Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/web/src/routes/event`.$slug.tsx:
- Around line 356-390: The effect is depending on the unstable TanStack mutation
object (logInteraction) which can change between renders and cause premature
cleanup; replace the dependency with a stable mutate function from
useConvexMutation(api.interactions.logInteraction) (e.g., const logInteractionFn
= useConvexMutation(api.interactions.logInteraction)) and call that function
inside the cleanup instead of logInteraction.mutate, then remove the mutation
object from the useEffect dependency array (keep eventData?.event?._id and
isAuthenticated). Ensure you still import/use getClientDeviceType,
getScrollDepthPercentage and preserve the same metadata shape when invoking the
stable mutate function.
In `@packages/backend/convex/interactions.ts`:
- Around line 12-20: INTERACTION_TYPE_VALIDATOR currently includes "bookmark"
and "unbookmark", which lets logInteraction insert bookmark rows and bypass
toggleBookmark's cooldown/dedup logic; remove the v.literal("bookmark") and
v.literal("unbookmark") from INTERACTION_TYPE_VALIDATOR (or alternatively update
logInteraction to explicitly reject these two types) so bookmark actions are
only handled by toggleBookmark; update logInteraction to throw or return early
if it receives "bookmark"/"unbookmark", and ensure resolveBookmarkStatus and
getBookmarkedEvents continue to treat bookmark rows as authoritative and rely on
toggleBookmark for writes.
- Around line 134-162: The code in interactions.ts currently fan-outs on every
interaction write by querying eventArticles, uniqueSourceIds, and sources and
computing totalBias/totalReliability to produce biasRating and
sourceReliability; move this work off the hot write path by reading precomputed
event-level aggregates (e.g., add avgBias and avgReliability fields to the
events record or an eventStats document) or require the caller to pass a cheap
context arg instead of recomputing articles/sources per write, and update the
interaction write logic (the block referencing eventArticles, uniqueSourceIds,
sources, totalBias, totalReliability, biasRating, sourceReliability and the
similar logic at the later block) to use those precomputed fields or the
passed-in context; ensure background jobs or DB triggers maintain the
precomputed aggregates when articles or sources change.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 435f699a-437b-4c35-be78-f93d0c0c0c88
📒 Files selected for processing (7)
apps/web/src/components/bookmark-button.tsxapps/web/src/components/feed/articles-list.tsxapps/web/src/components/feed/event-card.tsxapps/web/src/components/share-event-button.tsxapps/web/src/lib/interaction-tracking.tsapps/web/src/routes/event.$slug.tsxpackages/backend/convex/interactions.ts
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/web/src/components/bias-balance-meter.tsx`:
- Around line 62-69: The indicator thumb is clipped at extremes because the
element uses left: `${indicatorPosition}%` together with the existing
-translate-x-1/2 transform and the parent has overflow-hidden; update the
indicator positioning logic in the BiasBalanceMeter component (the thumb div
that currently has class "-translate-x-1/2" and style { left:
`${indicatorPosition}%` }) so that when indicatorPosition is 0 or 100 you remove
or override the -50% X-translation (or apply a pixel/offset calc) to keep the
full thumb inside the container (e.g., use conditional transform or left:
`calc(...)` to shift by half the thumb width only for non-extreme values, or
clamp left to a small inset like 0.5rem/99.5% at extremes).
In `@apps/web/src/components/user-menu.tsx`:
- Around line 60-63: The streak label always shows "day streak"; change it to
pluralize based on the current streak value by reading user?.stats.currentStreak
(use a local const like streak = user?.stats.currentStreak ?? 0) and render
`${streak} day${streak === 1 ? '' : 's'} streak` inside the DropdownMenuItem
(component DropdownMenuItem, variable user?.stats.currentStreak) so 0 and >1
show "days" and 1 shows "day".
In `@apps/web/src/routes/dashboard.tsx`:
- Line 312: The dashboard currently calls
useQuery(api.interactions.getBookmarkedEvents) (bookmarkedEvents) which fetches
full hydrated bookmark objects just to read .length; replace this with a
lightweight count endpoint or use the already-available currentUser.stats field
instead: add or switch to an API method like api.interactions.getBookmarkedCount
(or read currentUser.stats.bookmarks) and update the useQuery call and any
references to bookmarkedEvents.length to use the numeric count, ensuring you
remove/stop calling getBookmarkedEvents from the dashboard card to avoid
hydrating full articles/sources.
In `@apps/web/src/routes/event`.$slug.tsx:
- Around line 373-390: The cleanup callback currently calls
logInteractionFn(...) with void which can still produce unhandled promise
rejections; update the return cleanup to call logInteractionFn(...) and append a
.catch handler to swallow or log errors so failures don't surface as
unhandledrejection events. Locate the block that removes the "scroll" listener
(handleScroll) and the logInteractionFn invocation that uses
eventData.event._id, interactionContext, getClientDeviceType(),
getScrollDepthPercentage(), maxScrollDepth, and startedAt, and add a .catch(...)
to the returned promise to handle/recover from any rejection.
In `@packages/backend/convex/interactions.ts`:
- Around line 115-121: The current early return when
ctx.db.query("userStats").withIndex("by_user", ...).unique() yields no stats
prevents initializing tracking for new users; instead, create a new userStats
record with the same zero/default shape used by packages/backend/convex/user.ts
(include userId and default fields like streak, articlesRead, biasBalance,
lastReadAt or similar) so the first tracked view updates counts/streaks; locate
the lookup for "userStats" in interactions.ts, and if stats is null call the
appropriate db insert/transaction to persist the default userStats before
proceeding with the view handling logic.
- Around line 25-36: INTERACTION_METADATA_VALIDATOR currently allows any string
for deviceType which can fragment analytics; update the validator so deviceType
is validated as an optional closed enum of the three allowed values ("mobile",
"tablet", "desktop") instead of v.string(); modify the deviceType entry in
INTERACTION_METADATA_VALIDATOR to use the validation combinator that enforces
exact literals (e.g., v.optional of a union of v.literal("mobile"),
v.literal("tablet"), v.literal("desktop")) so only those three values are
accepted at the mutation boundary.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 7e1d3cb4-5dc9-49ed-9979-d505ded7f5e2
📒 Files selected for processing (10)
apps/web/src/components/bias-balance-meter.tsxapps/web/src/components/bookmark-button.tsxapps/web/src/components/feed/articles-list.tsxapps/web/src/components/feed/event-card.tsxapps/web/src/components/share-event-button.tsxapps/web/src/components/user-menu.tsxapps/web/src/lib/interaction-tracking.tsapps/web/src/routes/dashboard.tsxapps/web/src/routes/event.$slug.tsxpackages/backend/convex/interactions.ts
Summary by CodeRabbit