Files
Claude 218d5ef709 feat(connectors): HubSpot checks follow the design's rows, copy and states
HubSpot follows the design:
- Names and order: the 9 checks are the design's 9 rows ("Sign in to
  HubSpot", "Read tickets", "List linked records", "Read record
  viewers"...). Dependencies follow the design's run order. "List linked
  records" and "Sample notes" run after the sign-in, not after the read
  checks: an empty type would stop them, but they can sample a record of
  another type. They leave out a denied type, which its read check
  reports.
- Every failure gives a short line and a description. A denial names the
  private app scope that HubSpot needs. Passing checks give what they
  found ("Signed in to account {id}", "Found {n} tickets", "{n} users
  found"...).
- Checks that passed without testing anything now say so. An empty type
  is SKIPPED. No record of any selected type FAILS the first read check.
  No record in scope skips the samples. A record without notes, and no
  listed user, are INCOMPLETE.

Fixes from the design's review:
- A rate limit past the retries is RateLimitedValidationError, which
  stops the run.
- Sign-in reports a missing token, an unreachable HubSpot and a timeout.
  On a form run, an unreachable HubSpot or a timeout fails sign-in.
- HubSpotApiError is a SourceApiError with the request and HubSpot's
  error body, so Error Details show them. The gateway raises
  HubSpotConnectionError for a failed or timed-out connection.
- Permission sync validation accepts a portal with no records.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KFMazQbuG8ui3jxBxm47sC
2026-10-17 02:50:21 +00:00
..
…