Skip to content

Conversation

@faisalsiddique4400
Copy link
Contributor

@faisalsiddique4400 faisalsiddique4400 commented Dec 17, 2025

fix(admin-ui): improve Agama Flow status update handling to avoid long pending state (#2467)

Summary

Agama Flow status was remaining in the pending state for an extended period after deployment, causing confusion and making it difficult for users to determine whether processing had completed.

Fix Summary

  • Improved polling and state update logic for Agama Flow status.
  • Ensured the UI refreshes the flow status correctly after backend processing.
  • Prevented stale state rendering that caused prolonged pending status.
  • Improved synchronization between backend status updates and UI rendering.
  • Verified correct status transition from pending to processed.

Outcome

  • Agama Flow status now updates in a timely manner.
  • Users receive accurate and up-to-date flow status information.
  • Eliminates the need for manual page refreshes to observe status changes.

Closes

Closes: #2467

Summary by CodeRabbit

  • Chores
    • Optimized internal deployment flow for improved stability and maintainability.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 17, 2025

📝 Walkthrough

Walkthrough

Refactored the Agama project deployment flow in AgamaListPage.tsx by replacing React Query mutation abstractions with direct Axios API calls. Removed usePostAgamaPrj, getAgamaProject, and getGetAgamaProjectQueryKey imports and replaced their implementations with inline fetch, base64 decode, ZIP creation, and deployment posting logic.

Changes

Cohort / File(s) Summary
Agama Deployment Flow Refactor
admin-ui/plugins/auth-server/components/Agama/AgamaListPage.tsx
Replaced mutation-based deployment (usePostAgamaPrj) with direct Axios GET request to fetch repository data, base64 decoding, ZIP file blob creation, and direct POST to deployment endpoint. Updated state management for projectNameToUse, removed query key-based getters, and adjusted toast/modal/query invalidation cleanup logic.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Verify base64 decoding and ZIP blob construction logic is correct
  • Ensure error handling and cleanup (modals, state resets) works as expected on both success and failure paths
  • Validate that query invalidation properly refreshes Agama project list after deployment

Possibly related PRs

  • #2481: Modifies useGetAgamaPrj caching options on the same Agama project data-fetch code path
  • #2527: Also replaces mutation-based Agama project upload/deploy flow with direct Axios HTTP calls in AgamaListPage.tsx

Suggested labels

comp-admin-ui, kind-bug

Suggested reviewers

  • syntrydy
  • duttarnab

Poem

🐰 No more queries dancing in the night,
Direct Axios calls took flight!
Base64 blooms to ZIP we weave,
Deployment's fast—no need to grieve.
Old mutations fade, new flows bloom bright! 🌸

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title indicates fixing Agama Flow status update handling to avoid delays, which aligns with the main PR objective of addressing prolonged pending status issues.
Linked Issues check ✅ Passed The PR addresses issue #2467 by improving polling and state update logic for Agama Flow status, ensuring timely transitions from pending to processed state.
Out of Scope Changes check ✅ Passed Changes focus narrowly on the Agama Flow status update handling in AgamaListPage.tsx, replacing mutation logic with direct Axios calls for deployment, which aligns with the PR objectives.
✨ 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 admin-ui-issue-2467

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.

@mo-auto mo-auto added comp-admin-ui Component affected by issue or PR kind-bug Issue or PR is a bug in existing functionality labels Dec 17, 2025
@sonarqubecloud
Copy link

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
admin-ui/plugins/auth-server/components/Agama/AgamaListPage.tsx (1)

554-558: Improve error handling specificity and state cleanup consistency.

Two issues identified:

  1. Line 556: The error message "File not found or deployment failed" is too generic. It doesn't differentiate between download failure, base64 decode failure, or deployment POST failure, making it difficult for users to understand what went wrong.

  2. Line 557: Inconsistent state cleanup—setRepoName(null) is called in the success path (line 552) but not in the error path. This leaves stale state after an error, potentially confusing users who see the previously selected repository still selected.

Apply this diff to improve error handling:

     } catch (error) {
       console.error('Error deploying project:', error)
-      toast.error('File not found or deployment failed')
+      const errorMessage = error instanceof Error ? error.message : 'Failed to deploy project'
+      toast.error(errorMessage)
       setFileLoading(false)
+      setRepoName(null)
     }
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 646a816 and 365df6f.

📒 Files selected for processing (1)
  • admin-ui/plugins/auth-server/components/Agama/AgamaListPage.tsx (1 hunks)
🔇 Additional comments (4)
admin-ui/plugins/auth-server/components/Agama/AgamaListPage.tsx (4)

516-517: LGTM!

The project name extraction and state update are correct.


534-542: LGTM!

The Blob/File creation and deployment POST request are implemented correctly. Good use of encodeURIComponent for the project name in the URL path.


544-553: LGTM!

Success handling is comprehensive with proper toast notification, query invalidation, audit logging, and state cleanup.


502-559: Clarify how single query invalidation addresses long-pending status updates without continuous polling.

The handleDeploy function calls queryClient.invalidateQueries() after deployment, which triggers a single refetch. However, the PR objectives mention "fixing polling and state update logic to avoid long pending state," yet no polling mechanism (refetchInterval or polling loop) exists in the code. Status is computed based on whether finishedAt is set by the backend.

If backend processing is asynchronous, a single refetch won't continuously check status until completion. Clarify:

  • Whether the deployment endpoint now responds after processing completes (synchronous), or
  • If polling was added in a related component or hook that isn't visible in this change

Comment on lines +520 to +532
const downloadResponse = await AXIOS_INSTANCE.get(`/api/v1/agama-repo/download`, {
params: { downloadLink: downloadUrl },
})

if (!downloadResult) {
if (!downloadResponse.data) {
throw new Error('Failed to download project')
}
const base64Data = downloadResponse.data as string
const binaryString = atob(base64Data)
const bytes = new Uint8Array(binaryString.length)
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Add type validation and error handling for base64 decoding.

The code has critical type safety and error handling gaps:

  1. Line 527: Type assertion as string is unsafe. If the backend returns a non-string (e.g., error JSON object, null, array), the code will fail at line 528.
  2. Line 528: atob() will throw an InvalidCharacterError if the input is not valid base64, but there's no try-catch around this specific operation. The outer try-catch at line 519 will catch it, but the error message at line 556 won't distinguish between download failure and decoding failure.
  3. Line 524: The check if (!downloadResponse.data) is insufficient—it won't catch empty strings or invalid formats.

If the backend returns an error response (e.g., {"error": "not found"}), the code will attempt to decode it as base64 and throw a cryptic error.

Apply this diff to add proper validation:

     try {
       const downloadResponse = await AXIOS_INSTANCE.get(`/api/v1/agama-repo/download`, {
         params: { downloadLink: downloadUrl },
       })
 
-      if (!downloadResponse.data) {
+      if (!downloadResponse.data || typeof downloadResponse.data !== 'string') {
+        throw new Error('Invalid response from download endpoint')
+      }
+      
+      if (downloadResponse.data.trim().length === 0) {
         throw new Error('Failed to download project')
       }
+      
       const base64Data = downloadResponse.data as string
+      
+      // Validate base64 format before decoding
+      try {
-      const binaryString = atob(base64Data)
+        const binaryString = atob(base64Data)
-      const bytes = new Uint8Array(binaryString.length)
-      for (let i = 0; i < binaryString.length; i++) {
-        bytes[i] = binaryString.charCodeAt(i)
-      }
+        const bytes = new Uint8Array(binaryString.length)
+        for (let i = 0; i < binaryString.length; i++) {
+          bytes[i] = binaryString.charCodeAt(i)
+        }
+      } catch (decodeError) {
+        console.error('Base64 decode error:', decodeError)
+        throw new Error('Invalid base64 data received from server')
+      }
🤖 Prompt for AI Agents
In admin-ui/plugins/auth-server/components/Agama/AgamaListPage.tsx around lines
520 to 532, validate that downloadResponse.data is a non-empty string before
treating it as base64 (e.g., typeof check and trim length), and if invalid throw
a descriptive error; wrap the atob(base64Data) call in its own try-catch to
catch InvalidCharacterError and rethrow a clear "Invalid base64 data" error (or
return a specific failure), and ensure any thrown errors are distinguishable
from network/download failures so the outer error handling can report whether
the failure was downloading, empty/invalid type, or base64 decoding.

Comment on lines +538 to +542
await AXIOS_INSTANCE.post(
`/api/v1/agama-deployment/${encodeURIComponent(projectNameToUse)}`,
projectFile,
{ headers: { 'Content-Type': 'application/zip' } },
)
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider extracting shared deployment logic into a reusable function.

The deployment POST logic here (lines 538-542) is duplicated in the submitData function (lines 201-205). Both functions:

  • POST to /api/v1/agama-deployment/${encodeURIComponent(projectName)}
  • Use identical headers: { 'Content-Type': 'application/zip' }
  • Have similar success handling (toast, query invalidation, audit logging, state cleanup)

Consider extracting the common deployment logic:

const deployAgamaProject = async (projectName: string, projectFile: File): Promise<void> => {
  await AXIOS_INSTANCE.post(
    `/api/v1/agama-deployment/${encodeURIComponent(projectName)}`,
    projectFile,
    { headers: { 'Content-Type': 'application/zip' } },
  )
  dispatch(updateToast(true, 'success'))
  await queryClient.invalidateQueries({ queryKey: getGetAgamaPrjQueryKey() })
  await logAgamaCreation({} as Deployment, `Deployed Agama project: ${projectName}`)
}

Then both submitData and handleDeploy can call this shared function, reducing duplication and improving maintainability.

🤖 Prompt for AI Agents
In admin-ui/plugins/auth-server/components/Agama/AgamaListPage.tsx around lines
201-205 and 538-542, the POST + success handling for deploying an Agama project
is duplicated; extract that logic into a single async helper (e.g.,
deployAgamaProject(projectName: string, projectFile: File)): it should perform
the AXIOS_INSTANCE.post to
`/api/v1/agama-deployment/${encodeURIComponent(projectName)}` with headers
'Content-Type: application/zip', dispatch the success toast, invalidate the
getAgama project query via
queryClient.invalidateQueries(getGetAgamaPrjQueryKey()), call
logAgamaCreation/audit with the project name, and return or throw errors as
appropriate; then replace the duplicated blocks in submitData (lines ~201-205)
and handleDeploy (lines 538-542) to call this helper and keep any
caller-specific state cleanup (e.g., clearing selected file or closing modal) in
the callers.

@duttarnab duttarnab merged commit 0526cb4 into main Dec 17, 2025
10 checks passed
@duttarnab duttarnab deleted the admin-ui-issue-2467 branch December 17, 2025 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp-admin-ui Component affected by issue or PR kind-bug Issue or PR is a bug in existing functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

flex(admin-ui): agama-flow status change taking lot of time

4 participants