Skip to content

feat(projects): Load project stats with react query, remove ProjectsStatsStore#115463

Open
scttcper wants to merge 5 commits into
masterfrom
scttcper/project-stats-query-keys
Open

feat(projects): Load project stats with react query, remove ProjectsStatsStore#115463
scttcper wants to merge 5 commits into
masterfrom
scttcper/project-stats-query-keys

Conversation

@scttcper
Copy link
Copy Markdown
Member

@scttcper scttcper commented May 13, 2026

Kills the ProjectsStatsStore. Mostly used on the /projects/ page. Allows us to remove some types from the global project object that typically don't exist via the ProjectsStore.

Project cards were still going through the old Reflux stats store and mutating project-shaped data with endpoint-expanded stats fields.

Move the dashboard over to useAggregatedQueryKeys, keep stats separate from the base Project type, and let the project card read stats through the new hook.

Co-Authored-By: Codex <noreply@openai.com>
@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label May 13, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 13, 2026

📊 Type Coverage Diff

✅ No new type safety issues introduced. Coverage: 93.51%

Project cards could flash back to loading after being unmounted for a bit because the aggregate hook only reduced cached responses for the local ids it had already buffered.

Allow callers to synchronously read cached aggregate data for a specific id before queueing another request, so scrolling back to a project card keeps the stats around.

Co-Authored-By: Codex <noreply@openai.com>
};

export function ProjectStatsGraph({project, stats}: Props) {
stats = stats || project.stats || [];
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mutating props?

@scttcper scttcper changed the title ref(projects): Load dashboard stats with aggregated queries feat(projects): Load project stats with react query, remove ProjectsStatsStore May 13, 2026
The customer details test hits the projects endpoint with statsPeriod=30d, but the shared getsentry project fixture no longer carries stats by default.

Keep stats out of the base fixture and add the endpoint-expanded field at the mock response instead.

Co-Authored-By: Codex <noreply@openai.com>
@scttcper scttcper marked this pull request as ready for review May 13, 2026 16:16
@scttcper scttcper requested review from a team as code owners May 13, 2026 16:16
Comment thread static/app/views/projectsDashboard/projectCard.tsx
Comment on lines +108 to 116
(aggregates = prevQueryKeys.current) =>
queryClient
.getQueriesData<ApiResponse<Data>>({
.getQueriesData<ApiResponse<ResponseData>>({
predicate: ({queryKey}) => isApiQueryKeyForUrl(queryKey),
})
.flatMap(([, val]) => (defined(val) ? [val] : []))
.reduce<Data | undefined>(
(prevValue, val) => responseReducer(prevValue, val, prevQueryKeys.current),
(prevValue, val) => responseReducer(prevValue, val, aggregates),
undefined
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The readCache function incorrectly matches cached queries by URL only, ignoring query parameters. This leads to data from unrelated API calls being mixed, causing data loss.
Severity: HIGH

Suggested Fix

Update the readCache predicate to filter queries using the full query key, including query parameters, not just the URL path. This will ensure that only responses with the exact same parameters and expected data structure are processed, preventing cross-contamination from unrelated API calls.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: static/app/utils/api/useAggregatedQueryKeys.tsx#L108-L116

Potential issue: The `readCache` function in `useAggregatedQueryKeys` filters cached
React Query data by URL path only, ignoring query parameters. This causes it to retrieve
data from different API calls to the same endpoint that have different response
structures. For example, it can mix a response from the `OrganizationProjects` page
(which uses `collapse` to remove stats) with a response for the dashboard (which
includes stats). The `responseReducer` in `useProjectStats` can then process the
stat-less response, causing previously cached project statistics to be lost and leading
to missing data on the dashboard.

Also affects:

  • static/app/views/settings/organizationProjects/index.tsx:52~63
  • static/app/views/projectsDashboard/useProjectStats.tsx:62~74

Did we get this right? 👍 / 👎 to inform future reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant