Repository navigation
Fix engagement analytics and production readiness - #23
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b93e3309fe
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| this.delivery = new EngagementDelivery(input.sessionToken, (error) => { | ||
| if (error.status === 410) this.resetVisit(); | ||
| else this.stop(); |
There was a problem hiding this comment.
Restart tracking after a stale-visit response
When the server expires a visit slightly before the client does—for example because recent queued events failed delivery—the user's next interaction is sent to the old visit and receives 410. This callback only resets state, clearing hasInteracted, the qualification timer, and queued events; because the pointer/click handlers have already completed, no replacement visit starts until the user interacts again. Consequently the first navigation/read after the stale boundary is omitted from analytics. Preserve the current interaction and immediately attempt a new visit after resetting.
Useful? React with 👍 / 👎.
| select visit_id as "visitId", slide_id as "slideId", event_at as "eventAt", | ||
| sequence, accepted_duration_ms as "activeDurationMs", qualified | ||
| from engagement_events | ||
| where visit_id in ${database(visitIds)} | ||
| order by event_at, sequence, server_received_at, idempotency_key |
There was a problem hiding this comment.
Avoid loading every heartbeat for an analytics read
For a long-lived or high-traffic deck, this query materializes every raw engagement event for every matching visit before aggregation. The tracker emits a heartbeat every 10 seconds and retention defaults to 365 days, so this turns an analytics request that previously loaded roughly one row per visit/slide into one that can load hundreds of rows per visit and millions of rows for a popular deck, causing large latency and memory spikes or request failure. Derive appearance aggregates in SQL or persist bounded appearance records instead of returning the complete raw event history on each read.
Useful? React with 👍 / 👎.
Summary
Migration and operational notes
The additive nullable event-qualification column is migrated at API startup. Existing totals and immutable presentation revisions are retained. Exact appearance order cannot be reconstructed for historical events, so the dashboard labels those sequences as unrecorded instead of guessing.
No new package, service, public tool, or authorization surface is introduced. Original unrelated working-tree changes are excluded.
Verification
Post-merge verification checks both deployed commit hashes, real email sign-in, sharing/analytics UI, and cleanup of the synthetic release fixture. Local evidence does not claim population SLOs, Safari/Firefox certification, or actual browser BFCache admission.