Skip to content

Sync: preserve Pressable metadata in reconciliation fallback - #4078

Merged
gcsecsey merged 3 commits into
trunkfrom
stu-1944-preserve-pressable-sync-support
Jul 6, 2026
Merged

Sync: preserve Pressable metadata in reconciliation fallback#4078
gcsecsey merged 3 commits into
trunkfrom
stu-1944-preserve-pressable-sync-support

Conversation

@gcsecsey

@gcsecsey gcsecsey commented Jul 3, 2026

Copy link
Copy Markdown
Member

Related issues

How AI was used in this PR

Claude investigated the issue, helped reduce it against WPCom with a test Pressable site, and implemented the fix.

Proposed Changes

When the Sync tab loads, Studio refreshes connected-site metadata from page 1 of /me/sites and fetches any connected site missing from that page individually via rest/v1.1 /sites/{id}. The single-site endpoint never returns hosting_provider_guess or environment_type, these are wpcom decorations that exist only on the /me/sites endpoints, even when explicitly requested via fields. Because Pressable support is derived from hosting_provider_guess, a successful fallback response reclassified a known Pressable site as unsupported (and could misfile staging sites), and reconciliation persisted that downgrade. Accounts with more than one page of sites, eg. the 80-site agency in STU-1977, hit this on every Sync tab load.

  • The supplemental fetch now falls back to the stored connected site's isPressable / staging metadata when the response lacks those fields, instead of recomputing sync support from incomplete data.
  • Deletion and permission changes are still detected from the response, only the missing provider metadata is preserved, so a genuinely deleted site or lost permissions still downgrade correctly.
  • A jetpack counterpart (adding hosting_provider_guess/environment_type to the single-site endpoint) is being prepared separately, this guard protects all reconciliation paths regardless.

Testing Instructions

  1. Run the unit tests: npm test -- apps/studio/src/modules/sync/lib/tests/build-supplemental-sync-site.test.ts
  2. Manual verification (the bug needs a connected Pressable site that is NOT on page 1 of /me/sites):
    • Temporarily lower perPage in apps/studio/src/stores/sync/wpcom-sites.ts to force the fallback:
    diff --git a/apps/studio/src/stores/sync/wpcom-sites.ts b/apps/studio/src/stores/sync/wpcom-sites.ts
    index 602cf0afc..0d98bd509 100644
    --- a/apps/studio/src/stores/sync/wpcom-sites.ts
    +++ b/apps/studio/src/stores/sync/wpcom-sites.ts
    @@ -97,7 +97,9 @@ export const wpcomSitesApi = createApi( {
                                    search?: string;
                            }
                    >( {
    -                       queryFn: async ( { connectedSiteIds, page = 1, perPage = 20, search } ) => {
    +                       queryFn: async ( { connectedSiteIds, page = 1, perPage = 1, search } ) => {
                                    const wpcomClient = getWpcomClient();
                                    if ( ! wpcomClient ) {
                                            return { error: { status: 401, data: 'Not authenticated' } };
    • Connect a local site to a Pressable site
    • Reload the Sync tab
    • Before this change: the connected site shows "appears to be deleted or is currently unreachable" and its stored record flips to syncSupport: "unsupported", isPressable: false in ~/.studio/app.json. After: it stays recognized as a connected Pressable site and remains syncable.
trunk this branch
CleanShot 2026-07-06 at 11 08 08@2x CleanShot 2026-07-06 at 11 12 27@2x

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?
@wpmobilebot

wpmobilebot commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

📊 Performance Test Results

Comparing c947ee1 vs trunk

app-size

Metric trunk c947ee1 Diff Change
App Size (Mac) 1345.24 MB 1345.25 MB +0.00 MB ⚪ 0.0%

site-editor

Metric trunk c947ee1 Diff Change
load 736 ms 1071 ms +335 ms 🔴 45.5%

site-startup

Metric trunk c947ee1 Diff Change
siteCreation 6460 ms 6505 ms +45 ms ⚪ 0.0%
siteStartup 2392 ms 2394 ms +2 ms ⚪ 0.0%

Results are median values from multiple test runs.

Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff)

storedSite: SyncSite | undefined,
connectedSiteIds: number[]
): SyncSite {
if ( site.hosting_provider_guess === undefined && storedSite?.isPressable ) {

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.

this could be a possible refactor for clarity:

  const effectiveSite =                                                                                       
        site.hosting_provider_guess === undefined && storedSite?.isPressable                                  
                ? { ...site, hosting_provider_guess: 'pressable' as const }                                   
                : site;

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.

Good call, applied in 9c803c8 👍

@katinthehatsite katinthehatsite left a comment

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.

I think the changes make sense and look good, I came to a similar conclusion while checking the issue.

I left one minor comment

@katinthehatsite

Copy link
Copy Markdown
Contributor

As a sidenote: I don't have the right type of setup to test this manually but I reviewed the code visually and ran the tests

@gcsecsey
gcsecsey merged commit ea6480c into trunk Jul 6, 2026
11 checks passed
@gcsecsey
gcsecsey deleted the stu-1944-preserve-pressable-sync-support branch July 6, 2026 10:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants