Skip to content

🩺(project) reload app if front and back unsync#2276

Merged
AntoLC merged 2 commits into
mainfrom
fix/frontend-unsync-backend
May 7, 2026
Merged

🩺(project) reload app if front and back unsync#2276
AntoLC merged 2 commits into
mainfrom
fix/frontend-unsync-backend

Conversation

@AntoLC

@AntoLC AntoLC commented May 7, 2026

Copy link
Copy Markdown
Collaborator

Purpose

We observe some cases where the frontend and backend versions can get out of sync, which can cause issues.
To mitigate this, we want to implement a mechanism that detects when the frontend and backend versions are mismatched and triggers a reload of the application to ensure they are in sync.

@AntoLC AntoLC self-assigned this May 7, 2026
@AntoLC AntoLC added bug Something isn't working frontend labels May 7, 2026
@AntoLC AntoLC linked an issue May 7, 2026 that may be closed by this pull request
@AntoLC AntoLC force-pushed the fix/frontend-unsync-backend branch from f253792 to d8136b6 Compare May 7, 2026 08:58
@AntoLC

AntoLC commented May 7, 2026

Copy link
Copy Markdown
Collaborator Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented May 7, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions

github-actions Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

Size Change: 0 B

Total Size: 4.24 MB

📦 View Changed
Filename Size Change
apps/impress/out/_next/static/a2553e83/_buildManifest.js 633 B +633 B (new file) 🆕
apps/impress/out/_next/static/dc0f4ae7/_buildManifest.js 0 B -633 B (removed) 🏆

compressed-size-action

@coderabbitai

coderabbitai Bot commented May 7, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

This PR implements automatic app reload when frontend and backend versions become unsynchronized. The backend config API now exposes RELEASE_VERSION, the frontend app version is injected at build time via NEXT_PUBLIC_APP_VERSION, and ConfigProvider compares these versions on load. When versions differ, the app reloads with sessionStorage-based deduplication to prevent reload loops. Config cache staleness is reduced to 5 minutes to enable faster version checks, app version is registered with PostHog for analytics, and comprehensive E2E tests verify the reload behavior.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • Ovgodd
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: implementing a mechanism to detect and reload the app when frontend and backend versions are out of sync.
Description check ✅ Passed The description clearly explains the purpose and motivation for the changes, relating directly to the changeset's goal of detecting version mismatches and triggering reloads.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/frontend-unsync-backend

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/frontend/apps/e2e/__tests__/app-impress/doc-routing.spec.ts`:
- Around line 159-175: Register the page.route handler for /users/me/ before
performing the actions that trigger a version-mismatch reload, replace the fixed
waitForTimeout with a deterministic wait that polls sessionStorage (e.g. await
page.waitForFunction(() => sessionStorage.getItem('reload-version') ===
'0.0.0')), and then assert the route hit count in a stable way (either assert
counterReload >= 2 or assert counterReload === 2 only if you guarantee the first
hit cannot be missed). Update references: the page.route handler that increments
counterReload, the sessionStorage.getItem('reload-version') check, and the final
expect on counterReload.

In `@src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts`:
- Line 7: The RELEASE_VERSION is currently imported from the e2e app
package.json (packageJsonVersion from '../../package.json') which can diverge
from NEXT_PUBLIC_APP_VERSION; change the import to read the Impress app's
package.json (the apps/impress package.json used to build
NEXT_PUBLIC_APP_VERSION) and use that value for RELEASE_VERSION instead, and
update the second occurrence at the other import/site (line referenced by the
review) so both places reference the Impress package.json version; locate
occurrences by the identifier RELEASE_VERSION and the import named
packageJsonVersion and replace their source to the Impress package.json.

In `@src/frontend/apps/impress/src/core/config/ConfigProvider.tsx`:
- Around line 101-107: sessionStorage access in ConfigProvider.tsx (the
RELOAD_VERSION_KEY check comparing to conf.RELEASE_VERSION) can throw in
restricted/security contexts; wrap both
sessionStorage.getItem(RELOAD_VERSION_KEY) and
sessionStorage.setItem(RELOAD_VERSION_KEY, conf.RELEASE_VERSION) in a try/catch
so a SecurityError doesn’t abort boot, and only call window.location.reload()
when the get succeeded and revealed a different version (fallback to skipping
reload on error). Ensure you reference RELOAD_VERSION_KEY, conf.RELEASE_VERSION,
and the reload call so the guard surrounds those operations.
🪄 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: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4a3887a4-db1d-4b67-8411-f14e79830d91

📥 Commits

Reviewing files that changed from the base of the PR and between a166716 and d8136b6.

📒 Files selected for processing (9)
  • CHANGELOG.md
  • src/backend/core/api/viewsets.py
  • src/backend/core/tests/test_api_config.py
  • src/frontend/apps/e2e/__tests__/app-impress/doc-routing.spec.ts
  • src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts
  • src/frontend/apps/impress/next.config.js
  • src/frontend/apps/impress/src/core/config/ConfigProvider.tsx
  • src/frontend/apps/impress/src/core/config/api/useConfig.tsx
  • src/frontend/apps/impress/src/services/PosthogAnalytic.tsx

Comment on lines +159 to +175
let counterReload = 0;
await page.route(/.*\/users\/me\/$/, async (route) => {
counterReload += 1;
await route.continue();
});

await page.waitForTimeout(1000);

// The sessionStorage guard should be set to the mismatched backend version.
const reloadVersion = await page.evaluate(() =>
sessionStorage.getItem('reload-version'),
);
expect(reloadVersion).toBe('0.0.0');

// The page should have reloaded once
expect(counterReload).toBe(2);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Make the reload assertion deterministic to avoid flaky CI failures.

Line 165 uses a fixed sleep, and Line 174 expects an exact /users/me/ count. This is timing-sensitive and can intermittently fail with retries/background refetches. Also, register the route before triggering mismatch logic so the first hit is never missed.

Suggested stabilization
 test('checks redirect if unsync version', async ({ page }) => {
+  let counterReload = 0;
+  await page.route(/.*\/users\/me\/$/, async (route) => {
+    counterReload += 1;
+    await route.continue();
+  });
+
   await overrideConfig(page, {
     RELEASE_VERSION: '0.0.0',
   });
 
-  let counterReload = 0;
-  await page.route(/.*\/users\/me\/$/, async (route) => {
-    counterReload += 1;
-    await route.continue();
-  });
-
-  await page.waitForTimeout(1000);
-
-  // The sessionStorage guard should be set to the mismatched backend version.
-  const reloadVersion = await page.evaluate(() =>
-    sessionStorage.getItem('reload-version'),
-  );
-  expect(reloadVersion).toBe('0.0.0');
-
-  // The page should have reloaded once
-  expect(counterReload).toBe(2);
+  await expect
+    .poll(
+      () => page.evaluate(() => sessionStorage.getItem('reload-version')),
+      { timeout: 10000 },
+    )
+    .toBe('0.0.0');
+
+  // At least 2 calls proves initial load + post-reload load.
+  await expect.poll(() => counterReload, { timeout: 10000 }).toBeGreaterThanOrEqual(2);
 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/frontend/apps/e2e/__tests__/app-impress/doc-routing.spec.ts` around lines
159 - 175, Register the page.route handler for /users/me/ before performing the
actions that trigger a version-mismatch reload, replace the fixed waitForTimeout
with a deterministic wait that polls sessionStorage (e.g. await
page.waitForFunction(() => sessionStorage.getItem('reload-version') ===
'0.0.0')), and then assert the route hit count in a stable way (either assert
counterReload >= 2 or assert counterReload === 2 only if you guarantee the first
hit cannot be missed). Update references: the page.route handler that increments
counterReload, the sessionStorage.getItem('reload-version') check, and the final
expect on counterReload.

import { Locator, Page, TestInfo, expect } from '@playwright/test';

import theme_customization from '../../../../../backend/impress/configuration/theme/default.json';
import { version as packageJsonVersion } from '../../package.json';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use the Impress package version, not the E2E package version, for RELEASE_VERSION.

../../package.json resolves to the e2e app package, which can diverge from NEXT_PUBLIC_APP_VERSION (built from apps/impress/package.json) and cause false mismatch/reload behavior in tests.

✅ Suggested fix
-import { version as packageJsonVersion } from '../../package.json';
+import { version as packageJsonVersion } from '../../../impress/package.json';

Also applies to: 44-44

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts` at line 7, The
RELEASE_VERSION is currently imported from the e2e app package.json
(packageJsonVersion from '../../package.json') which can diverge from
NEXT_PUBLIC_APP_VERSION; change the import to read the Impress app's
package.json (the apps/impress package.json used to build
NEXT_PUBLIC_APP_VERSION) and use that value for RELEASE_VERSION instead, and
update the second occurrence at the other import/site (line referenced by the
review) so both places reference the Impress package.json version; locate
occurrences by the identifier RELEASE_VERSION and the import named
packageJsonVersion and replace their source to the Impress package.json.

Comment thread src/frontend/apps/impress/src/core/config/ConfigProvider.tsx Outdated
Comment thread src/backend/core/api/viewsets.py Outdated
Comment thread src/backend/core/api/viewsets.py Outdated
Comment thread src/backend/core/tests/test_api_config.py Outdated
@AntoLC AntoLC force-pushed the fix/frontend-unsync-backend branch 3 times, most recently from 169c47c to 40dbbaa Compare May 7, 2026 09:31
@AntoLC AntoLC requested a review from lunika May 7, 2026 09:51
@AntoLC AntoLC force-pushed the fix/frontend-unsync-backend branch from 40dbbaa to bc8bc4a Compare May 7, 2026 09:52
AntoLC added 2 commits May 7, 2026 14:20
We observe some cases where the frontend and
backend versions can get out of sync, which can
cause issues.
To mitigate this, we want to implement a mechanism
that detects when the frontend and backend
versions are mismatched and triggers a
reload of the application to ensure they are in sync.
We add the app version in Posthog events to be
able to track which versions are being used and
identify potential issues related to specific
versions.
@AntoLC AntoLC force-pushed the fix/frontend-unsync-backend branch from bc8bc4a to d340c8f Compare May 7, 2026 12:20
@AntoLC AntoLC merged commit d340c8f into main May 7, 2026
42 of 45 checks passed
@AntoLC AntoLC deleted the fix/frontend-unsync-backend branch May 7, 2026 12:53
@lunika lunika mentioned this pull request May 7, 2026
lunika added a commit that referenced this pull request May 7, 2026
Added

- ⚡️(frontend) add skeleton on content loading #2254
- ⚡️(frontend) close websocket connection when user change tab #2264

Changed

- 🏗️(core) migrate from pip to uv

Fixed

- 🩺(project) reload app if front and back unsync #2276
- 🐛(frontend) fix patch and comments #2273
- 🐛(frontend) interlinking are exported correctly in print mode #2269
- 💬(frontend) add missing link in onboarding description #2233
- 🐛(frontend) sanitize pasted and dropped content in document title #2210
- 🐛(frontend) Emoji menu doesn't display above comment box #2229
- 🐛(frontend) Block menu doesn't stay open on 1st line #2229
- 🐛(frontend) The "+" on the first line of a new doc doesn't work #2229
- 🐛(backend) manage race condition between GET and PATCH content #2271
- 🐛(backend) replace document creation table locks with retry strategy #2274

Security

- 🔒️(frontend) sanitize color during collaboration #2270
lunika added a commit that referenced this pull request May 7, 2026
Added

- ⚡️(frontend) add skeleton on content loading #2254
- ⚡️(frontend) close websocket connection when user change tab #2264

Changed

- 🏗️(core) migrate from pip to uv

Fixed

- 🩺(project) reload app if front and back unsync #2276
- 🐛(frontend) fix patch and comments #2273
- 🐛(frontend) interlinking are exported correctly in print mode #2269
- 💬(frontend) add missing link in onboarding description #2233
- 🐛(frontend) sanitize pasted and dropped content in document title #2210
- 🐛(frontend) Emoji menu doesn't display above comment box #2229
- 🐛(frontend) Block menu doesn't stay open on 1st line #2229
- 🐛(frontend) The "+" on the first line of a new doc doesn't work #2229
- 🐛(backend) manage race condition between GET and PATCH content #2271
- 🐛(backend) replace document creation table locks with retry strategy #2274

Security

- 🔒️(frontend) sanitize color during collaboration #2270
lunika added a commit that referenced this pull request May 11, 2026
Added

- ⚡️(frontend) add skeleton on content loading #2254
- ⚡️(frontend) close websocket connection when user change tab #2264

Changed

- 🏗️(core) migrate from pip to uv

Fixed

- 🩺(project) reload app if front and back unsync #2276
- 🐛(frontend) fix patch and comments #2273
- 🐛(frontend) interlinking are exported correctly in print mode #2269
- 💬(frontend) add missing link in onboarding description #2233
- 🐛(frontend) sanitize pasted and dropped content in document title #2210
- 🐛(frontend) Emoji menu doesn't display above comment box #2229
- 🐛(frontend) Block menu doesn't stay open on 1st line #2229
- 🐛(frontend) The "+" on the first line of a new doc doesn't work #2229
- 🐛(backend) manage race condition between GET and PATCH content #2271
- 🐛(backend) replace document creation table locks with retry strategy #2274

Security

- 🔒️(frontend) sanitize color during collaboration #2270
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working frontend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛Frontend and backend unsync

2 participants