Skip to content

refactor(wizard): split integration health validators into grouped modules#958

Merged
muddlebee merged 2 commits intoTracer-Cloud:mainfrom
7vignesh:issue/873-split-integration-health-validators
Apr 29, 2026
Merged

refactor(wizard): split integration health validators into grouped modules#958
muddlebee merged 2 commits intoTracer-Cloud:mainfrom
7vignesh:issue/873-split-integration-health-validators

Conversation

@7vignesh
Copy link
Copy Markdown
Contributor

Fixes #873

Describe the changes you have made in this PR -

This PR refactors app/cli/wizard/integration_health.py into smaller, grouped validator modules while preserving the stable public import surface.

What changed:

  1. Split validators into focused modules under app/cli/wizard/integration_validators/:

    • client_validators.py — 11 validators backed by service clients (Grafana, Datadog, Honeycomb, Coralogix, AWS, Sentry, GitLab, Vercel, Alertmanager, OpsGenie, BetterStack)
    • http_probe_validators.py — 5 HTTP-based validators (Slack webhook, Notion, Jira, Google Docs, Discord)
    • mcp_validators.py — 2 MCP validators (GitHub MCP, OpenClaw)
    • shared.pyIntegrationHealthResult dataclass
    • __init__.py — Module marker
  2. Kept app/cli/wizard/integration_health.py as the stable public API by re-exporting all validators and the result type, so external imports remain unchanged.

  3. Updated test monkeypatch targets to point at new implementation modules while maintaining backward-compatible public function imports in tests.

  4. Added compatibility test that verifies validators are still accessible through the legacy public module path.

Test updates:

  • Updated 31 existing tests to patch implementation symbols in new modules
  • All tests still import public functions from app.cli.wizard.integration_health
  • Added explicit compatibility check for legacy public import surface

No validator behavior changed; this is a pure refactoring for maintainability.

Demo/Screenshot for feature changes and bug fixes -

Validation run for this change:

  • python -m pytest tests/cli/wizard/test_integration_health.py — 31 passed
  • python -m ruff check app/cli/wizard/integration_health.py app/cli/wizard/integration_validators tests/cli/wizard/test_integration_health.py
  • python -m ruff format --check app/cli/wizard/integration_health.py app/cli/wizard/integration_validators tests/cli/wizard/test_integration_health.py
  • python -m mypy app/cli/wizard/integration_health.py app/cli/wizard/integration_validators (no issues)

Code Understanding and AI Usage

Did you use AI assistance (ChatGPT, Claude, Copilot, etc.) to write any part of this code?

Yes, I used AI assistance (GitHub Copilot)

If you used AI assistance:

  • I have reviewed every single line of the AI-generated code
  • I can explain the purpose and logic of each function/component I added
  • I have tested edge cases and understand how the code handles them
  • I have modified the AI output to follow this project's coding standards and conventions

Explain your implementation approach:

The refactoring grouped validators by their implementation style (client-backed, HTTP-probe, MCP) for clarity and separation of concerns, while maintaining a stable re-export surface so that all external callers and test imports remain unaffected. The monkeypatch paths were updated to target the actual implementation modules rather than the re-export surface, ensuring test isolation and precise mocking.

Checklist before requesting a review

  • I have added proper PR title and linked to the issue
  • I have performed a self-review of my code
  • I can explain the purpose of every function, class, and logic block I added
  • I understand why my changes work and have tested them thoroughly
  • I have considered potential edge cases and how my code handles them
  • If it is a core feature, I have added thorough tests
  • My code follows the project's style guidelines and conventions

Copilot AI review requested due to automatic review settings April 25, 2026 21:26
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 25, 2026

Greptile Summary

This PR splits the monolithic integration_health.py (632 lines) into four focused sub-modules under app/cli/wizard/integration_validators/, while keeping the original file as a stable re-export facade with a full __all__. All 31 existing tests pass after updating monkeypatch targets to the new implementation paths.

One point worth noting: validate_slack_webhook was quietly switched from requests to httpx (exception type changed from requests.RequestException to httpx.RequestError), which contradicts the PR's claim of a pure refactoring. The added compatibility test also only verifies one of the 18 public symbols.

Confidence Score: 5/5

Safe to merge; all findings are P2 style/documentation concerns with no runtime impact.

The refactoring is structurally sound — the public API surface is fully preserved, all tests pass, and the module split follows clear grouping logic. The two findings (undocumented library swap in validate_slack_webhook and weak compatibility test) are P2 quality suggestions that do not affect correctness or production behavior.

app/cli/wizard/integration_validators/http_probe_validators.py (undisclosed requests→httpx swap) and tests/cli/wizard/test_integration_health.py (compatibility test coverage).

Important Files Changed

Filename Overview
app/cli/wizard/integration_health.py Reduced to a thin re-export facade; all 18 public symbols preserved in all, backward compatibility maintained.
app/cli/wizard/integration_validators/client_validators.py 11 client-backed validators extracted verbatim from the original module; logic is unchanged.
app/cli/wizard/integration_validators/http_probe_validators.py 5 HTTP validators extracted; validate_slack_webhook silently switched from requests to httpx, contradicting the "pure refactoring" claim in the PR description.
app/cli/wizard/integration_validators/mcp_validators.py 2 MCP validators extracted unchanged; logic is identical to the original.
app/cli/wizard/integration_validators/shared.py IntegrationHealthResult dataclass extracted to shared.py; clean separation with a necessary dependency on GitHubMCPValidationResult.
tests/cli/wizard/test_integration_health.py 31 monkeypatch targets correctly updated to new implementation modules; compatibility test added but only covers 1 of 18 public exports.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["app.cli.wizard.integration_health\n(stable public facade / __all__)"]

    A --> B["integration_validators/\nclient_validators.py\n(Grafana, Datadog, Honeycomb,\nCoralogix, AWS, Sentry,\nGitLab, Vercel, Alertmanager,\nOpsGenie, BetterStack)"]

    A --> C["integration_validators/\nhttp_probe_validators.py\n(Slack, Notion, Jira,\nGoogle Docs, Discord)"]

    A --> D["integration_validators/\nmcp_validators.py\n(GitHub MCP, OpenClaw)"]

    B & C & D --> E["integration_validators/\nshared.py\nIntegrationHealthResult"]

    E --> F["app.integrations.github_mcp\nGitHubMCPValidationResult"]
Loading

Comments Outside Diff (2)

  1. app/cli/wizard/integration_validators/http_probe_validators.py, line 1092-1106 (link)

    P2 Undisclosed HTTP client swap in validate_slack_webhook

    The PR description states "No validator behavior changed; this is a pure refactoring," but validate_slack_webhook was silently switched from requests to httpx. The caught exception type changed from requests.RequestException to httpx.RequestError, which has a different exception hierarchy. While the common-case behavior is equivalent, any caller relying on the original requests.RequestException semantics (e.g., downstream error handling or logging that inspects the exception type) would see a different type. The commit message and description should acknowledge this behavioral delta.

  2. tests/cli/wizard/test_integration_health.py, line 1380-1384 (link)

    P2 Compatibility test checks only one of 18 public symbols

    The new compatibility test verifies that validate_slack_webhook is accessible via the legacy module path, but __all__ in integration_health.py lists 18 symbols. If any of the other 17 re-exports were accidentally dropped or misnamed, this test would pass silently. Consider asserting against the full __all__ list:

    def test_legacy_integration_health_import_surface_still_exports_validators() -> None:
        import app.cli.wizard.integration_health as mod
    
        for name in mod.__all__:
            assert hasattr(mod, name), f"Missing from legacy surface: {name}"

Reviews (1): Last reviewed commit: "refactor(wizard): split integration heal..." | Re-trigger Greptile

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@7vignesh 7vignesh force-pushed the issue/873-split-integration-health-validators branch from c91d6df to 9277017 Compare April 26, 2026 08:45
@7vignesh
Copy link
Copy Markdown
Contributor Author

@VaibhavUpreti
Resolved the merge conflicts in app/cli/wizard/integration_health.py and tests/cli/wizard/test_integration_health.py by rebasing onto the latest main. Force-pushed the updated branch — no conflicts remaining. Please review when you get a chance!

class IntegrationHealthResult:
"""Result of validating an optional integration."""

ok: bool
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

shared.py imports GitHubMCPValidationResult from a concrete integration module, which means every consumer of IntegrationHealthResult silently pulls in the GitHub MCP import chain. The field is only meaningful for one validator. Consider using object | None (or a Protocol) here and letting mcp_validators.py own the typed field, or move GitHubMCPValidationResult into shared.py to keep the dependency explicit in the right layer.

ok=False, detail="Jira credentials invalid. Check email and API token."
)
if resp.status_code == 404:
return IntegrationHealthResult(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

validate_google_docs_integration belongs in client_validators.py. It uses GoogleDocsClient (a service client), not a raw HTTP probe — the only reason it's here is that the original file had it adjacent to Notion/Jira. The module docstring says 'HTTP-probe validators'; this function violates that contract and will confuse the next person deciding where to put a new validator.

def test_legacy_integration_health_import_surface_still_exports_validators() -> None:
module = import_module("app.cli.wizard.integration_health")

assert hasattr(module, "validate_slack_webhook")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Spot-checking one symbol out of 18 exported gives false confidence. Assert against the full all list so a future refactor can't silently drop exports: assert set(module.all) == {all 18 names}.

@7vignesh
Copy link
Copy Markdown
Contributor Author

Hi @muddlebee, addressed all 3 points in the latest push:

  • IntegrationHealthResult now uses a type-only reference to GitHubMCPValidationResult in shared.py — no more runtime import chain for every consumer.
  • validate_google_docs_integration moved to client_validators.py where it belongs.
  • Compatibility test now checks the full all surface instead of a single symbol.

All tests + lint/type checks pass.

Copy link
Copy Markdown
Collaborator

@muddlebee muddlebee left a comment

Choose a reason for hiding this comment

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

Looks good.

@muddlebee
Copy link
Copy Markdown
Collaborator

thank you looks good. I will wait additional reviews, @VaibhavUpreti @hamzzaaamalik @yashksaini-coder

@hamzzaaamalik
Copy link
Copy Markdown
Collaborator

Looked at this locally and ran the tests. It's a clean refactor integration_health.py becomes a re-export façade, validators move into 3 grouped modules, tests pass.

Spot-checked every validator body against the old file: 13 are byte-identical, the other 5 only have cosmetic tweaks (hoisting import httpx to the top of the file, renaming e to err for consistency, an em-dash → -- in one comment). No behaviour change.

Other things I checked:

Every place in the codebase that imports from integration_health still works — all 19 symbols are re-exported and the new compat test guards that.
IntegrationHealthResult no longer pulls in github_mcp at runtime (verified — fresh import doesn't load that module).
validate_google_docs_integration is in client_validators.py like @muddlebee asked.
31/31 tests pass, 203/203 in the broader tests/cli/ sweep.
Tiny nit: PR description says "5 HTTP validators" but it's actually 4 (Google Docs got moved). Cosmetic only.

LGTM, approve and merge.

@muddlebee muddlebee merged commit 17c5bbd into Tracer-Cloud:main Apr 29, 2026
7 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

🎯 Bullseye. @7vignesh opened a PR, kept the vibes clean, and got it merged. Absolute cinema. 🎬


👋 Join us on Discord - OpenSRE : hang out, contribute, or hunt for features and issues. Everyone's welcome.

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.

Split app/cli/wizard/integration_health.py into smaller validator modules

4 participants