Skip to content

feat(convex): add Convex plugin with Management API operations - #569

Open
Mayank-saraswal wants to merge 9 commits into
corsairdev:mainfrom
Mayank-saraswal:feat/convex-plugin
Open

feat(convex): add Convex plugin with Management API operations#569
Mayank-saraswal wants to merge 9 commits into
corsairdev:mainfrom
Mayank-saraswal:feat/convex-plugin

Conversation

@Mayank-saraswal

@Mayank-saraswal Mayank-saraswal commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the Convex plugin to Corsair, implementing all 19 operations claimed on the OSS dashboard:

Convex Management API (Bearer token, https://api.convex.dev/v1):

  • Projects — list, get by ID, get by team/slug, create (optionally provisioning a deployment), delete
  • Deployments — list, get, create (dev/prod/preview/custom), update, delete
  • Deploy keys — create (returns the one-time secret; only non-secret metadata is cached), list
  • Custom domains — delete
  • Platform — token details, deployment classes, deployment regions

Convex deployment-scoped REST API (https://<deployment>.convex.cloud/api, Authorization: Convex <deploy-key>):

  • Execute a query batch, get the current query timestamp, list log streams

Auth is configurable per plugin: api_key (deploy key) or oauth_2 (access token), with a subdomain account field used to resolve the deployment URL for deployment-scoped operations. Schema entities (projects, deployments, deployKeys) are cached on successful reads/writes, and destructive endpoints remove cached entities.

Fixes #568

Checklist

  • I have run pnpm lint and all checks pass
  • I have run pnpm typecheck and there are no TypeScript errors
  • I have run pnpm build and all packages build successfully
  • I have run pnpm test and all tests pass
  • I have added or updated tests where applicable (21 tests: shape, client auth, endpoint routing for all 19 ops, error handlers)
  • I have added or updated necessary documentation (plugin-docs.yaml)

Screenshots / Demos (if applicable)

🎥 Demo video: Loom recording — running the full Convex plugin test suite (21/21 tests passing) and exercising the endpoints against a live Convex deployment.

Additional Notes

  • Generated with pnpm generate:plugin, footprint matches R1 (plugin package + packages/corsair/core/constants.ts registration + lockfile).
  • No webhooks — the claimed integration has 0 triggers.
  • Deploy key secrets are never persisted; only non-secret metadata is stored in the schema entity.
  • pnpm run validate:plugins fails only on pre-existing epicgames/kaggle packages (missing package.json), unrelated to this PR; Convex passes validation.

Summary by CodeRabbit

  • New Features

    • Added Convex integration for projects, deployments, deploy keys, custom domains, queries, logs, tokens, and platform metadata.
    • Added configurable authentication, API requests, and validation for inputs and responses.
    • Added Convex to the supported provider list.
  • Reliability

    • Added categorized error handling with retry support for rate limits and server errors.
    • Improved resilience when caching operational data.
  • Tests

    • Added comprehensive endpoint, schema, caching, routing, and error-handling coverage.
  • Documentation

    • Added Convex plugin metadata and overview documentation.

@vercel

vercel Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

@Mayank-saraswal is attempting to deploy a commit to the corsair Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds the @corsair-dev/convex plugin with typed Convex API endpoints, authentication, deployment resolution, database synchronization, error handling, schemas, tests, package configuration, and provider registration.

Changes

Convex integration

Layer / File(s) Summary
Package, schema, and provider setup
packages/convex/package.json, packages/convex/schema/*, packages/convex/*config*, packages/convex/plugin-docs.yaml, packages/corsair/core/constants.ts
Adds the Convex package, database schemas, package configuration, documentation, test setup, and provider registration.
Contracts, client, and plugin wiring
packages/convex/endpoints/types.ts, packages/convex/client.ts, packages/convex/index.ts, packages/convex/error-handlers.ts
Adds typed endpoint schemas, request construction, error normalization, authentication, credential resolution, plugin types, and retry handlers.
Management API endpoint handlers
packages/convex/endpoints/projects.ts, packages/convex/endpoints/deployments.ts, packages/convex/endpoints/deploy-keys.ts, packages/convex/endpoints/custom-domains.ts, packages/convex/endpoints/platform.ts
Adds management API handlers with logging and database synchronization.
Deployment-scoped API flow
packages/convex/endpoints/deployment-scoped.ts
Adds deployment validation and authenticated query, timestamp, and log-stream operations.
Endpoint registry and validation coverage
packages/convex/endpoints/index.ts, packages/convex/api.test.ts
Registers 19 endpoints with metadata and schemas. Tests routing, authentication, request construction, deployment resolution, persistence, deletion, cache behavior, and error handling.

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

Sequence Diagram(s)

sequenceDiagram
  participant Corsair
  participant ConvexPlugin
  participant EndpointHandler
  participant ConvexRequestClient
  participant ConvexAPI
  participant Database
  Corsair->>ConvexPlugin: invoke Convex endpoint
  ConvexPlugin->>EndpointHandler: bind credentials and context
  EndpointHandler->>ConvexRequestClient: construct typed API request
  ConvexRequestClient->>ConvexAPI: send authenticated request
  ConvexAPI-->>EndpointHandler: return Convex response
  EndpointHandler->>Database: upsert or delete cached resource
  EndpointHandler-->>Corsair: return endpoint result
Loading

Possibly related PRs

  • corsairdev/corsair#473 — Adds a provider plugin and registers its provider identifier and display name.
  • corsairdev/corsair#482 — Adds a first-class provider plugin with provider registration.
  • corsairdev/corsair#552 — Adds an integration with analogous clients, endpoint registries, schemas, authentication, error handlers, and tests.

Suggested labels: docs, plugin

Suggested reviewers: devjain32

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR adds Convex integration features, but it does not show the requested team, environment-variable, or member operations from issue #568. Implement the missing team, environment-variable, and member operations, or update issue #568 to define the revised API scope.
Out of Scope Changes check ⚠️ Warning Custom-domain, platform, query, timestamp, and log-stream endpoints are not among the coding objectives listed in issue #568. Remove these unrelated endpoints or split them into a separate PR unless issue #568 is updated to include their scope.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 clearly identifies the Convex plugin and its Management API operations.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the core Changes in packages/corsair label Aug 2, 2026
@Mayank-saraswal
Mayank-saraswal marked this pull request as ready for review August 2, 2026 20:23
@greptile-apps

greptile-apps Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The follow-up changes complete the Convex plugin’s credential separation, authenticated-host validation, secret-safe event logging, and best-effort cache handling.

  • Separates Management API bearer credentials from deployment-scoped deploy keys.
  • Validates every deployment subdomain source before constructing an authenticated Convex URL.
  • Excludes plaintext deploy keys from persisted completion-event payloads.
  • Prevents cache and cache-refresh failures from masking successful provider operations.
  • Adds cache cleanup for deployments and deploy keys removed through parent-resource deletion.
  • Expands tests around authentication, routing, cache failures, cleanup, and secret handling.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
packages/convex/index.ts Configures separate account fields and resolves Management credentials without reusing deployment keys as bearer tokens.
packages/convex/endpoints/deployment-scoped.ts Validates deployment host labels, resolves deployment keys independently, and records redacted completion events.
packages/convex/client.ts Implements Management and deployment-scoped request authentication plus isolated best-effort cache writes.
packages/convex/endpoints/projects.ts Implements project operations with non-fatal cache updates and cascading cached-deployment cleanup.
packages/convex/endpoints/deployments.ts Implements deployment operations while isolating cache refresh failures and cleaning related cached deploy keys.
packages/convex/endpoints/deploy-keys.ts Avoids persisting one-time deploy-key secrets and caches only metadata returned by list operations.
packages/convex/api.test.ts Covers endpoint routing, credential separation, host validation, cache resilience, cleanup, and secret-safe behavior.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  C[Convex connection] --> K{Operation family}
  K -->|Management API| M[Resolve API key or OAuth access token]
  M --> B[Authorization: Bearer token]
  B --> API[api.convex.dev/v1]
  K -->|Deployment scoped| D[Resolve per-call or stored deploy key]
  D --> S[Validate deployment DNS label]
  S --> H[Authorization: Convex deploy key]
  H --> CLOUD[deployment.convex.cloud/api]
Loading

Reviews (6): Last reviewed commit: "fix(convex): support deploy-key-only con..." | Re-trigger Greptile

Comment thread packages/convex/endpoints/deployment-scoped.ts
Comment thread packages/convex/index.ts
Comment thread packages/convex/endpoints/projects.ts
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown

Plugin PR scorecard — packages/convex

Check Status Notes
R1 — Scope: plugin files only
R2 — Tests with assertions
R3 — Description complete
R3 — Linked issue / claim
R4 — Demo video / recording

Rules: PLUGIN_PR_RULES.md · re-runs on every push

@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown

Hey @Mayank-saraswal, thanks for the contribution! 🏴‍☠️ Before a maintainer reviews, please fix the items below — the review re-runs automatically on your next push.

Must fix

  • P1 packages/convex/endpoints/deployment-scoped.ts:18Authenticated URL permits host escape
    When a caller supplies a subdomain containing an authority-terminating slash, such as attacker.example:443/, the interpolated URL targets that host while retaining Authorization: Convex <deploy-key>, disclosing the deployment credential. Restrict this value to a single valid Convex DNS label before constructing the URL.

How this was verified: The nonempty-string input flows directly into the base URL, and the shared request client sends the configured authorization header to that resolved URL.

  • P1 packages/convex/index.ts:160Credential families are conflated
    A connection selects one plugin-wide credential, but Management handlers always send it as a Bearer token while deployment-scoped handlers always send it with the Convex scheme. As a result, a default deploy-key connection cannot authenticate Management operations, and an OAuth connection cannot reliably satisfy operations requiring a deployment key, leaving part of the advertised endpoint surface unusable.

Rule Used: Verify the implementation matches the PR descripti... (source)

Knowledge Base Used: The provider-plugin package pattern

  • P1 packages/convex/endpoints/projects.ts:96Cache failures mask remote success
    When Convex successfully creates or deletes a resource but the subsequent local cache operation throws, the handler rejects and skips its completion event even though the remote mutation already occurred. This reports completed operations as failures, leaves deleted cache entries stale, and can prompt retries that create duplicates or encounter unexpected not-found responses; isolate cache failures from endpoint results across the project, deployment, and deploy-key handlers.

Knowledge Base Used: The provider-plugin package pattern

If anything remains after your next push, a bot commit will clean it up; a maintainer always does the final review and merge.

@github-actions github-actions Bot added the bot:round-1 Review bot posted consolidated findings label Aug 2, 2026

@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: 5

🧹 Nitpick comments (2)
packages/convex/endpoints/deployment-scoped.ts (1)

15-19: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use ConvexAPIError for consistency.

The missing-subdomain guard throws a plain Error (Lines 16-18), while every other failure path in this plugin surfaces a ConvexAPIError. Throwing ConvexAPIError here keeps error shape consistent for any downstream code that inspects error.name or error instanceof ConvexAPIError.

🤖 Prompt for 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.

In `@packages/convex/endpoints/deployment-scoped.ts` around lines 15 - 19, Update
the missing-subdomain guard in the deployment-scoped endpoint to throw
ConvexAPIError instead of a plain Error, preserving the existing message and
ensuring downstream error checks remain consistent with the other failure paths.
packages/convex/error-handlers.ts (1)

5-83: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Consider tightening the message-based fallback matching.

Each handler falls back to substring checks on error.message (for example Lines 12-17, 38-43, 64-65) when the error isn't ApiError/ConvexAPIError. A message that incidentally contains "404" or "403" for unrelated reasons would be misclassified into the wrong retry policy.

This only matters for errors that aren't already ApiError or ConvexAPIError, so the risk is bounded. If broader coverage is intentional (e.g., wrapped errors from other library layers), consider narrowing the substring checks or documenting why message-based matching is necessary here.

🤖 Prompt for 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.

In `@packages/convex/error-handlers.ts` around lines 5 - 83, Tighten the
message-based fallback checks in the match functions for RATE_LIMIT_ERROR,
AUTH_ERROR, PERMISSION_ERROR, and NOT_FOUND_ERROR so incidental status-code text
cannot classify unrelated errors; use more specific, intentional patterns while
preserving matching for wrapped errors if required.
🤖 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/convex/endpoints/deploy-keys.ts`:
- Around line 23-36: Update the create flow around the deployKeys upsert to
avoid using input.deployment_name as the entity ID, since list uses each deploy
key’s durable deployKey.id and multiple keys can share a deployment. Prefer
skipping this pre-list cache write and relying on list to populate records; if
caching is required, use a deployment-scoped composite ID that cannot collide
with other keys and guard the write against retries consistently with
projects.ts and deployments.ts.

In `@packages/convex/endpoints/deployments.ts`:
- Around line 88-113: After the successful PATCH in update, fetch the refreshed
deployment record with GET using input.deployment_name and ctx.key, then pass
that record to ctx.db.deployments.upsertByEntityId before logging completion and
returning. Preserve the existing update request and response behavior.

In `@packages/convex/endpoints/projects.ts`:
- Around line 118-120: Update the project deletion handler around
ctx.db.projects.deleteByEntityId to also remove or invalidate all cached
deployments belonging to input.project_id; update the deployment deletion
handler around ctx.db.deployments.deleteByEntityId to also remove or invalidate
cached deploy keys belonging to input.deployment_name. Apply the corresponding
cleanup in packages/convex/endpoints/projects.ts lines 118-120 and
packages/convex/endpoints/deployments.ts lines 125-127.
- Around line 90-99: Isolate post-create cache failures so successful
non-idempotent API calls are not reported as failed. In
packages/convex/endpoints/projects.ts lines 90-99, wrap the projects upsert in
try/catch; apply the same change to deployments.upsertByEntityId in
packages/convex/endpoints/deployments.ts lines 68-77 and
deployKeys.upsertByEntityId in packages/convex/endpoints/deploy-keys.ts lines
23-36, preserving the successful create response even when caching fails.

In `@packages/convex/plugin-docs.yaml`:
- Around line 8-10: Update the authentication documentation in the plugin
configuration around the existing Bearer-token and deployment-key text to
include the supported oauth_2 token flow. Document OAuth bearer authentication
for the Management API and explicitly state the authorization scheme used for
each API scope, while preserving the existing personal/team token and deploy-key
guidance.

---

Nitpick comments:
In `@packages/convex/endpoints/deployment-scoped.ts`:
- Around line 15-19: Update the missing-subdomain guard in the deployment-scoped
endpoint to throw ConvexAPIError instead of a plain Error, preserving the
existing message and ensuring downstream error checks remain consistent with the
other failure paths.

In `@packages/convex/error-handlers.ts`:
- Around line 5-83: Tighten the message-based fallback checks in the match
functions for RATE_LIMIT_ERROR, AUTH_ERROR, PERMISSION_ERROR, and
NOT_FOUND_ERROR so incidental status-code text cannot classify unrelated errors;
use more specific, intentional patterns while preserving matching for wrapped
errors if required.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ca7276bf-322a-4e34-ac0c-59c549d5247d

📥 Commits

Reviewing files that changed from the base of the PR and between 709940c and 83e4332.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (21)
  • packages/convex/api.test.ts
  • packages/convex/client.ts
  • packages/convex/endpoints/custom-domains.ts
  • packages/convex/endpoints/deploy-keys.ts
  • packages/convex/endpoints/deployment-scoped.ts
  • packages/convex/endpoints/deployments.ts
  • packages/convex/endpoints/index.ts
  • packages/convex/endpoints/platform.ts
  • packages/convex/endpoints/projects.ts
  • packages/convex/endpoints/types.ts
  • packages/convex/error-handlers.ts
  • packages/convex/index.ts
  • packages/convex/jest.config.cjs
  • packages/convex/package.json
  • packages/convex/plugin-docs.yaml
  • packages/convex/schema.test.ts
  • packages/convex/schema/database.ts
  • packages/convex/schema/index.ts
  • packages/convex/tsconfig.json
  • packages/convex/tsup.config.ts
  • packages/corsair/core/constants.ts

Comment thread packages/convex/endpoints/deploy-keys.ts Outdated
Comment thread packages/convex/endpoints/deployments.ts
Comment thread packages/convex/endpoints/projects.ts
Comment thread packages/convex/endpoints/projects.ts Outdated
Comment thread packages/convex/plugin-docs.yaml Outdated
@Mayank-saraswal

Copy link
Copy Markdown
Contributor Author

@greptileai

@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: 1

🧹 Nitpick comments (1)
packages/convex/client.ts (1)

38-56: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Keep tryCacheWrite callbacks limited to cache operations.

tryCacheWrite catches every error from its callback. In packages/convex/endpoints/deployments.ts, the deployment update callback also calls makeConvexRequest to refresh the cache at Lines 99-143. A rate-limit or network error from that provider request is discarded as a cache-write failure. The endpoint can leave the deployment cache stale without diagnostics.

Keep only deployments.upsertByEntityId inside this helper. Catch refresh failures separately and record a structured diagnostic without changing the successful PATCH result.

🤖 Prompt for 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.

In `@packages/convex/client.ts` around lines 38 - 56, Restrict the callback passed
to tryCacheWrite in the deployment update flow to only
deployments.upsertByEntityId. Move the makeConvexRequest refresh out of that
swallowed-error callback, catch its failures separately, and record a structured
diagnostic while preserving the successful PATCH result.
🤖 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/convex/index.ts`:
- Around line 30-38: Update resolveDeployKey to remove the ctx.key fallback and
require an explicit deployment deployKey for both api_key and oauth_2
connections, or use a distinct deploy-key credential when available. Preserve
the existing deployment authorization behavior and update affected tests to
verify missing deployKey is rejected.

---

Nitpick comments:
In `@packages/convex/client.ts`:
- Around line 38-56: Restrict the callback passed to tryCacheWrite in the
deployment update flow to only deployments.upsertByEntityId. Move the
makeConvexRequest refresh out of that swallowed-error callback, catch its
failures separately, and record a structured diagnostic while preserving the
successful PATCH result.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a4586e61-d597-467a-be54-f220bd46ff4d

📥 Commits

Reviewing files that changed from the base of the PR and between 83e4332 and faf87a2.

📒 Files selected for processing (10)
  • packages/convex/api.test.ts
  • packages/convex/client.ts
  • packages/convex/endpoints/deploy-keys.ts
  • packages/convex/endpoints/deployment-scoped.ts
  • packages/convex/endpoints/deployments.ts
  • packages/convex/endpoints/projects.ts
  • packages/convex/endpoints/types.ts
  • packages/convex/error-handlers.ts
  • packages/convex/index.ts
  • packages/convex/plugin-docs.yaml
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/convex/plugin-docs.yaml
  • packages/convex/error-handlers.ts
  • packages/convex/endpoints/types.ts

Comment thread packages/convex/index.ts Outdated
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

Remaining findings are being fixed by a bot commit — it will be re-reviewed automatically.

@github-actions github-actions Bot added the bot:round-2 Review bot pushed an automated fix label Aug 3, 2026
@Mayank-saraswal

Copy link
Copy Markdown
Contributor Author

@greptileai

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

Maintainer review needed

Automated rounds are exhausted. Remaining findings:

  • P1 packages/convex/endpoints/deployment-scoped.ts:115Completion events persist deploy keys
    When getQueryTimestamp or listLogStreams receives the required per-call deployKey, spreading the complete input into logEventFromContext stores the plaintext deployment admin key in corsair_events, exposing it to event readers and database backups.

How this was verified: Both handlers pass the secret-bearing input to the shared event logger, which inserts the payload into corsair_events.

@github-actions github-actions Bot added the needs-maintainer Automated rounds exhausted - human review needed label Aug 3, 2026
@Mayank-saraswal

Copy link
Copy Markdown
Contributor Author

@greptileai

Comment thread packages/convex/endpoints/deployment-scoped.ts
@Mayank-saraswal

Copy link
Copy Markdown
Contributor Author

@greptileai

@Mayank-saraswal

Copy link
Copy Markdown
Contributor Author

@greptileai

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:round-1 Review bot posted consolidated findings bot:round-2 Review bot pushed an automated fix core Changes in packages/corsair needs-maintainer Automated rounds exhausted - human review needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Integration request]: Convex

1 participant