feat(search): add personal integration inventory and connection cards - #7711
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
|
@cubic-dev-ai review this PR |
@TheodoreSpeaks I have started the AI code review. It will take a few minutes to complete. |
|
| if (attempt.connectionIntent && attempt.completionId && attempt.organizationId) { | ||
| await recordSearchConnectionCompletion({ | ||
| organizationId: attempt.organizationId, | ||
| userId: attempt.userId, | ||
| completionId: attempt.completionId, | ||
| credentialId: completion.credentialId, | ||
| }) |
There was a problem hiding this comment.
Receipt Failure Misreports Success
The credential grant is committed before this completion receipt is written. If Redis is unavailable or rejects the write, the error reaches the OAuth callback, which shows a failure even though the account was successfully connected. This can prompt the user to retry an authorization that already completed. Make the receipt write non-fatal after the commit, or otherwise prevent receipt failures from reporting the committed grant as failed.
| export function readSearchConnectionAttempt(key: string): SearchConnectionAttempt | null { | ||
| if (typeof window === 'undefined') return null | ||
| const value = window.localStorage.getItem(key) | ||
| if (!value) return null | ||
| return attemptSchema.parse(JSON.parse(value)) | ||
| } |
There was a problem hiding this comment.
This persistent browser state is parsed without handling malformed or schema-incompatible values. Because the connection hook calls this function while rendering, a corrupt value—or an older value after a future schema change—can replace the entire organization chat or integrations page with its error state until storage is cleared. Treat invalid state as absent and clear it, as the existing OAuth-attempt reader does.
| export function readSearchConnectionAttempt(key: string): SearchConnectionAttempt | null { | |
| if (typeof window === 'undefined') return null | |
| const value = window.localStorage.getItem(key) | |
| if (!value) return null | |
| return attemptSchema.parse(JSON.parse(value)) | |
| } | |
| export function readSearchConnectionAttempt(key: string): SearchConnectionAttempt | null { | |
| if (typeof window === 'undefined') return null | |
| try { | |
| const value = window.localStorage.getItem(key) | |
| if (!value) return null | |
| const parsed = attemptSchema.safeParse(JSON.parse(value)) | |
| if (parsed.success) return parsed.data | |
| window.localStorage.removeItem(key) | |
| return null | |
| } catch { | |
| return null | |
| } | |
| } |
|
@cubic-dev-ai review this PR |
@TheodoreSpeaks I have started the AI code review. It will take a few minutes to complete. |
Summary
Type of Change
Testing
Focused integration and Slack tests, app/auth typechecks, Biome, generated catalog checks, and all 46 repository audits. The latest Slack regression run passed 260 tests across 25 suites. Live browser verification covered authenticated inventory, agent tool execution, and connection-card rendering. Live provider consent and Submit verification remain pending. Live Slack delivery is blocked by an inactive test installation.
Rollout
Deploy these handlers and renderers before enabling the tool and prompt in Mothership #491.
Checklist