feat(analytics): creator performance query contract - #6692
Conversation
Adds the typed client contract for `creatorPerformance` and `creatorPostPerformance`: query documents, response types and the two options-creators the dashboard will spread into useQuery. The response shape is kept as the server sends it rather than flattened into plain numbers. Each metric keeps its `semantics`, so a lifetime total cannot end up captioned as a 30-day figure, and its `previous`, which is absent whenever a comparison would mislead. `coverage` travels alongside so the dashboard can say how much of the window the numbers really reach, and a null value stays distinguishable from a zero. No UI yet — that is the next ticket. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
rebelchris
left a comment
There was a problem hiding this comment.
Contract-only PR, CI green, hand-written types match the schema in dailydotdev/daily-api#4284 (nullability of value/previous/impressions/updatedAt, non-null connection). Two inline notes below, both non-blocking, plus one question:
Question (non-blocking): the client already carries a creator-analytics stack in packages/shared/src/graphql/users.ts (USER_POSTS_ANALYTICS_QUERY, USER_POSTS_ANALYTICS_HISTORY_QUERY, USER_POSTS_WITH_ANALYTICS_QUERY) powering /analytics. Is ENG-2126 replacing that page and its queries, or will the two stacks coexist? If it replaces it, it would be good to note in the ticket that the old queries and their RequestKey entries get removed with it, so we do not end up with two definitions of "creator impressions" in the client.
Reviewed by AI.
| upvotes | ||
| comments | ||
| outboundVisits | ||
| post { |
There was a problem hiding this comment.
Non-blocking, but worth fixing in the contract now: share posts have title: null and image: null on the post itself; the real title and image live on sharedPost. The existing table for this exact use case selects sharedPost { title image } and falls back to it (USER_POSTS_WITH_ANALYTICS_QUERY in graphql/users.ts, rendered in webapp/components/analytics/UserPostsAnalyticsTable.tsx). With the current selection, every shared post in a creator's table comes back with an empty title and no image, and ENG-2126 would have to reopen this file to fix it. Since post is the full Post type on the API side, add sharedPost { title image } here and mirror it in CreatorPostPerformance['post'].
Reviewed by AI.
| order?: CreatorPostSortOrder; | ||
| first?: number; | ||
| }) => ({ | ||
| // Sort and period are part of the key: the server re-ranks and re-scopes the |
There was a problem hiding this comment.
Nit, non-blocking: this restates the PR description. Root AGENTS.md asks for the reasoning to live in the commit message rather than above the code, and the other graphql/*.ts domain files carry almost no inline comments. The doc comments on the types are defensible because the next ticket reads them at the call site; this one is only about the key shape and can go.
Reviewed by AI.
Part of ENG-2125. Client half of dailydotdev/daily-api#4284 — merge and deploy the API first, the queries do not exist until then.
Changes
packages/shared/src/graphql/creatorAnalytics.ts: query documents, response types, and the two options-creators (creatorPerformanceQueryOptions,creatorPostPerformanceQueryOptions) for ENG-2126 to spread intouseQuery/useInfiniteQuery.RequestKeyentries. Sort, period and page size are part of the infinite-query key, since the server re-ranks and re-scopes the rows and pages fetched under one setting cannot be reused under another.No UI — that is ENG-2126.
The response shape is kept as the server sends it rather than flattened into plain numbers, because the meaning does not survive flattening:
semantics. Only impressions have a daily breakdown behind them, sooutboundVisitscomes backLIFETIME; rendering it as a bare integer would put a lifetime total under a "last 30 days" heading.value: nullmeans unknown and is not interchangeable with0— the dashboard needs to show an em dash or an explanation there, not a zero.previousis absent whenever a comparison would mislead, so the UI does not have to decide when a trend is trustworthy.coveragetravels alongside, so the dashboard can say how much of the window the numbers actually reach.The types carry those constraints as doc comments, so the next ticket sees them at the call site.
Events
No new tracking events.
Experiment
No new experiments.
Testing
Strict typecheck on the changed files,
eslinton the shared package, and a full webapptscall pass. (The webapp errors that remain are pre-existing, all under__tests__/, none related to this change.) No tests added: this is query documents and hand-written types with no logic to regress.🤖 Generated with Claude Code
Preview domain
https://eng-2125-creator-performance-que.preview.app.daily.dev