Skip to content

force db sync button#1167

Merged
N2D4 merged 1 commit intodevfrom
force-db-sync-button
Feb 9, 2026
Merged

force db sync button#1167
N2D4 merged 1 commit intodevfrom
force-db-sync-button

Conversation

@BilalG1
Copy link
Copy Markdown
Collaborator

@BilalG1 BilalG1 commented Feb 9, 2026

Summary by CodeRabbit

  • New Features

    • Manual force sync capability with Run Now and Cancel buttons on the external DB sync dashboard
    • Real-time sync status indicator displaying current Running or Idle state
    • Additional sync control options for enhanced granular management
  • UI Improvements

    • Reorganized external DB sync dashboard with improved responsive grid layout for better usability

@vercel
Copy link
Copy Markdown

vercel bot commented Feb 9, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
stack-backend Ready Ready Preview, Comment Feb 9, 2026 5:59pm
stack-dashboard Ready Ready Preview, Comment Feb 9, 2026 5:59pm
stack-demo Ready Ready Preview, Comment Feb 9, 2026 5:59pm
stack-docs Ready Ready Preview, Comment Feb 9, 2026 5:59pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 9, 2026

📝 Walkthrough

Walkthrough

External DB sync endpoints (poller and sequencer) now support admin/internal authorization bypass, allowing privileged access without the CRON secret. The authorization header becomes optional in request schemas. A dashboard UI component adds manual force sync controls with trigger and cancellation capabilities, reloading status upon completion.

Changes

Cohort / File(s) Summary
Backend API Route Auth Updates
apps/backend/src/app/api/latest/internal/external-db-sync/poller/route.ts, apps/backend/src/app/api/latest/internal/external-db-sync/sequencer/route.ts
Both routes now accept an auth parameter in handler signatures. Authorization header changed from required to optional. New admin/internal bypass condition: if auth.type === "admin" and auth.project.id === "internal", access allowed without CRON secret; otherwise, Authorization header must match CRON secret.
Dashboard Force Sync UI
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/external-db-sync/page-client.tsx
Added forceSyncRunning state and forceSyncAbortRef to manage manual sync operations. New forceTriggerSync function triggers poller and sequencer endpoints in parallel with AbortController-based cancellation. New cancelForceSync function aborts in-progress syncs. UI restructured into responsive grid with expanded Fusebox card (sequencer/poller switches) and new Force Sync card displaying status and run/cancel actions.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Client as Dashboard Client
    participant Seq as Sequencer Endpoint
    participant Poll as Poller Endpoint
    participant Status as Status Reload

    User->>Client: Click "Run Now" (force sync)
    Client->>Client: Create AbortController
    Client->>Seq: POST /sequencer (parallel)
    Client->>Poll: POST /poller (parallel)
    Seq-->>Client: Response
    Poll-->>Client: Response
    Client->>Status: Reload sync status
    Status-->>Client: Updated status
    Client->>Client: Reset forceSyncRunning, clear abort ref
    Client-->>User: Display updated status
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Poem

🐰 A rabbit hops through sync endpoints with glee,
Admin bypasses and parallel calls, so free!
Force sync buttons now sparkle and shine,
With cancel controls that work just fine,
The dashboard rejoices, no more delays,
External DB harmony brightens the days! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is empty except for the CONTRIBUTING.md comment template, with no substantive information about the changes, motivation, or implementation details. Add a detailed description explaining what the force sync button does, why it was added, how it works with the backend endpoints, and any relevant testing or behavioral notes.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'force db sync button' accurately describes the primary change—adding a manual force sync button to the external DB sync UI in the dashboard.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ 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 force-db-sync-button

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.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Feb 9, 2026

Greptile Overview

Greptile Summary

This PR adds a "Force Sync" button to the external DB sync dashboard that allows admin users to manually trigger the sequencer and poller endpoints.

Key Changes:

  • Modified poller and sequencer route handlers to accept admin authentication from the internal project in addition to the existing CRON_SECRET bearer token
  • Removed unused getLocalApiBaseUrl function from poller route
  • Added new Force Sync UI card with manual trigger functionality that calls both endpoints in parallel
  • Implemented proper abort controller for cancellation, loading states, and error handling using runAsynchronouslyWithAlert

Architecture:
The force sync feature integrates well with the existing authentication model. The endpoints now support dual authentication: either via CRON_SECRET (for automated cron jobs) or via admin auth for the internal project (for manual dashboard triggers). The dashboard implementation correctly uses adminApp[stackAppInternalsSymbol].sendRequest with "admin" request type to authenticate.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The changes are straightforward and follow existing patterns. The authentication logic properly restricts access to admin users of the internal project or cron jobs. The dashboard implementation uses recommended patterns (runAsynchronouslyWithAlert, proper abort controller). The only minor issue is an extra blank line that doesn't affect functionality.
  • No files require special attention

Important Files Changed

Filename Overview
apps/backend/src/app/api/latest/internal/external-db-sync/poller/route.ts Modified auth to allow admin users from internal project to trigger the poller endpoint in addition to cron jobs. Removed unused getLocalApiBaseUrl function. Has minor formatting issue (extra blank line).
apps/backend/src/app/api/latest/internal/external-db-sync/sequencer/route.ts Modified auth to allow admin users from internal project to trigger the sequencer endpoint in addition to cron jobs. Clean implementation matching the pattern in poller route.
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/external-db-sync/page-client.tsx Added Force Sync UI card with manual trigger button that calls both sequencer and poller endpoints in parallel. Includes proper abort controller, loading states, and error handling following best practices.

Sequence Diagram

sequenceDiagram
    participant User as Admin User
    participant Dashboard as Dashboard UI
    participant Poller as Poller Endpoint
    participant Sequencer as Sequencer Endpoint
    participant DB as Database

    User->>Dashboard: Click "Run Now" button
    Dashboard->>Dashboard: Create AbortController
    Dashboard->>Dashboard: Set forceSyncRunning = true
    
    par Parallel Sync
        Dashboard->>Sequencer: GET /internal/external-db-sync/sequencer<br/>(with admin auth)
        Sequencer->>Sequencer: Verify isAdmin OR CRON_SECRET
        Sequencer->>DB: Backfill sequence IDs
        Sequencer-->>Dashboard: Return {ok: true, iterations}
    and
        Dashboard->>Poller: GET /internal/external-db-sync/poller<br/>(with admin auth)
        Poller->>Poller: Verify isAdmin OR CRON_SECRET
        Poller->>DB: Claim pending requests
        Poller-->>Dashboard: Return {ok: true, requests_processed}
    end
    
    Dashboard->>Dashboard: Load updated status
    Dashboard->>Dashboard: Set forceSyncRunning = false
    Dashboard-->>User: Display updated sync status
Loading

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

3 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Copy link
Copy Markdown
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: 1

🤖 Fix all issues with AI agents
In
`@apps/dashboard/src/app/`(main)/(protected)/projects/[projectId]/external-db-sync/page-client.tsx:
- Around line 346-375: The forceTriggerSync callback is calling the sequencer
and poller endpoints without stopWhenIdle, causing requests to hang up to
DEFAULT_MAX_DURATION_MS; update the endpoints used in forceTriggerSync (the
endpoints array and the sendRequest calls inside the map) to include the query
param stopWhenIdle=true (e.g. append "?stopWhenIdle=true" or use
URLSearchParams) so the backend stops immediately when idle; ensure
abortController.signal is still passed and keep error handling and loadStatus()
as-is.
🧹 Nitpick comments (1)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/external-db-sync/page-client.tsx (1)

759-761: saveFusebox is an async function invoked directly in onClick — consider wrapping with runAsynchronouslyWithAlert.

saveFusebox is async and its errors are handled internally via setError, but if an unexpected error is thrown (e.g., network failure before Result.fromPromise is entered), it would become an unhandled promise rejection. Per coding guidelines, async handlers should be wrapped with runAsynchronouslyWithAlert to avoid voided promises.

Proposed fix
-                  <Button onClick={saveFusebox} disabled={!fuseboxDirty || savingFusebox} loading={savingFusebox}>
+                  <Button onClick={() => runAsynchronouslyWithAlert(saveFusebox)} disabled={!fuseboxDirty || savingFusebox} loading={savingFusebox}>

Based on learnings: "In the stack-auth codebase, use runAsynchronouslyWithAlert from stackframe/stack-shared/dist/utils/promises for async button click handlers and form submissions instead of manual try/catch blocks."

@N2D4 N2D4 merged commit 2072dd4 into dev Feb 9, 2026
35 of 38 checks passed
@N2D4 N2D4 deleted the force-db-sync-button branch February 9, 2026 18:54
Sign up for free to 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.

2 participants