feat(web): Add banner to notify user when permissions are syncing for the first time - #852

Merged
brendan-kellam merged 3 commits into
mainfrom
bkellam/fix-SOU-314
Feb 4, 2026
Merged

feat(web): Add banner to notify user when permissions are syncing for the first time#852
brendan-kellam merged 3 commits into
mainfrom
bkellam/fix-SOU-314

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Problem

There can be a delay between when a account is created and it's permissions are synced for the first time. This creates user confusion since all repositories will not be visible until this permission sync completes.

Solution

This PR adds a notification banner that is displayed at the top while permissions are syncing for the first time for the user.

permission-syncing.mp4

Fixes#817

Summary by CodeRabbit

  • New Features
    • Added an in-app notification banner that informs users when repository permissions are being synced for the first time.
    • Introduced a new alert UI component to standardize and improve informational and status messages across the app.
    • Updated entitlements to enable "anonymous-access" for the self-hosted Enterprise Unlimited plan.

@github-actions

This comment has been minimized.

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

Walkthrough

Adds a permission-sync notification banner and supporting API/UI: server route to report first-time permission sync status, client polling and banner component, new Alert UI primitives, entitlement update, and changelog entry.

Changes

Cohort / File(s)Summary
Changelog
CHANGELOG.md
Added Unreleased "Added" entry documenting the permission-sync notification banner (refs PR #852).
Entitlements
packages/shared/src/entitlements.ts
Updated plan entitlements: added anonymous-access to self-hosted:enterprise-unlimited; arrays reformatted to multiline.
Server API
packages/web/src/app/api/(server)/ee/permissionSyncStatus/route.ts
New GET route returning PermissionSyncStatusResponse { hasPendingFirstSync }; validates permission-syncing entitlement, queries accounts and latest permissionSyncJobs to determine pending-first-sync state; returns structured service errors for auth/entitlement failures.
Client API
packages/web/src/app/api/(client)/client.ts
Added getPermissionSyncStatus() client function calling /api/ee/permissionSyncStatus, returns typed PermissionSyncStatusResponse or ServiceError.
Permission Sync UI
packages/web/src/app/[domain]/components/permissionSyncBanner.tsx, packages/web/src/app/[domain]/layout.tsx
New PermissionSyncBanner component using react-query to poll status (conditional refetch), tracks prior state to trigger router.refresh() when sync completes; layout imports and conditionally renders banner based on session and permission-syncing entitlement.
UI primitives
packages/web/src/components/ui/alert.tsx
New Alert component suite (Alert, AlertTitle, AlertDescription, AlertAction) with variant styling and accessibility attributes; used by the banner.

Sequence Diagram(s)

sequenceDiagram
participant Browser as Browser/Client
participant Banner as PermissionSyncBanner
participant ReactQuery as React Query
participant APIClient as API Client
participant Server as Server API
participant DB as Database
Browser->>Banner: Mount
Banner->>ReactQuery: useQuery(getPermissionSyncStatus)
loop while hasPendingFirstSync
ReactQuery->>APIClient: getPermissionSyncStatus()
APIClient->>Server: GET /api/ee/permissionSyncStatus
Server->>DB: Query accounts + latest permissionSyncJobs
DB-->>Server: account sync data
Server-->>APIClient: PermissionSyncStatusResponse(hasPendingFirstSync)
APIClient-->>ReactQuery: response
ReactQuery-->>Banner: update status
alt pending
Banner->>Browser: show Alert banner (spinner)
else completed
Banner->>Browser: router.refresh(), hide banner
end
end
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

Suggested Reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe PR title clearly and specifically describes the main change: adding a banner to notify users when permissions are syncing for the first time, which directly aligns with the primary objective of the changeset.
Linked Issues check✅ PassedThe PR partially addresses issue #817 by providing visual feedback (a notification banner) during permission syncing, but does not implement pre-fetching/prioritizing repos or progress metrics as suggested in the feature request.
Out of Scope Changes check✅ PassedAll changes are directly related to implementing the permission sync banner feature: UI component, server endpoint, client API call, entitlements mapping, and layout integration. The new Alert component provides necessary UI foundation for the banner.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bkellam/fix-SOU-314

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.

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@packages/web/src/app/`[domain]/components/permissionSyncBanner.tsx:
- Around line 23-27: The refetchInterval callback currently checks
query.state.data for truthiness, but that is the raw response object and always
truthy once loaded, causing infinite polling; update the logic in the
refetchInterval function to inspect the hasPendingFirstSync property on the data
(e.g., return query.state.data?.hasPendingFirstSync ? POLL_INTERVAL_MS : false)
so polling continues only while hasPendingFirstSync is true; reference symbols:
refetchInterval, query.state.data, hasPendingFirstSync, POLL_INTERVAL_MS.
In `@packages/web/src/app/api/`(server)/ee/permissionSyncStatus/route.ts:
- Around line 16-18: Update the JSDoc comment on the permission sync route so
the grammar is correct: change "Returns whether a user has a account that has
it's permissions synced for the first time." to "Returns whether a user has an
account that has its permissions synced for the first time." — edit the comment
above the exported route handler in route.ts (the file-level JSDoc for the
permissionSyncStatus endpoint).
- Around line 23-27: Replace the incorrect error code used in the permission
sync route: in the code path that returns serviceErrorResponse with statusCode
StatusCodes.FORBIDDEN and ErrorCode.NOT_FOUND, change the error code to
ErrorCode.INSUFFICIENT_PERMISSIONS (keep the existing message and status);
update the call in the route handler (the function returning
serviceErrorResponse in route.ts) so the error code matches the 403 semantics
and existing entitlement/plan denial conventions.
🧹 Nitpick comments (1)
packages/web/src/app/api/(server)/ee/permissionSyncStatus/route.ts (1)

1-1: Unnecessary 'use server' directive for route handlers.

Route handlers in Next.js App Router are server-side by default. The 'use server' directive is specifically for Server Actions (functions called from client components). This directive is unnecessary here and could cause confusion.

🔧 Suggested fix
-'use server';-
import { apiHandler } from "@/lib/apiHandler";

@brendan-kellam
brendan-kellam merged commit fb358d8 into mainFeb 4, 2026
8 of 9 checks passed
@brendan-kellam
brendan-kellam deleted the bkellam/fix-SOU-314 branch February 4, 2026 23:59
@github-actionsgithub-actionsBot mentioned this pull request Feb 4, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FR] Improve initial login experience during permission syncing (repo sync delay)

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(web): Add banner to notify user when permissions are syncing for the first time - #852

Merged
brendan-kellam merged 3 commits into
mainfrom
bkellam/fix-SOU-314
Feb 4, 2026
Merged

feat(web): Add banner to notify user when permissions are syncing for the first time#852
brendan-kellam merged 3 commits into
mainfrom
bkellam/fix-SOU-314

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Problem

There can be a delay between when a account is created and it's permissions are synced for the first time. This creates user confusion since all repositories will not be visible until this permission sync completes.

Solution

This PR adds a notification banner that is displayed at the top while permissions are syncing for the first time for the user.

permission-syncing.mp4

Fixes#817

Summary by CodeRabbit

  • New Features
    • Added an in-app notification banner that informs users when repository permissions are being synced for the first time.
    • Introduced a new alert UI component to standardize and improve informational and status messages across the app.
    • Updated entitlements to enable "anonymous-access" for the self-hosted Enterprise Unlimited plan.

@github-actions

This comment has been minimized.

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

Walkthrough

Adds a permission-sync notification banner and supporting API/UI: server route to report first-time permission sync status, client polling and banner component, new Alert UI primitives, entitlement update, and changelog entry.

Changes

Cohort / File(s)Summary
Changelog
CHANGELOG.md
Added Unreleased "Added" entry documenting the permission-sync notification banner (refs PR #852).
Entitlements
packages/shared/src/entitlements.ts
Updated plan entitlements: added anonymous-access to self-hosted:enterprise-unlimited; arrays reformatted to multiline.
Server API
packages/web/src/app/api/(server)/ee/permissionSyncStatus/route.ts
New GET route returning PermissionSyncStatusResponse { hasPendingFirstSync }; validates permission-syncing entitlement, queries accounts and latest permissionSyncJobs to determine pending-first-sync state; returns structured service errors for auth/entitlement failures.
Client API
packages/web/src/app/api/(client)/client.ts
Added getPermissionSyncStatus() client function calling /api/ee/permissionSyncStatus, returns typed PermissionSyncStatusResponse or ServiceError.
Permission Sync UI
packages/web/src/app/[domain]/components/permissionSyncBanner.tsx, packages/web/src/app/[domain]/layout.tsx
New PermissionSyncBanner component using react-query to poll status (conditional refetch), tracks prior state to trigger router.refresh() when sync completes; layout imports and conditionally renders banner based on session and permission-syncing entitlement.
UI primitives
packages/web/src/components/ui/alert.tsx
New Alert component suite (Alert, AlertTitle, AlertDescription, AlertAction) with variant styling and accessibility attributes; used by the banner.

Sequence Diagram(s)

sequenceDiagram
participant Browser as Browser/Client
participant Banner as PermissionSyncBanner
participant ReactQuery as React Query
participant APIClient as API Client
participant Server as Server API
participant DB as Database
Browser->>Banner: Mount
Banner->>ReactQuery: useQuery(getPermissionSyncStatus)
loop while hasPendingFirstSync
ReactQuery->>APIClient: getPermissionSyncStatus()
APIClient->>Server: GET /api/ee/permissionSyncStatus
Server->>DB: Query accounts + latest permissionSyncJobs
DB-->>Server: account sync data
Server-->>APIClient: PermissionSyncStatusResponse(hasPendingFirstSync)
APIClient-->>ReactQuery: response
ReactQuery-->>Banner: update status
alt pending
Banner->>Browser: show Alert banner (spinner)
else completed
Banner->>Browser: router.refresh(), hide banner
end
end
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

Suggested Reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe PR title clearly and specifically describes the main change: adding a banner to notify users when permissions are syncing for the first time, which directly aligns with the primary objective of the changeset.
Linked Issues check✅ PassedThe PR partially addresses issue #817 by providing visual feedback (a notification banner) during permission syncing, but does not implement pre-fetching/prioritizing repos or progress metrics as suggested in the feature request.
Out of Scope Changes check✅ PassedAll changes are directly related to implementing the permission sync banner feature: UI component, server endpoint, client API call, entitlements mapping, and layout integration. The new Alert component provides necessary UI foundation for the banner.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bkellam/fix-SOU-314

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.

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@packages/web/src/app/`[domain]/components/permissionSyncBanner.tsx:
- Around line 23-27: The refetchInterval callback currently checks
query.state.data for truthiness, but that is the raw response object and always
truthy once loaded, causing infinite polling; update the logic in the
refetchInterval function to inspect the hasPendingFirstSync property on the data
(e.g., return query.state.data?.hasPendingFirstSync ? POLL_INTERVAL_MS : false)
so polling continues only while hasPendingFirstSync is true; reference symbols:
refetchInterval, query.state.data, hasPendingFirstSync, POLL_INTERVAL_MS.
In `@packages/web/src/app/api/`(server)/ee/permissionSyncStatus/route.ts:
- Around line 16-18: Update the JSDoc comment on the permission sync route so
the grammar is correct: change "Returns whether a user has a account that has
it's permissions synced for the first time." to "Returns whether a user has an
account that has its permissions synced for the first time." — edit the comment
above the exported route handler in route.ts (the file-level JSDoc for the
permissionSyncStatus endpoint).
- Around line 23-27: Replace the incorrect error code used in the permission
sync route: in the code path that returns serviceErrorResponse with statusCode
StatusCodes.FORBIDDEN and ErrorCode.NOT_FOUND, change the error code to
ErrorCode.INSUFFICIENT_PERMISSIONS (keep the existing message and status);
update the call in the route handler (the function returning
serviceErrorResponse in route.ts) so the error code matches the 403 semantics
and existing entitlement/plan denial conventions.
🧹 Nitpick comments (1)
packages/web/src/app/api/(server)/ee/permissionSyncStatus/route.ts (1)

1-1: Unnecessary 'use server' directive for route handlers.

Route handlers in Next.js App Router are server-side by default. The 'use server' directive is specifically for Server Actions (functions called from client components). This directive is unnecessary here and could cause confusion.

🔧 Suggested fix
-'use server';-
import { apiHandler } from "@/lib/apiHandler";

@brendan-kellam
brendan-kellam merged commit fb358d8 into mainFeb 4, 2026
8 of 9 checks passed
@brendan-kellam
brendan-kellam deleted the bkellam/fix-SOU-314 branch February 4, 2026 23:59
@github-actionsgithub-actionsBot mentioned this pull request Feb 4, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FR] Improve initial login experience during permission syncing (repo sync delay)

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(web): Add banner to notify user when permissions are syncing for the first time - #852

Merged
brendan-kellam merged 3 commits into
mainfrom
bkellam/fix-SOU-314
Feb 4, 2026
Merged

feat(web): Add banner to notify user when permissions are syncing for the first time#852
brendan-kellam merged 3 commits into
mainfrom
bkellam/fix-SOU-314

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Problem

There can be a delay between when a account is created and it's permissions are synced for the first time. This creates user confusion since all repositories will not be visible until this permission sync completes.

Solution

This PR adds a notification banner that is displayed at the top while permissions are syncing for the first time for the user.

permission-syncing.mp4

Fixes#817

Summary by CodeRabbit

  • New Features
    • Added an in-app notification banner that informs users when repository permissions are being synced for the first time.
    • Introduced a new alert UI component to standardize and improve informational and status messages across the app.
    • Updated entitlements to enable "anonymous-access" for the self-hosted Enterprise Unlimited plan.

@github-actions

This comment has been minimized.

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

Walkthrough

Adds a permission-sync notification banner and supporting API/UI: server route to report first-time permission sync status, client polling and banner component, new Alert UI primitives, entitlement update, and changelog entry.

Changes

Cohort / File(s)Summary
Changelog
CHANGELOG.md
Added Unreleased "Added" entry documenting the permission-sync notification banner (refs PR #852).
Entitlements
packages/shared/src/entitlements.ts
Updated plan entitlements: added anonymous-access to self-hosted:enterprise-unlimited; arrays reformatted to multiline.
Server API
packages/web/src/app/api/(server)/ee/permissionSyncStatus/route.ts
New GET route returning PermissionSyncStatusResponse { hasPendingFirstSync }; validates permission-syncing entitlement, queries accounts and latest permissionSyncJobs to determine pending-first-sync state; returns structured service errors for auth/entitlement failures.
Client API
packages/web/src/app/api/(client)/client.ts
Added getPermissionSyncStatus() client function calling /api/ee/permissionSyncStatus, returns typed PermissionSyncStatusResponse or ServiceError.
Permission Sync UI
packages/web/src/app/[domain]/components/permissionSyncBanner.tsx, packages/web/src/app/[domain]/layout.tsx
New PermissionSyncBanner component using react-query to poll status (conditional refetch), tracks prior state to trigger router.refresh() when sync completes; layout imports and conditionally renders banner based on session and permission-syncing entitlement.
UI primitives
packages/web/src/components/ui/alert.tsx
New Alert component suite (Alert, AlertTitle, AlertDescription, AlertAction) with variant styling and accessibility attributes; used by the banner.

Sequence Diagram(s)

sequenceDiagram
participant Browser as Browser/Client
participant Banner as PermissionSyncBanner
participant ReactQuery as React Query
participant APIClient as API Client
participant Server as Server API
participant DB as Database
Browser->>Banner: Mount
Banner->>ReactQuery: useQuery(getPermissionSyncStatus)
loop while hasPendingFirstSync
ReactQuery->>APIClient: getPermissionSyncStatus()
APIClient->>Server: GET /api/ee/permissionSyncStatus
Server->>DB: Query accounts + latest permissionSyncJobs
DB-->>Server: account sync data
Server-->>APIClient: PermissionSyncStatusResponse(hasPendingFirstSync)
APIClient-->>ReactQuery: response
ReactQuery-->>Banner: update status
alt pending
Banner->>Browser: show Alert banner (spinner)
else completed
Banner->>Browser: router.refresh(), hide banner
end
end
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

Suggested Reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe PR title clearly and specifically describes the main change: adding a banner to notify users when permissions are syncing for the first time, which directly aligns with the primary objective of the changeset.
Linked Issues check✅ PassedThe PR partially addresses issue #817 by providing visual feedback (a notification banner) during permission syncing, but does not implement pre-fetching/prioritizing repos or progress metrics as suggested in the feature request.
Out of Scope Changes check✅ PassedAll changes are directly related to implementing the permission sync banner feature: UI component, server endpoint, client API call, entitlements mapping, and layout integration. The new Alert component provides necessary UI foundation for the banner.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bkellam/fix-SOU-314

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.

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@packages/web/src/app/`[domain]/components/permissionSyncBanner.tsx:
- Around line 23-27: The refetchInterval callback currently checks
query.state.data for truthiness, but that is the raw response object and always
truthy once loaded, causing infinite polling; update the logic in the
refetchInterval function to inspect the hasPendingFirstSync property on the data
(e.g., return query.state.data?.hasPendingFirstSync ? POLL_INTERVAL_MS : false)
so polling continues only while hasPendingFirstSync is true; reference symbols:
refetchInterval, query.state.data, hasPendingFirstSync, POLL_INTERVAL_MS.
In `@packages/web/src/app/api/`(server)/ee/permissionSyncStatus/route.ts:
- Around line 16-18: Update the JSDoc comment on the permission sync route so
the grammar is correct: change "Returns whether a user has a account that has
it's permissions synced for the first time." to "Returns whether a user has an
account that has its permissions synced for the first time." — edit the comment
above the exported route handler in route.ts (the file-level JSDoc for the
permissionSyncStatus endpoint).
- Around line 23-27: Replace the incorrect error code used in the permission
sync route: in the code path that returns serviceErrorResponse with statusCode
StatusCodes.FORBIDDEN and ErrorCode.NOT_FOUND, change the error code to
ErrorCode.INSUFFICIENT_PERMISSIONS (keep the existing message and status);
update the call in the route handler (the function returning
serviceErrorResponse in route.ts) so the error code matches the 403 semantics
and existing entitlement/plan denial conventions.
🧹 Nitpick comments (1)
packages/web/src/app/api/(server)/ee/permissionSyncStatus/route.ts (1)

1-1: Unnecessary 'use server' directive for route handlers.

Route handlers in Next.js App Router are server-side by default. The 'use server' directive is specifically for Server Actions (functions called from client components). This directive is unnecessary here and could cause confusion.

🔧 Suggested fix
-'use server';-
import { apiHandler } from "@/lib/apiHandler";

@brendan-kellam
brendan-kellam merged commit fb358d8 into mainFeb 4, 2026
8 of 9 checks passed
@brendan-kellam
brendan-kellam deleted the bkellam/fix-SOU-314 branch February 4, 2026 23:59
@github-actionsgithub-actionsBot mentioned this pull request Feb 4, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FR] Improve initial login experience during permission syncing (repo sync delay)

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(web): Add banner to notify user when permissions are syncing for the first time - #852

Merged
brendan-kellam merged 3 commits into
mainfrom
bkellam/fix-SOU-314
Feb 4, 2026
Merged

feat(web): Add banner to notify user when permissions are syncing for the first time#852
brendan-kellam merged 3 commits into
mainfrom
bkellam/fix-SOU-314

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Problem

There can be a delay between when a account is created and it's permissions are synced for the first time. This creates user confusion since all repositories will not be visible until this permission sync completes.

Solution

This PR adds a notification banner that is displayed at the top while permissions are syncing for the first time for the user.

permission-syncing.mp4

Fixes#817

Summary by CodeRabbit

  • New Features
    • Added an in-app notification banner that informs users when repository permissions are being synced for the first time.
    • Introduced a new alert UI component to standardize and improve informational and status messages across the app.
    • Updated entitlements to enable "anonymous-access" for the self-hosted Enterprise Unlimited plan.

@github-actions

This comment has been minimized.

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

Walkthrough

Adds a permission-sync notification banner and supporting API/UI: server route to report first-time permission sync status, client polling and banner component, new Alert UI primitives, entitlement update, and changelog entry.

Changes

Cohort / File(s)Summary
Changelog
CHANGELOG.md
Added Unreleased "Added" entry documenting the permission-sync notification banner (refs PR #852).
Entitlements
packages/shared/src/entitlements.ts
Updated plan entitlements: added anonymous-access to self-hosted:enterprise-unlimited; arrays reformatted to multiline.
Server API
packages/web/src/app/api/(server)/ee/permissionSyncStatus/route.ts
New GET route returning PermissionSyncStatusResponse { hasPendingFirstSync }; validates permission-syncing entitlement, queries accounts and latest permissionSyncJobs to determine pending-first-sync state; returns structured service errors for auth/entitlement failures.
Client API
packages/web/src/app/api/(client)/client.ts
Added getPermissionSyncStatus() client function calling /api/ee/permissionSyncStatus, returns typed PermissionSyncStatusResponse or ServiceError.
Permission Sync UI
packages/web/src/app/[domain]/components/permissionSyncBanner.tsx, packages/web/src/app/[domain]/layout.tsx
New PermissionSyncBanner component using react-query to poll status (conditional refetch), tracks prior state to trigger router.refresh() when sync completes; layout imports and conditionally renders banner based on session and permission-syncing entitlement.
UI primitives
packages/web/src/components/ui/alert.tsx
New Alert component suite (Alert, AlertTitle, AlertDescription, AlertAction) with variant styling and accessibility attributes; used by the banner.

Sequence Diagram(s)

sequenceDiagram
participant Browser as Browser/Client
participant Banner as PermissionSyncBanner
participant ReactQuery as React Query
participant APIClient as API Client
participant Server as Server API
participant DB as Database
Browser->>Banner: Mount
Banner->>ReactQuery: useQuery(getPermissionSyncStatus)
loop while hasPendingFirstSync
ReactQuery->>APIClient: getPermissionSyncStatus()
APIClient->>Server: GET /api/ee/permissionSyncStatus
Server->>DB: Query accounts + latest permissionSyncJobs
DB-->>Server: account sync data
Server-->>APIClient: PermissionSyncStatusResponse(hasPendingFirstSync)
APIClient-->>ReactQuery: response
ReactQuery-->>Banner: update status
alt pending
Banner->>Browser: show Alert banner (spinner)
else completed
Banner->>Browser: router.refresh(), hide banner
end
end
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

Suggested Reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe PR title clearly and specifically describes the main change: adding a banner to notify users when permissions are syncing for the first time, which directly aligns with the primary objective of the changeset.
Linked Issues check✅ PassedThe PR partially addresses issue #817 by providing visual feedback (a notification banner) during permission syncing, but does not implement pre-fetching/prioritizing repos or progress metrics as suggested in the feature request.
Out of Scope Changes check✅ PassedAll changes are directly related to implementing the permission sync banner feature: UI component, server endpoint, client API call, entitlements mapping, and layout integration. The new Alert component provides necessary UI foundation for the banner.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bkellam/fix-SOU-314

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.

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@packages/web/src/app/`[domain]/components/permissionSyncBanner.tsx:
- Around line 23-27: The refetchInterval callback currently checks
query.state.data for truthiness, but that is the raw response object and always
truthy once loaded, causing infinite polling; update the logic in the
refetchInterval function to inspect the hasPendingFirstSync property on the data
(e.g., return query.state.data?.hasPendingFirstSync ? POLL_INTERVAL_MS : false)
so polling continues only while hasPendingFirstSync is true; reference symbols:
refetchInterval, query.state.data, hasPendingFirstSync, POLL_INTERVAL_MS.
In `@packages/web/src/app/api/`(server)/ee/permissionSyncStatus/route.ts:
- Around line 16-18: Update the JSDoc comment on the permission sync route so
the grammar is correct: change "Returns whether a user has a account that has
it's permissions synced for the first time." to "Returns whether a user has an
account that has its permissions synced for the first time." — edit the comment
above the exported route handler in route.ts (the file-level JSDoc for the
permissionSyncStatus endpoint).
- Around line 23-27: Replace the incorrect error code used in the permission
sync route: in the code path that returns serviceErrorResponse with statusCode
StatusCodes.FORBIDDEN and ErrorCode.NOT_FOUND, change the error code to
ErrorCode.INSUFFICIENT_PERMISSIONS (keep the existing message and status);
update the call in the route handler (the function returning
serviceErrorResponse in route.ts) so the error code matches the 403 semantics
and existing entitlement/plan denial conventions.
🧹 Nitpick comments (1)
packages/web/src/app/api/(server)/ee/permissionSyncStatus/route.ts (1)

1-1: Unnecessary 'use server' directive for route handlers.

Route handlers in Next.js App Router are server-side by default. The 'use server' directive is specifically for Server Actions (functions called from client components). This directive is unnecessary here and could cause confusion.

🔧 Suggested fix
-'use server';-
import { apiHandler } from "@/lib/apiHandler";

@brendan-kellam
brendan-kellam merged commit fb358d8 into mainFeb 4, 2026
8 of 9 checks passed
@brendan-kellam
brendan-kellam deleted the bkellam/fix-SOU-314 branch February 4, 2026 23:59
@github-actionsgithub-actionsBot mentioned this pull request Feb 4, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FR] Improve initial login experience during permission syncing (repo sync delay)

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(web): Add banner to notify user when permissions are syncing for the first time - #852

Merged
brendan-kellam merged 3 commits into
mainfrom
bkellam/fix-SOU-314
Feb 4, 2026
Merged

feat(web): Add banner to notify user when permissions are syncing for the first time#852
brendan-kellam merged 3 commits into
mainfrom
bkellam/fix-SOU-314

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Problem

There can be a delay between when a account is created and it's permissions are synced for the first time. This creates user confusion since all repositories will not be visible until this permission sync completes.

Solution

This PR adds a notification banner that is displayed at the top while permissions are syncing for the first time for the user.

permission-syncing.mp4

Fixes#817

Summary by CodeRabbit

  • New Features
    • Added an in-app notification banner that informs users when repository permissions are being synced for the first time.
    • Introduced a new alert UI component to standardize and improve informational and status messages across the app.
    • Updated entitlements to enable "anonymous-access" for the self-hosted Enterprise Unlimited plan.

@github-actions

This comment has been minimized.

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

Walkthrough

Adds a permission-sync notification banner and supporting API/UI: server route to report first-time permission sync status, client polling and banner component, new Alert UI primitives, entitlement update, and changelog entry.

Changes

Cohort / File(s)Summary
Changelog
CHANGELOG.md
Added Unreleased "Added" entry documenting the permission-sync notification banner (refs PR #852).
Entitlements
packages/shared/src/entitlements.ts
Updated plan entitlements: added anonymous-access to self-hosted:enterprise-unlimited; arrays reformatted to multiline.
Server API
packages/web/src/app/api/(server)/ee/permissionSyncStatus/route.ts
New GET route returning PermissionSyncStatusResponse { hasPendingFirstSync }; validates permission-syncing entitlement, queries accounts and latest permissionSyncJobs to determine pending-first-sync state; returns structured service errors for auth/entitlement failures.
Client API
packages/web/src/app/api/(client)/client.ts
Added getPermissionSyncStatus() client function calling /api/ee/permissionSyncStatus, returns typed PermissionSyncStatusResponse or ServiceError.
Permission Sync UI
packages/web/src/app/[domain]/components/permissionSyncBanner.tsx, packages/web/src/app/[domain]/layout.tsx
New PermissionSyncBanner component using react-query to poll status (conditional refetch), tracks prior state to trigger router.refresh() when sync completes; layout imports and conditionally renders banner based on session and permission-syncing entitlement.
UI primitives
packages/web/src/components/ui/alert.tsx
New Alert component suite (Alert, AlertTitle, AlertDescription, AlertAction) with variant styling and accessibility attributes; used by the banner.

Sequence Diagram(s)

sequenceDiagram
participant Browser as Browser/Client
participant Banner as PermissionSyncBanner
participant ReactQuery as React Query
participant APIClient as API Client
participant Server as Server API
participant DB as Database
Browser->>Banner: Mount
Banner->>ReactQuery: useQuery(getPermissionSyncStatus)
loop while hasPendingFirstSync
ReactQuery->>APIClient: getPermissionSyncStatus()
APIClient->>Server: GET /api/ee/permissionSyncStatus
Server->>DB: Query accounts + latest permissionSyncJobs
DB-->>Server: account sync data
Server-->>APIClient: PermissionSyncStatusResponse(hasPendingFirstSync)
APIClient-->>ReactQuery: response
ReactQuery-->>Banner: update status
alt pending
Banner->>Browser: show Alert banner (spinner)
else completed
Banner->>Browser: router.refresh(), hide banner
end
end
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

Suggested Reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe PR title clearly and specifically describes the main change: adding a banner to notify users when permissions are syncing for the first time, which directly aligns with the primary objective of the changeset.
Linked Issues check✅ PassedThe PR partially addresses issue #817 by providing visual feedback (a notification banner) during permission syncing, but does not implement pre-fetching/prioritizing repos or progress metrics as suggested in the feature request.
Out of Scope Changes check✅ PassedAll changes are directly related to implementing the permission sync banner feature: UI component, server endpoint, client API call, entitlements mapping, and layout integration. The new Alert component provides necessary UI foundation for the banner.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bkellam/fix-SOU-314

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.

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@packages/web/src/app/`[domain]/components/permissionSyncBanner.tsx:
- Around line 23-27: The refetchInterval callback currently checks
query.state.data for truthiness, but that is the raw response object and always
truthy once loaded, causing infinite polling; update the logic in the
refetchInterval function to inspect the hasPendingFirstSync property on the data
(e.g., return query.state.data?.hasPendingFirstSync ? POLL_INTERVAL_MS : false)
so polling continues only while hasPendingFirstSync is true; reference symbols:
refetchInterval, query.state.data, hasPendingFirstSync, POLL_INTERVAL_MS.
In `@packages/web/src/app/api/`(server)/ee/permissionSyncStatus/route.ts:
- Around line 16-18: Update the JSDoc comment on the permission sync route so
the grammar is correct: change "Returns whether a user has a account that has
it's permissions synced for the first time." to "Returns whether a user has an
account that has its permissions synced for the first time." — edit the comment
above the exported route handler in route.ts (the file-level JSDoc for the
permissionSyncStatus endpoint).
- Around line 23-27: Replace the incorrect error code used in the permission
sync route: in the code path that returns serviceErrorResponse with statusCode
StatusCodes.FORBIDDEN and ErrorCode.NOT_FOUND, change the error code to
ErrorCode.INSUFFICIENT_PERMISSIONS (keep the existing message and status);
update the call in the route handler (the function returning
serviceErrorResponse in route.ts) so the error code matches the 403 semantics
and existing entitlement/plan denial conventions.
🧹 Nitpick comments (1)
packages/web/src/app/api/(server)/ee/permissionSyncStatus/route.ts (1)

1-1: Unnecessary 'use server' directive for route handlers.

Route handlers in Next.js App Router are server-side by default. The 'use server' directive is specifically for Server Actions (functions called from client components). This directive is unnecessary here and could cause confusion.

🔧 Suggested fix
-'use server';-
import { apiHandler } from "@/lib/apiHandler";

@brendan-kellam
brendan-kellam merged commit fb358d8 into mainFeb 4, 2026
8 of 9 checks passed
@brendan-kellam
brendan-kellam deleted the bkellam/fix-SOU-314 branch February 4, 2026 23:59
@github-actionsgithub-actionsBot mentioned this pull request Feb 4, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FR] Improve initial login experience during permission syncing (repo sync delay)

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(web): Add banner to notify user when permissions are syncing for the first time - #852

Merged
brendan-kellam merged 3 commits into
mainfrom
bkellam/fix-SOU-314
Feb 4, 2026
Merged

feat(web): Add banner to notify user when permissions are syncing for the first time#852
brendan-kellam merged 3 commits into
mainfrom
bkellam/fix-SOU-314

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Problem

There can be a delay between when a account is created and it's permissions are synced for the first time. This creates user confusion since all repositories will not be visible until this permission sync completes.

Solution

This PR adds a notification banner that is displayed at the top while permissions are syncing for the first time for the user.

permission-syncing.mp4

Fixes#817

Summary by CodeRabbit

  • New Features
    • Added an in-app notification banner that informs users when repository permissions are being synced for the first time.
    • Introduced a new alert UI component to standardize and improve informational and status messages across the app.
    • Updated entitlements to enable "anonymous-access" for the self-hosted Enterprise Unlimited plan.

@github-actions

This comment has been minimized.

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

Walkthrough

Adds a permission-sync notification banner and supporting API/UI: server route to report first-time permission sync status, client polling and banner component, new Alert UI primitives, entitlement update, and changelog entry.

Changes

Cohort / File(s)Summary
Changelog
CHANGELOG.md
Added Unreleased "Added" entry documenting the permission-sync notification banner (refs PR #852).
Entitlements
packages/shared/src/entitlements.ts
Updated plan entitlements: added anonymous-access to self-hosted:enterprise-unlimited; arrays reformatted to multiline.
Server API
packages/web/src/app/api/(server)/ee/permissionSyncStatus/route.ts
New GET route returning PermissionSyncStatusResponse { hasPendingFirstSync }; validates permission-syncing entitlement, queries accounts and latest permissionSyncJobs to determine pending-first-sync state; returns structured service errors for auth/entitlement failures.
Client API
packages/web/src/app/api/(client)/client.ts
Added getPermissionSyncStatus() client function calling /api/ee/permissionSyncStatus, returns typed PermissionSyncStatusResponse or ServiceError.
Permission Sync UI
packages/web/src/app/[domain]/components/permissionSyncBanner.tsx, packages/web/src/app/[domain]/layout.tsx
New PermissionSyncBanner component using react-query to poll status (conditional refetch), tracks prior state to trigger router.refresh() when sync completes; layout imports and conditionally renders banner based on session and permission-syncing entitlement.
UI primitives
packages/web/src/components/ui/alert.tsx
New Alert component suite (Alert, AlertTitle, AlertDescription, AlertAction) with variant styling and accessibility attributes; used by the banner.

Sequence Diagram(s)

sequenceDiagram
participant Browser as Browser/Client
participant Banner as PermissionSyncBanner
participant ReactQuery as React Query
participant APIClient as API Client
participant Server as Server API
participant DB as Database
Browser->>Banner: Mount
Banner->>ReactQuery: useQuery(getPermissionSyncStatus)
loop while hasPendingFirstSync
ReactQuery->>APIClient: getPermissionSyncStatus()
APIClient->>Server: GET /api/ee/permissionSyncStatus
Server->>DB: Query accounts + latest permissionSyncJobs
DB-->>Server: account sync data
Server-->>APIClient: PermissionSyncStatusResponse(hasPendingFirstSync)
APIClient-->>ReactQuery: response
ReactQuery-->>Banner: update status
alt pending
Banner->>Browser: show Alert banner (spinner)
else completed
Banner->>Browser: router.refresh(), hide banner
end
end
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

Suggested Reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe PR title clearly and specifically describes the main change: adding a banner to notify users when permissions are syncing for the first time, which directly aligns with the primary objective of the changeset.
Linked Issues check✅ PassedThe PR partially addresses issue #817 by providing visual feedback (a notification banner) during permission syncing, but does not implement pre-fetching/prioritizing repos or progress metrics as suggested in the feature request.
Out of Scope Changes check✅ PassedAll changes are directly related to implementing the permission sync banner feature: UI component, server endpoint, client API call, entitlements mapping, and layout integration. The new Alert component provides necessary UI foundation for the banner.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bkellam/fix-SOU-314

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.

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@packages/web/src/app/`[domain]/components/permissionSyncBanner.tsx:
- Around line 23-27: The refetchInterval callback currently checks
query.state.data for truthiness, but that is the raw response object and always
truthy once loaded, causing infinite polling; update the logic in the
refetchInterval function to inspect the hasPendingFirstSync property on the data
(e.g., return query.state.data?.hasPendingFirstSync ? POLL_INTERVAL_MS : false)
so polling continues only while hasPendingFirstSync is true; reference symbols:
refetchInterval, query.state.data, hasPendingFirstSync, POLL_INTERVAL_MS.
In `@packages/web/src/app/api/`(server)/ee/permissionSyncStatus/route.ts:
- Around line 16-18: Update the JSDoc comment on the permission sync route so
the grammar is correct: change "Returns whether a user has a account that has
it's permissions synced for the first time." to "Returns whether a user has an
account that has its permissions synced for the first time." — edit the comment
above the exported route handler in route.ts (the file-level JSDoc for the
permissionSyncStatus endpoint).
- Around line 23-27: Replace the incorrect error code used in the permission
sync route: in the code path that returns serviceErrorResponse with statusCode
StatusCodes.FORBIDDEN and ErrorCode.NOT_FOUND, change the error code to
ErrorCode.INSUFFICIENT_PERMISSIONS (keep the existing message and status);
update the call in the route handler (the function returning
serviceErrorResponse in route.ts) so the error code matches the 403 semantics
and existing entitlement/plan denial conventions.
🧹 Nitpick comments (1)
packages/web/src/app/api/(server)/ee/permissionSyncStatus/route.ts (1)

1-1: Unnecessary 'use server' directive for route handlers.

Route handlers in Next.js App Router are server-side by default. The 'use server' directive is specifically for Server Actions (functions called from client components). This directive is unnecessary here and could cause confusion.

🔧 Suggested fix
-'use server';-
import { apiHandler } from "@/lib/apiHandler";

@brendan-kellam
brendan-kellam merged commit fb358d8 into mainFeb 4, 2026
8 of 9 checks passed
@brendan-kellam
brendan-kellam deleted the bkellam/fix-SOU-314 branch February 4, 2026 23:59
@github-actionsgithub-actionsBot mentioned this pull request Feb 4, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FR] Improve initial login experience during permission syncing (repo sync delay)

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(web): Add banner to notify user when permissions are syncing for the first time - #852

Merged
brendan-kellam merged 3 commits into
mainfrom
bkellam/fix-SOU-314
Feb 4, 2026
Merged

feat(web): Add banner to notify user when permissions are syncing for the first time#852
brendan-kellam merged 3 commits into
mainfrom
bkellam/fix-SOU-314

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Problem

There can be a delay between when a account is created and it's permissions are synced for the first time. This creates user confusion since all repositories will not be visible until this permission sync completes.

Solution

This PR adds a notification banner that is displayed at the top while permissions are syncing for the first time for the user.

permission-syncing.mp4

Fixes#817

Summary by CodeRabbit

  • New Features
    • Added an in-app notification banner that informs users when repository permissions are being synced for the first time.
    • Introduced a new alert UI component to standardize and improve informational and status messages across the app.
    • Updated entitlements to enable "anonymous-access" for the self-hosted Enterprise Unlimited plan.

@github-actions

This comment has been minimized.

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

Walkthrough

Adds a permission-sync notification banner and supporting API/UI: server route to report first-time permission sync status, client polling and banner component, new Alert UI primitives, entitlement update, and changelog entry.

Changes

Cohort / File(s)Summary
Changelog
CHANGELOG.md
Added Unreleased "Added" entry documenting the permission-sync notification banner (refs PR #852).
Entitlements
packages/shared/src/entitlements.ts
Updated plan entitlements: added anonymous-access to self-hosted:enterprise-unlimited; arrays reformatted to multiline.
Server API
packages/web/src/app/api/(server)/ee/permissionSyncStatus/route.ts
New GET route returning PermissionSyncStatusResponse { hasPendingFirstSync }; validates permission-syncing entitlement, queries accounts and latest permissionSyncJobs to determine pending-first-sync state; returns structured service errors for auth/entitlement failures.
Client API
packages/web/src/app/api/(client)/client.ts
Added getPermissionSyncStatus() client function calling /api/ee/permissionSyncStatus, returns typed PermissionSyncStatusResponse or ServiceError.
Permission Sync UI
packages/web/src/app/[domain]/components/permissionSyncBanner.tsx, packages/web/src/app/[domain]/layout.tsx
New PermissionSyncBanner component using react-query to poll status (conditional refetch), tracks prior state to trigger router.refresh() when sync completes; layout imports and conditionally renders banner based on session and permission-syncing entitlement.
UI primitives
packages/web/src/components/ui/alert.tsx
New Alert component suite (Alert, AlertTitle, AlertDescription, AlertAction) with variant styling and accessibility attributes; used by the banner.

Sequence Diagram(s)

sequenceDiagram
participant Browser as Browser/Client
participant Banner as PermissionSyncBanner
participant ReactQuery as React Query
participant APIClient as API Client
participant Server as Server API
participant DB as Database
Browser->>Banner: Mount
Banner->>ReactQuery: useQuery(getPermissionSyncStatus)
loop while hasPendingFirstSync
ReactQuery->>APIClient: getPermissionSyncStatus()
APIClient->>Server: GET /api/ee/permissionSyncStatus
Server->>DB: Query accounts + latest permissionSyncJobs
DB-->>Server: account sync data
Server-->>APIClient: PermissionSyncStatusResponse(hasPendingFirstSync)
APIClient-->>ReactQuery: response
ReactQuery-->>Banner: update status
alt pending
Banner->>Browser: show Alert banner (spinner)
else completed
Banner->>Browser: router.refresh(), hide banner
end
end
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

Suggested Reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe PR title clearly and specifically describes the main change: adding a banner to notify users when permissions are syncing for the first time, which directly aligns with the primary objective of the changeset.
Linked Issues check✅ PassedThe PR partially addresses issue #817 by providing visual feedback (a notification banner) during permission syncing, but does not implement pre-fetching/prioritizing repos or progress metrics as suggested in the feature request.
Out of Scope Changes check✅ PassedAll changes are directly related to implementing the permission sync banner feature: UI component, server endpoint, client API call, entitlements mapping, and layout integration. The new Alert component provides necessary UI foundation for the banner.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bkellam/fix-SOU-314

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.

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@packages/web/src/app/`[domain]/components/permissionSyncBanner.tsx:
- Around line 23-27: The refetchInterval callback currently checks
query.state.data for truthiness, but that is the raw response object and always
truthy once loaded, causing infinite polling; update the logic in the
refetchInterval function to inspect the hasPendingFirstSync property on the data
(e.g., return query.state.data?.hasPendingFirstSync ? POLL_INTERVAL_MS : false)
so polling continues only while hasPendingFirstSync is true; reference symbols:
refetchInterval, query.state.data, hasPendingFirstSync, POLL_INTERVAL_MS.
In `@packages/web/src/app/api/`(server)/ee/permissionSyncStatus/route.ts:
- Around line 16-18: Update the JSDoc comment on the permission sync route so
the grammar is correct: change "Returns whether a user has a account that has
it's permissions synced for the first time." to "Returns whether a user has an
account that has its permissions synced for the first time." — edit the comment
above the exported route handler in route.ts (the file-level JSDoc for the
permissionSyncStatus endpoint).
- Around line 23-27: Replace the incorrect error code used in the permission
sync route: in the code path that returns serviceErrorResponse with statusCode
StatusCodes.FORBIDDEN and ErrorCode.NOT_FOUND, change the error code to
ErrorCode.INSUFFICIENT_PERMISSIONS (keep the existing message and status);
update the call in the route handler (the function returning
serviceErrorResponse in route.ts) so the error code matches the 403 semantics
and existing entitlement/plan denial conventions.
🧹 Nitpick comments (1)
packages/web/src/app/api/(server)/ee/permissionSyncStatus/route.ts (1)

1-1: Unnecessary 'use server' directive for route handlers.

Route handlers in Next.js App Router are server-side by default. The 'use server' directive is specifically for Server Actions (functions called from client components). This directive is unnecessary here and could cause confusion.

🔧 Suggested fix
-'use server';-
import { apiHandler } from "@/lib/apiHandler";

@brendan-kellam
brendan-kellam merged commit fb358d8 into mainFeb 4, 2026
8 of 9 checks passed
@brendan-kellam
brendan-kellam deleted the bkellam/fix-SOU-314 branch February 4, 2026 23:59
@github-actionsgithub-actionsBot mentioned this pull request Feb 4, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FR] Improve initial login experience during permission syncing (repo sync delay)

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(web): Add banner to notify user when permissions are syncing for the first time - #852

Merged
brendan-kellam merged 3 commits into
mainfrom
bkellam/fix-SOU-314
Feb 4, 2026
Merged

feat(web): Add banner to notify user when permissions are syncing for the first time#852
brendan-kellam merged 3 commits into
mainfrom
bkellam/fix-SOU-314

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Problem

There can be a delay between when a account is created and it's permissions are synced for the first time. This creates user confusion since all repositories will not be visible until this permission sync completes.

Solution

This PR adds a notification banner that is displayed at the top while permissions are syncing for the first time for the user.

permission-syncing.mp4

Fixes#817

Summary by CodeRabbit

  • New Features
    • Added an in-app notification banner that informs users when repository permissions are being synced for the first time.
    • Introduced a new alert UI component to standardize and improve informational and status messages across the app.
    • Updated entitlements to enable "anonymous-access" for the self-hosted Enterprise Unlimited plan.

@github-actions

This comment has been minimized.

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

Walkthrough

Adds a permission-sync notification banner and supporting API/UI: server route to report first-time permission sync status, client polling and banner component, new Alert UI primitives, entitlement update, and changelog entry.

Changes

Cohort / File(s)Summary
Changelog
CHANGELOG.md
Added Unreleased "Added" entry documenting the permission-sync notification banner (refs PR #852).
Entitlements
packages/shared/src/entitlements.ts
Updated plan entitlements: added anonymous-access to self-hosted:enterprise-unlimited; arrays reformatted to multiline.
Server API
packages/web/src/app/api/(server)/ee/permissionSyncStatus/route.ts
New GET route returning PermissionSyncStatusResponse { hasPendingFirstSync }; validates permission-syncing entitlement, queries accounts and latest permissionSyncJobs to determine pending-first-sync state; returns structured service errors for auth/entitlement failures.
Client API
packages/web/src/app/api/(client)/client.ts
Added getPermissionSyncStatus() client function calling /api/ee/permissionSyncStatus, returns typed PermissionSyncStatusResponse or ServiceError.
Permission Sync UI
packages/web/src/app/[domain]/components/permissionSyncBanner.tsx, packages/web/src/app/[domain]/layout.tsx
New PermissionSyncBanner component using react-query to poll status (conditional refetch), tracks prior state to trigger router.refresh() when sync completes; layout imports and conditionally renders banner based on session and permission-syncing entitlement.
UI primitives
packages/web/src/components/ui/alert.tsx
New Alert component suite (Alert, AlertTitle, AlertDescription, AlertAction) with variant styling and accessibility attributes; used by the banner.

Sequence Diagram(s)

sequenceDiagram
participant Browser as Browser/Client
participant Banner as PermissionSyncBanner
participant ReactQuery as React Query
participant APIClient as API Client
participant Server as Server API
participant DB as Database
Browser->>Banner: Mount
Banner->>ReactQuery: useQuery(getPermissionSyncStatus)
loop while hasPendingFirstSync
ReactQuery->>APIClient: getPermissionSyncStatus()
APIClient->>Server: GET /api/ee/permissionSyncStatus
Server->>DB: Query accounts + latest permissionSyncJobs
DB-->>Server: account sync data
Server-->>APIClient: PermissionSyncStatusResponse(hasPendingFirstSync)
APIClient-->>ReactQuery: response
ReactQuery-->>Banner: update status
alt pending
Banner->>Browser: show Alert banner (spinner)
else completed
Banner->>Browser: router.refresh(), hide banner
end
end
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

Suggested Reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe PR title clearly and specifically describes the main change: adding a banner to notify users when permissions are syncing for the first time, which directly aligns with the primary objective of the changeset.
Linked Issues check✅ PassedThe PR partially addresses issue #817 by providing visual feedback (a notification banner) during permission syncing, but does not implement pre-fetching/prioritizing repos or progress metrics as suggested in the feature request.
Out of Scope Changes check✅ PassedAll changes are directly related to implementing the permission sync banner feature: UI component, server endpoint, client API call, entitlements mapping, and layout integration. The new Alert component provides necessary UI foundation for the banner.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bkellam/fix-SOU-314

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.

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@packages/web/src/app/`[domain]/components/permissionSyncBanner.tsx:
- Around line 23-27: The refetchInterval callback currently checks
query.state.data for truthiness, but that is the raw response object and always
truthy once loaded, causing infinite polling; update the logic in the
refetchInterval function to inspect the hasPendingFirstSync property on the data
(e.g., return query.state.data?.hasPendingFirstSync ? POLL_INTERVAL_MS : false)
so polling continues only while hasPendingFirstSync is true; reference symbols:
refetchInterval, query.state.data, hasPendingFirstSync, POLL_INTERVAL_MS.
In `@packages/web/src/app/api/`(server)/ee/permissionSyncStatus/route.ts:
- Around line 16-18: Update the JSDoc comment on the permission sync route so
the grammar is correct: change "Returns whether a user has a account that has
it's permissions synced for the first time." to "Returns whether a user has an
account that has its permissions synced for the first time." — edit the comment
above the exported route handler in route.ts (the file-level JSDoc for the
permissionSyncStatus endpoint).
- Around line 23-27: Replace the incorrect error code used in the permission
sync route: in the code path that returns serviceErrorResponse with statusCode
StatusCodes.FORBIDDEN and ErrorCode.NOT_FOUND, change the error code to
ErrorCode.INSUFFICIENT_PERMISSIONS (keep the existing message and status);
update the call in the route handler (the function returning
serviceErrorResponse in route.ts) so the error code matches the 403 semantics
and existing entitlement/plan denial conventions.
🧹 Nitpick comments (1)
packages/web/src/app/api/(server)/ee/permissionSyncStatus/route.ts (1)

1-1: Unnecessary 'use server' directive for route handlers.

Route handlers in Next.js App Router are server-side by default. The 'use server' directive is specifically for Server Actions (functions called from client components). This directive is unnecessary here and could cause confusion.

🔧 Suggested fix
-'use server';-
import { apiHandler } from "@/lib/apiHandler";

@brendan-kellam
brendan-kellam merged commit fb358d8 into mainFeb 4, 2026
8 of 9 checks passed
@brendan-kellam
brendan-kellam deleted the bkellam/fix-SOU-314 branch February 4, 2026 23:59
@github-actionsgithub-actionsBot mentioned this pull request Feb 4, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FR] Improve initial login experience during permission syncing (repo sync delay)

1 participant

@brendan-kellam