Skip to content

fix(providers): expose unhealthy data sources - #2270

Merged
Asherlc merged 5 commits into
mainfrom
Asherlc/issue-2071-provider-health
Jul 29, 2026
Merged

Asherlc merged 5 commits into
mainfrom
Asherlc/issue-2071-provider-health

Conversation

@Asherlc

@Asherlc Asherlc commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Summary

  • separate provider connection state from authorization health on web and iOS
  • promote the existing provider-specific reconnect flow when credentials need renewal
  • keep per-dataset processing failures, last-ready freshness, and actionable server errors visible on provider and downstream metric screens

Validation

  • pnpm test:changed (907 files, 14,322 tests)
  • pnpm typecheck
  • pnpm lint code/policy gates
  • pnpm lint:analytics-sql with workspace-isolated ClickHouse
  • pnpm --dir packages/web build
  • pnpm --dir packages/web build-storybook
  • pnpm --dir packages/mobile build-storybook

Fixes #2071

Summary by Sourcery

Clarify provider connection versus authorization health across web and mobile and surface dataset-level processing problems and freshness on provider and metric screens.

New Features:

  • Expose provider connection and authorization health indicators, including reconnect requirements, on web and mobile provider detail views.
  • Add dataset-level status, freshness, and actionable error messaging to processing status widgets for providers and downstream metric views.
  • Introduce provider health utilities for consistent connection and authorization state derivation across platforms.

Enhancements:

  • Reuse existing provider-specific reconnect flows via new auth modals on web and the primary action on mobile when credentials need renewal.
  • Ensure processing status cards can render additional dataset details while maintaining recompute-only views when no dataset issues exist.

Tests:

  • Extend web and mobile processing status widget tests to cover failed and blocked datasets, freshness display, and synthetic ready cases.
  • Add provider detail page tests on web and mobile to validate separated connection/authorization states, reconnect promotion, and visible freshness.
  • Add unit tests for provider health computation and dataset error/status labeling in providers-meta.

Summary by cubic

Separate provider connection status from authorization health and surface unhealthy datasets with freshness and actionable errors on web and iOS. Fixes #2071 and promotes clear reconnect flows to restore data sync.

  • New Features

    • Added @dofek/providers/provider-health with Connection/Authorization indicators and requiresReconnect.
    • Provider Detail shows Connection and Authorization separately; promotes “Reconnect” when needed (web uses provider-specific modals for token/credential/Garmin/WHOOP; mobile uses the primary action).
    • Processing status surfaces failed/blocked datasets with status labels, “Last ready” freshness, and the latest actionable error; alwaysVisible still shows readiness/freshness when overall status is ready.
  • Bug Fixes

    • Expired authorization no longer appears healthy when a connection exists (e.g., “Connected” + “Reconnect required”).
    • Unhealthy datasets and their freshness remain visible on provider pages and downstream metric screens, including when overall status is failed or blocked.
    • Prevent misleading freshness on synthetic “ready” datasets without processing history.

Written for commit 9993703. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added separate Connection and Authorization status indicators on provider detail pages.
    • Added provider-specific reconnect actions and reconnect forms when authorization is required.
    • Added detailed processing status information, including dataset status, freshness timestamps, and error messages.
    • Processing status now remains visible for failed or blocked datasets and on applicable downstream screens.
  • Bug Fixes

    • Improved handling of ready datasets so freshness information displays consistently.
    • Prevented synthetic completed datasets from showing misleading freshness details.

Separate connection from authorization health and surface dataset failures and freshness on web and iOS.

Fixes #2071
Copilot AI review requested due to automatic review settings July 29, 2026 02:27
@Asherlc Asherlc linked an issue Jul 29, 2026 that may be closed by this pull request
@cursor

cursor Bot commented Jul 29, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@codereviewbot-ai

Copy link
Copy Markdown

🤖 Review skipped: Repository rate limit exceeded. Free accounts are limited to 2 reviews per 4 hours per repository. Upgrade to a paid plan for unlimited reviews.

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@sourcery-ai sourcery-ai Bot 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.

Sorry @Asherlc, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@sourcery-ai

sourcery-ai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Separates provider connection vs authorization health across web and mobile, introduces a reusable provider-health model, enhances processing status widgets to always expose unhealthy datasets with freshness and actionable errors, and wires reconnect-specific flows and UI (including modals and buttons) for various auth types while extending tests and stories.

Flow diagram for providerHealth connection and authorization status computation

flowchart TD
  A[providerHealth input
  authorized
  needsReauth
  requiresAuthorization] --> B{authorized?}

  B -->|true| C[connection = Connected
  status = healthy]
  B -->|false| D[connection = Not connected
  status = neutral]

  C --> E{needsReauth?}
  D --> E

  E -->|true| F[authorization = Reconnect required
  status = warning
  requiresReconnect = true]
  E -->|false| G{requiresAuthorization?}

  G -->|true| H{authorized?}
  G -->|false| I[authorization = Not required
  status = neutral
  requiresReconnect = false]

  H -->|true| J[authorization = Active
  status = healthy
  requiresReconnect = false]
  H -->|false| K[authorization = Not connected
  status = neutral
  requiresReconnect = false]

  F:::out
  I:::out
  J:::out
  K:::out

  classDef out fill:#e3f2fd,stroke:#1e88e5,stroke-width:1;
Loading

File-Level Changes

Change Details Files
Introduce shared provider health model and expose it in web and mobile provider detail screens, including reconnect UX.
  • Add provider-health helper and export from providers-meta to derive connection and authorization indicators plus reconnect requirement from provider state.
  • Use providerHealth in web ProviderDetailPage to render separate Connection/Authorization labels, compute when reconnect is required, and show a reconnect button wired to auth-type-specific reconnect flows/modals.
  • Use providerHealth in mobile ProviderDetailScreen to render separate Connection/Authorization labels, adjust reconnect primary action button, and keep sync controls hidden when reconnect is needed while still showing last sync info.
packages/providers-meta/src/provider-health.ts
packages/providers-meta/src/provider-health.test.ts
packages/providers-meta/package.json
packages/web/src/pages/ProviderDetailPage.tsx
packages/web/src/pages/ProviderDetailPage.test.tsx
packages/mobile/app/providers/[id].tsx
packages/mobile/app/providers/[id].test.tsx
Promote provider-specific reconnect flows and auth modals on web for multiple auth types.
  • Introduce reconnectModal state and handlers in ProviderDetailPage to select reconnect UX based on authType (credential, token, Garmin, WHOOP, oauth/oauth1).
  • Wire CredentialAuthModal, GarminAuthModal, TokenAuthModal, and WhoopAuthModal into ProviderDetailPage, including success handling that invalidates sync and processing TRPC queries.
  • Adjust sync controls heading and visibility so they become 'Connection Controls' and hide sync actions when a reconnect is required, while keeping disconnect available.
packages/web/src/pages/ProviderDetailPage.tsx
packages/web/src/pages/ProviderDetailPage.test.tsx
packages/web/src/components/DataSourcesAuthModals.tsx
Expose processing status details for unhealthy and ready datasets, including per-dataset freshness and actionable errors, across web and mobile widgets, cards, tests, and stories.
  • Extend providers-meta processing-status with helpers to derive dataset-level error messages from operation timelines and to map dataset statuses to display labels.
  • Update web and mobile ProcessingStatusWidget components to always render when unhealthy, optionally always-visible, and to list relevant datasets with status label, last-ready freshness (using formatRelativeTime), and dataset-specific actionable errors.
  • Allow SourceProcessingStatusCard (web and mobile) to accept children so dataset details can be nested; adjust recompute-only path to short-circuit when there are no visible dataset details.
  • Expand unit tests for web/mobile ProcessingStatusWidget to cover failed/blocked datasets, freshness display, downstream metric scopes, and synthetic ready datasets without history; update stories to include failed and ready cases with dataset timelines.
  • Ensure provider pages pass alwaysVisible to their ProcessingStatusWidget instances so dataset freshness and errors stay visible on provider and downstream screens.
packages/providers-meta/src/processing-status.ts
packages/providers-meta/src/processing-status.test.ts
packages/web/src/components/ProcessingStatusWidget.tsx
packages/web/src/components/ProcessingStatusWidget.test.tsx
packages/web/src/components/ProcessingStatusWidget.stories.tsx
packages/web/src/components/SourceProcessingStatusCard.tsx
packages/mobile/components/ProcessingStatusWidget.tsx
packages/mobile/components/ProcessingStatusWidget.test.tsx
packages/mobile/components/ProcessingStatusWidget.stories.tsx
packages/mobile/components/SourceProcessingStatusCard.tsx
packages/mobile/app/providers/[id].tsx
packages/mobile/app/providers/[id].test.tsx

Assessment against linked issues

Issue Objective Addressed Explanation
#2071 Separate provider connection state from authorization health so that an expired or failed authorization no longer appears as simply 'Connected' in the UI.
#2071 Expose per-dataset sync health and freshness (status, last-ready age, actionable errors) on provider and downstream metric screens so a generic 'Connected' state cannot mask failed or stale datasets.
#2071 Promote provider-specific reconnect flows when credentials fail (e.g., WHOOP, Garmin, token, credential flows) and suppress normal sync controls until reconnection.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Expose provider authorization and dataset health

🐞 Bug fix ✨ Enhancement 🧪 Tests 🕐 40+ Minutes

Grey Divider

AI Description

• Separate provider connection and authorization health across web and mobile detail screens.
• Route expired credentials through provider-specific reconnect flows while suppressing sync
 controls.
• Surface dataset failures, actionable errors, and last-ready freshness throughout processing status
 views.
Diagram

graph TD
  A["Provider state"] --> B["Health utility"] --> C["Web detail"]
  B --> D["Mobile detail"]
  E["Processing snapshot"] --> F["Status utilities"] --> G["Web widget"]
  F --> H["Mobile widget"]
Loading
High-Level Assessment

The shared presentation-utility approach is appropriate because web and mobile consume the same existing provider and processing fields while retaining platform-specific reconnect UI. Duplicating derivation logic per platform would invite drift, while adding server-computed presentation labels would unnecessarily couple the API to client wording.

Files changed (17) +1050 / -128

Enhancement (2) +8 / -0
SourceProcessingStatusCard.tsxAllow nested mobile processing details +4/-0

Allow nested mobile processing details

• Adds a children slot so processing cards can render dataset-level status details before progress.

packages/mobile/components/SourceProcessingStatusCard.tsx

SourceProcessingStatusCard.tsxAllow nested web processing details +4/-0

Allow nested web processing details

• Adds a children slot for dataset-level content within the shared processing status card.

packages/web/src/components/SourceProcessingStatusCard.tsx

Bug fix (6) +451 / -119
[id].tsxExpose mobile authorization health and reconnect actions +50/-19

Expose mobile authorization health and reconnect actions

• Displays connection and authorization as distinct provider health indicators. Promotes the existing primary reconnect flow for expired credentials and keeps processing freshness visible.

packages/mobile/app/providers/[id].tsx

ProcessingStatusWidget.tsxRender mobile dataset failures and freshness +65/-8

Render mobile dataset failures and freshness

• Stops hiding failed and blocked processing snapshots. Adds per-dataset status, last-ready freshness, and the latest applicable processing error while preserving compact recompute-only views.

packages/mobile/components/ProcessingStatusWidget.tsx

processing-status.tsAdd shared dataset status presentation helpers +43/-0

Add shared dataset status presentation helpers

• Adds helpers that map dataset statuses to user-facing labels and select the latest relevant actionable failure from operation timelines.

packages/providers-meta/src/processing-status.ts

provider-health.tsDerive connection and authorization health separately +40/-0

Derive connection and authorization health separately

• Introduces a shared health model that independently describes connection and authorization states and identifies reconnect requirements.

packages/providers-meta/src/provider-health.ts

ProcessingStatusWidget.tsxRender web dataset failures and freshness +39/-8

Render web dataset failures and freshness

• Makes failed and blocked snapshots visible with per-dataset status, last-ready age, and actionable errors. Retains compact recompute rendering when no dataset details are relevant.

packages/web/src/components/ProcessingStatusWidget.tsx

ProviderDetailPage.tsxPromote provider-specific web reconnect flows +214/-84

Promote provider-specific web reconnect flows

• Separates connection from authorization health and presents reconnect as the primary action when credentials expire. Reuses OAuth, credential, token, Garmin, and WHOOP authentication flows, suppresses sync controls until recovery, and keeps dataset health visible.

packages/web/src/pages/ProviderDetailPage.tsx

Tests (8) +590 / -9
[id].test.tsxCover mobile provider health and freshness states +37/-3

Cover mobile provider health and freshness states

• Updates reconnect expectations for separate connection and authorization indicators. Adds coverage ensuring ready dataset freshness remains visible on provider details.

packages/mobile/app/providers/[id].test.tsx

ProcessingStatusWidget.stories.tsxAdd realistic failed and ready processing stories +47/-2

Add realistic failed and ready processing stories

• Expands Storybook fixtures with dataset failures, actionable server errors, and ready-state freshness.

packages/mobile/components/ProcessingStatusWidget.stories.tsx

ProcessingStatusWidget.test.tsxTest mobile dataset health details +126/-1

Test mobile dataset health details

• Covers failed and blocked datasets, actionable errors, last-ready age, downstream metric failures, and synthetic ready datasets without history.

packages/mobile/components/ProcessingStatusWidget.test.tsx

processing-status.test.tsTest dataset error selection and labels +78/-0

Test dataset error selection and labels

• Verifies latest applicable failed-event selection, message fallback behavior, dataset isolation, and all display-status labels.

packages/providers-meta/src/processing-status.test.ts

provider-health.test.tsTest provider health derivation +60/-0

Test provider health derivation

• Covers healthy providers, expired authorization with retained or removed connections, and providers that require no authorization.

packages/providers-meta/src/provider-health.test.ts

ProcessingStatusWidget.stories.tsxAdd realistic web processing health stories +47/-2

Add realistic web processing health stories

• Expands Storybook fixtures with failed dataset errors and ready dataset freshness.

packages/web/src/components/ProcessingStatusWidget.stories.tsx

ProcessingStatusWidget.test.tsxTest web dataset health details +119/-0

Test web dataset health details

• Covers failed and blocked datasets, actionable errors, freshness, downstream metric failures, and synthetic ready datasets without history.

packages/web/src/components/ProcessingStatusWidget.test.tsx

ProviderDetailPage.test.tsxCover web reconnect health and freshness behavior +76/-1

Cover web reconnect health and freshness behavior

• Tests separated connection and authorization states, promoted provider-specific reconnect modals, hidden sync controls, and persistent ready freshness.

packages/web/src/pages/ProviderDetailPage.test.tsx

Other (1) +1 / -0
package.jsonExport the provider health utility +1/-0

Export the provider health utility

• Adds the provider-health module to the package export map for web and mobile consumers.

packages/providers-meta/package.json

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Provider health is separated into connection and authorization states, reconnect flows use provider-specific modals, and web/mobile processing widgets now expose dataset status, freshness, and failure details.

Changes

Provider health and reconnect flow

Layer / File(s) Summary
Health model and provider reconnect flow
packages/providers-meta/src/provider-health.ts, packages/web/src/pages/ProviderDetailPage.tsx, packages/mobile/app/providers/[id].tsx, related tests
Provider detail screens show separate connection and authorization states, promote reconnect actions for reauthorization, route to provider-specific reconnect modals, and pass persistent dataset visibility to processing widgets.

Dataset processing status

Layer / File(s) Summary
Processing helpers and card content
packages/providers-meta/src/processing-status.ts, packages/*/components/SourceProcessingStatusCard.tsx, related tests
Shared helpers select dataset-specific failure messages and map processing statuses to display labels; status cards accept nested content.
Web dataset status rendering
packages/web/src/components/ProcessingStatusWidget.tsx, packages/web/src/components/ProcessingStatusWidget.stories.tsx, packages/web/src/components/ProcessingStatusWidget.test.tsx
The web widget renders failed, blocked, and historical datasets with status labels, freshness, and timeline error messages.
Mobile dataset status rendering
packages/mobile/components/ProcessingStatusWidget.tsx, packages/mobile/components/ProcessingStatusWidget.stories.tsx, packages/mobile/components/ProcessingStatusWidget.test.tsx
The mobile widget applies the same dataset-level status, freshness, failure, and history-aware rendering behavior.

Estimated code review effort: 4 (Complex) | ~45 minutes

Assessment against linked issues

Objective Addressed Explanation
Separate connection, authorization, dataset sync health, and freshness; promote reconnect for failed credentials [#2071]
Prevent a connected provider from masking failed or stale datasets, including downstream metric surfaces [#2071]

Sequence Diagram(s)

sequenceDiagram
  participant ProviderDetailPage
  participant providerHealth
  participant ProcessingStatusWidget
  participant DataSourcesAuthModals
  ProviderDetailPage->>providerHealth: derive connection and authorization status
  providerHealth-->>ProviderDetailPage: return health and reconnect requirement
  ProviderDetailPage->>ProcessingStatusWidget: render dataset status and freshness
  ProviderDetailPage->>DataSourcesAuthModals: open provider-specific reconnect form
Loading

Possibly related PRs

  • Asherlc/dofek#1870: Updates the mobile processing-status UI and related provider-detail integrations.

Suggested labels: area/mobile, area/web, type/bug

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise, imperative, and clearly reflects the provider-health and reconnect work in this changeset.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks

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.

@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Mobile Preview

Scan to open on device:

QR code for dofek://preview/pr-2270

Channel pr-2270
Deep Link dofek://preview/pr-2270
Commit 1a32ec8

To test on device:

  1. Build and install the preview client: PREVIEW_CHANNEL=pr-2270 pnpm expo prebuild --clean -p ios
  2. Or tap deep link on an existing preview build: dofek://preview/pr-2270

Each PR gets its own channel. Build a preview client with PREVIEW_CHANNEL=pr-{N} to test.

@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Storybook previews for 1a32ec87 are ready:

This comment updates automatically on each PR push.

@qodo-code-review

qodo-code-review Bot commented Jul 29, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (1) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 182 rules

Grey Divider


Action required

1. Stale failures shown as current ✓ Resolved 🐞 Bug ≡ Correctness
Description
processingDatasetErrorMessage chooses the newest retained failure across all operations rather
than the operation determining the dataset’s current status. A recovered ready dataset can therefore
show an old red error, and an operation-level failure from another dataset can be misattributed.
Code

packages/providers-meta/src/processing-status.ts[R175-181]

+  const failedEvent = operations
+    .flatMap((operation) => operation.timeline)
+    .filter(
+      (event) =>
+        event.status === "failed" && (event.datasetKey === null || event.datasetKey === datasetKey),
+    )
+    .sort((left, right) => right.occurredAt.localeCompare(left.occurredAt))[0];
Relevance

⭐⭐⭐ High

Recovery-aware processing behavior was previously accepted; stale failures directly undermine this
PR’s stated visibility goal.

PR-#1868

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The repository derives each dataset’s current status from its first/latest relevant operation but
returns all retained operations to clients. Both widgets call the new helper for every
history-bearing dataset when always visible, while the helper flattens all timelines without
checking operation membership or whether the dataset remains unhealthy.

packages/server/src/repositories/processing-repository.ts[225-290]
src/processing/processing-event-store.ts[647-708]
packages/web/src/components/ProcessingStatusWidget.tsx[104-126]
PR-#1868

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`processingDatasetErrorMessage` searches all retained operations, allowing historical or unrelated operation-level failures to appear as current dataset errors. Select errors only from the operation that determines the dataset's current failed or blocked state, and do not show failure messages for ready datasets.

## Issue Context
Processing status retains up to 20 operations from 90 days, while current dataset status is derived from the latest relevant operation. Add regression coverage for an older failed operation followed by a newer successful operation and for null-key failures belonging to operations that do not contain the displayed dataset.

## Fix Focus Areas
- packages/providers-meta/src/processing-status.ts[171-182]
- packages/web/src/components/ProcessingStatusWidget.tsx[101-126]
- packages/mobile/components/ProcessingStatusWidget.tsx[92-117]
- packages/providers-meta/src/processing-status.test.ts[169-230]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Global processing status invalidation ✓ Resolved 📘 Rule violation ➹ Performance
Description
The reconnect success handler calls processing.status.invalidate() without an input, invalidating
every cached processing-status query even though only one provider was reconnected. This causes
unrelated provider and metric views to refetch instead of targeting the affected provider key.
Code

packages/web/src/pages/ProviderDetailPage.tsx[283]

+    trpcUtils.processing.status.invalidate();
Relevance

⭐⭐⭐ High

Close accepted precedent favors provider-scoped processing status operations over global cache
behavior.

PR-#1869

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1540840 requires cache invalidations to specify selectors tied to the affected
resource. The changed handler omits the processing.status input, while the procedure schema and
client hook show that status caches are differentiated by providerId and datasets.

Rule 1540840: Target cache invalidation to affected query keys only
packages/web/src/pages/ProviderDetailPage.tsx[280-284]
packages/server/src/routers/processing.ts[24-27]
packages/web/src/hooks/useProcessingStatus.ts[4-19]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The reconnect success handler globally invalidates all `processing.status` query variants.

## Issue Context
The status procedure accepts `providerId` and `datasets` as query-key inputs. A reconnect applies to the current provider, so its invalidation should be scoped to that provider rather than refetching unrelated metric and provider status queries.

## Fix Focus Areas
- packages/web/src/pages/ProviderDetailPage.tsx[280-284]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Provider health export undocumented 📘 Rule violation ⚙ Maintainability
Description
The PR adds the public ./provider-health package entry point and changes user-visible provider
health behavior without updating a README or documentation file. Consumers therefore lack
documentation for the new API and connection-versus-authorization semantics.
Code

packages/providers-meta/package.json[9]

+    "./provider-health": "./src/provider-health.ts",
Relevance

⭐⭐⭐ High

Public package export and user-visible semantics directly trigger the active documentation
requirement.

PR-#1359

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 773522 requires documentation for significant behavior changes and newly exported
public entry points. The package manifest now exposes ./provider-health, but the PR diff contains
no README or docs/ update.

Rule 773522: Update README and docs with significant code changes in the same PR
packages/providers-meta/package.json[6-13]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new `./provider-health` export and provider health behavior are not documented in this PR.

## Issue Context
Document the exported health model, its connection and authorization semantics, and intended web/mobile usage in the providers package README or appropriate provider documentation.

## Fix Focus Areas
- packages/providers-meta/package.json[6-13]
- packages/providers-meta/README.md[1-1]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Provider screen exceeds line limit ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
The additions leave packages/mobile/app/providers/[id].tsx at 1,220 lines, exceeding the
1,000-line maximum for TypeScript files. The provider health display should be extracted rather than
further expanding this multi-responsibility screen.
Code

packages/mobile/app/providers/[id].tsx[R1184-1185]

+  statusColumn: { gap: 4, marginTop: 6 },
+  statusLabel: { color: colors.textTertiary, fontSize: 12 },
Relevance

⭐⭐⭐ High

Explicit 1,000-line compliance rule makes extraction likely despite prior resistance to broader
refactors.

PR-#1679

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 773521 prohibits changed TypeScript files from exceeding 1,000 physical lines. The
PR adds more styles at lines 1184-1194, while the resulting file continues through line 1220.

Rule 773521: Enforce a 1000-line maximum per TypeScript file
packages/mobile/app/providers/[id].tsx[1184-1194]
packages/mobile/app/providers/[id].tsx[1220-1220]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`packages/mobile/app/providers/[id].tsx` exceeds the 1,000-line limit after this PR's additions.

## Issue Context
The new connection and authorization health presentation can be extracted into a focused component, reducing the provider screen's size and responsibilities without changing behavior.

## Fix Focus Areas
- packages/mobile/app/providers/[id].tsx[1-1220]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (1)
5. Reconnect error remains invisible ✓ Resolved 🐞 Bug ≡ Correctness
Description
When a token-auth provider requiring reconnect lacks tokenAuth metadata, the new handler stores an
actionable error in syncMessage, but that message renders only inside the section gated by
provider.authorized === true. In the supported disconnected-expired state, clicking the promoted
Reconnect button therefore appears to do nothing.
Code

packages/web/src/pages/ProviderDetailPage.tsx[R268-269]

+        setSyncStatus("error");
+        setSyncMessage(error.message);
Relevance

⭐⭐⭐ High

Exact precedent requires missing token metadata errors to be user-visible and telemetry-backed.

PR-#2045

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The reconnect button is available whenever health requires reconnect, independent of authorization,
but the only syncMessage rendering is inside the authorized-only sync-controls section. Repository
tests establish that providers can have credentials removed while retaining needsReauth=true.

packages/web/src/pages/ProviderDetailPage.tsx[432-440]
packages/web/src/pages/ProviderDetailPage.tsx[485-603]
packages/server/src/routers/sync.test.ts[521-558]
PR-#2045

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The missing-token-metadata reconnect branch records an error in `syncMessage`, but disconnected providers cannot see the authorized-only section where that state is rendered. Render reconnect errors beside the promoted reconnect control or in another section visible regardless of authorization.

## Issue Context
`authorized: false` with `needsReauth: true` is a supported state after expired credentials are removed. Add a provider-detail regression test combining that state with absent token metadata and verify the error becomes visible after clicking Reconnect.

## Fix Focus Areas
- packages/web/src/pages/ProviderDetailPage.tsx[247-284]
- packages/web/src/pages/ProviderDetailPage.tsx[432-440]
- packages/web/src/pages/ProviderDetailPage.tsx[485-603]
- packages/web/src/pages/ProviderDetailPage.test.tsx[550-575]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment thread packages/mobile/app/providers/[id].tsx
Comment thread packages/providers-meta/package.json
Comment thread packages/web/src/pages/ProviderDetailPage.tsx Outdated
Comment thread packages/providers-meta/src/processing-status.ts Outdated
Comment thread packages/web/src/pages/ProviderDetailPage.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

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

Inline comments:
In `@packages/mobile/app/providers/`[id].tsx:
- Around line 903-907: Update the provider health and reconnect button
visibility logic in the provider screen to use the `requiresReconnect` value
returned by `providerHealth`, rather than deriving the decision from
`provider?.needsReauth`. Replace the duplicate check in the button visibility
path around the existing health calculation, preserving the current behavior for
other health conditions.

In `@packages/web/src/components/ProcessingStatusWidget.tsx`:
- Around line 112-126: Update the dataset error derivation and rendering in
ProcessingStatusWidget so historical failures are resolved and displayed only
when the current dataset status is failed or blocked. Apply the same status
guard to the mobile rendering path, preserving equivalent web and mobile
behavior, and ensure a failed-then-ready timeline shows the ready state without
the obsolete error.

In `@packages/web/src/pages/ProviderDetailPage.tsx`:
- Around line 605-634: Split ProviderDetailPage by extracting the SyncHistory UI
and records browser into focused modules with direct imports, keeping their
existing behavior and interfaces unchanged. Update ProviderDetailPage to use
those extracted components and ensure no TypeScript file exceeds 1,000 lines; do
not introduce a barrel file.
- Around line 261-269: Update the reconnect handling in ProviderDetailPage,
including the unavailable-token branch that calls captureException and
setSyncMessage, to store a reconnect-specific error state and render it beside
the Reconnect action outside the provider authorized-controls gate. Ensure the
state is cleared on a successful reconnect or new attempt as appropriate, and
add coverage verifying disconnected token providers see the error.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9ca83d9d-18cd-4583-8954-ee2b6c317757

📥 Commits

Reviewing files that changed from the base of the PR and between eff34bb and 27262dc.

📒 Files selected for processing (17)
  • packages/mobile/app/providers/[id].test.tsx
  • packages/mobile/app/providers/[id].tsx
  • packages/mobile/components/ProcessingStatusWidget.stories.tsx
  • packages/mobile/components/ProcessingStatusWidget.test.tsx
  • packages/mobile/components/ProcessingStatusWidget.tsx
  • packages/mobile/components/SourceProcessingStatusCard.tsx
  • packages/providers-meta/package.json
  • packages/providers-meta/src/processing-status.test.ts
  • packages/providers-meta/src/processing-status.ts
  • packages/providers-meta/src/provider-health.test.ts
  • packages/providers-meta/src/provider-health.ts
  • packages/web/src/components/ProcessingStatusWidget.stories.tsx
  • packages/web/src/components/ProcessingStatusWidget.test.tsx
  • packages/web/src/components/ProcessingStatusWidget.tsx
  • packages/web/src/components/SourceProcessingStatusCard.tsx
  • packages/web/src/pages/ProviderDetailPage.test.tsx
  • packages/web/src/pages/ProviderDetailPage.tsx

Comment thread packages/mobile/app/providers/[id].tsx
Comment thread packages/web/src/components/ProcessingStatusWidget.tsx
Comment thread packages/web/src/pages/ProviderDetailPage.tsx Outdated
Comment thread packages/web/src/pages/ProviderDetailPage.tsx
@codereviewbot-ai

codereviewbot-ai Bot commented Jul 29, 2026

Copy link
Copy Markdown

LGTM! The changes cleanly introduce providerHealth to separate connection and authorization states, extract dataset status helpers and errors, refactor web and mobile processing widgets with equivalent logic, and split large page modules to stay within line limits. Unit tests and stories cover all scenarios.


🤖 Reviewed by codereviewbot.ai - Catch bugs before your team does.

@Asherlc
Asherlc merged commit a56f653 into main Jul 29, 2026
107 checks passed
@Asherlc
Asherlc deleted the Asherlc/issue-2071-provider-health branch July 29, 2026 04:26
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.

[P0-13] Provider Connected status masks failed or stale datasets

2 participants