Repository navigation
feat(convex): add Convex plugin with Management API operations - #569
Conversation
|
@Mayank-saraswal is attempting to deploy a commit to the corsair Team on Vercel. A member of the Team first needs to authorize it. |
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 Walkthrough
Pre-merge checks ·
|
|
Plugin PR scorecard —
|
| 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
|
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
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.
Rule Used: Verify the implementation matches the PR descripti... (source) Knowledge Base Used: The provider-plugin package pattern
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. |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (2)
packages/convex/endpoints/deployment-scoped.ts (1)
15-19: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUse
ConvexAPIErrorfor consistency.The missing-subdomain guard throws a plain
Error(Lines 16-18), while every other failure path in this plugin surfaces aConvexAPIError. ThrowingConvexAPIErrorhere keeps error shape consistent for any downstream code that inspectserror.nameorerror 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 valueConsider 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'tApiError/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
ApiErrororConvexAPIError, 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
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (21)
packages/convex/api.test.tspackages/convex/client.tspackages/convex/endpoints/custom-domains.tspackages/convex/endpoints/deploy-keys.tspackages/convex/endpoints/deployment-scoped.tspackages/convex/endpoints/deployments.tspackages/convex/endpoints/index.tspackages/convex/endpoints/platform.tspackages/convex/endpoints/projects.tspackages/convex/endpoints/types.tspackages/convex/error-handlers.tspackages/convex/index.tspackages/convex/jest.config.cjspackages/convex/package.jsonpackages/convex/plugin-docs.yamlpackages/convex/schema.test.tspackages/convex/schema/database.tspackages/convex/schema/index.tspackages/convex/tsconfig.jsonpackages/convex/tsup.config.tspackages/corsair/core/constants.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/convex/client.ts (1)
38-56: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winKeep
tryCacheWritecallbacks limited to cache operations.
tryCacheWritecatches every error from its callback. Inpackages/convex/endpoints/deployments.ts, the deployment update callback also callsmakeConvexRequestto 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.upsertByEntityIdinside this helper. Catch refresh failures separately and record a structured diagnostic without changing the successfulPATCHresult.🤖 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
📒 Files selected for processing (10)
packages/convex/api.test.tspackages/convex/client.tspackages/convex/endpoints/deploy-keys.tspackages/convex/endpoints/deployment-scoped.tspackages/convex/endpoints/deployments.tspackages/convex/endpoints/projects.tspackages/convex/endpoints/types.tspackages/convex/error-handlers.tspackages/convex/index.tspackages/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
|
Remaining findings are being fixed by a bot commit — it will be re-reviewed automatically. |
Maintainer review neededAutomated rounds are exhausted. Remaining findings:
How this was verified: Both handlers pass the secret-bearing input to the shared event logger, which inserts the payload into |
326c300 to
b3bbe63
Compare
Use Record<string, never> for the empty webhook surface and document intentional unknown usages in request bodies, schemas, and tests.
Re-sync .github/workflows with upstream/main so the convex plugin PR stays within the allowed scope after the merge.
Revert accidental workflow deletions from the fork base so the PR diff stays within the plugin footprint, and document the ApiError.body narrowing.
Restore the missing ts-jest lockfile entry that broke frozen installs, and use only the narrowed error body for the code field.
Backfill repository, homepage, and author fields required by the plugin README/metadata CI check.
|
@greptileai review |
|
@greptileai review |

Description
Adds the Convex plugin to Corsair with all 19 operations listed on the OSS dashboard. Every path, method, request body and response shape is checked against Convex's published OpenAPI specs (
api.convex.dev/v1/openapi.json,public-deployment-openapi.json,deployment-openapi.json).Operations
projects.listGET /v1/teams/{team_id}/projectsprojects.getByIdGET /v1/projects/{project_id}projects.getBySlugGET /v1/teams/{team_id_or_slug}/projects/{project_slug}projects.createPOST /v1/teams/{team_id}/create_projectprojects.deletePOST /v1/projects/{project_id}/deletedeployments.listGET /v1/projects/{project_id}/list_deploymentsdeployments.getGET /v1/deployments/{deployment_name}deployments.createPOST /v1/projects/{project_id}/create_deploymentdeployments.updatePATCH /v1/deployments/{deployment_name}deployments.deletePOST /v1/deployments/{deployment_name}/deletedeployKeys.createPOST /v1/deployments/{deployment_name}/create_deploy_keydeployKeys.listGET /v1/deployments/{deployment_name}/list_deploy_keyscustomDomains.deletePOST /v1/deployments/{deployment_name}/delete_custom_domainplatform.getTokenDetailsGET /v1/token_detailsplatform.listDeploymentClassesGET /v1/teams/{team_id}/list_deployment_classesplatform.listDeploymentRegionsGET /v1/teams/{team_id}/list_deployment_regionsdeployment.executeQueryBatchPOST https://<deployment>.convex.cloud/api/query_batchdeployment.getQueryTimestampPOST https://<deployment>.convex.cloud/api/query_tsdeployment.listLogStreamsGET https://<deployment>.convex.cloud/api/v1/list_log_streamsManagement operations use
https://api.convex.dev. Deployment-scoped operations resolve the host from thesubdomaininput, the pluginsubdomainoption, the connection'ssubdomainfield, or an explicitdeploymentUrl(restricted tohttps://*.convex.cloud).Auth
api_key(default) oroauth_2. The credential is a Convex team/personal access token sent asAuthorization: Bearer <token>to the Management API.Authorization: Convex <deploy key>, taken from the per-calldeployKeyinput or the connection'sdeploy_keyfield. A connection that only stores a deploy key can still run deployment-scoped operations.Database entities
Modeled on the Management API response objects (OpenAPI, docs); identifiers are int64 as in the API.
projectsidProjectResponseprojects.list,getById,getBySlug,create(fetches the full record after creating)deploymentsnamePlatformDeploymentResponsedeployments.list,get,create,update(refetches after the PATCH)deployKeysidPlatformDeployKeyResponseplusdeploymentNamedeployKeys.list(the secret returned bycreateis never stored)Webhooks
None. corsair.dev lists no triggers for Convex, so the plugin defines no webhooks.
Live test
Run against the real Management API with a team access token (
Authorization: Bearer, read-only calls through the plugin handlers; no keys in the repo).platform.getTokenDetailsteamTokenpayload matches schemaplatform.listDeploymentRegionsplatform.listDeploymentClassesServiceAccountCannotManageTeamfor team tokens (documented behavior of the API)projects.listprojects.getById/getBySlug,deployments.list/get,deployKeys.list(unknown ids)ProjectNotFound/DeploymentNotFound, confirming path and authdeployment.getQueryTimestamp/executeQueryBatch/api/query_ts,/api/query_batch)deployment.listLogStreamsMalformedAccessTokenwith a bogus deploy key, confirming/api/v1/list_log_streamsis the admin routecreate/update/delete)Tests
packages/convex/api.test.tsstubsfetchwith realResponseobjects. Each of the 19 endpoints has a test that asserts the exact method, full URL with query string, auth header, JSON body, and the parsed result against literal values. Also covered: entity writes for projects, deployments and deploy keys, 401 mapping, 429 withRetry-Afterreaching the rate-limit handler, 403/404/5xx classification, deployment URL and subdomain validation, path-segment escaping, keyBuilder credential resolution, and cache writes and cleanup on create/delete. 50 tests pass.Fixes #568
Checklist
pnpm lintand all checks passpnpm typecheckand there are no TypeScript errorspnpm buildand all packages build successfullypnpm testand all tests passdocs/plugins/convex,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
packages/convex/**, the registration inpackages/corsair/core/constants.ts, thepackages/conveximporter inpnpm-lock.yaml,docs/plugins/convex/**, and the Convex nav entry indocs/docs.json.list_deploy_keysis stored.projects.delete,deployments.update,deployments.delete,customDomains.delete) return{ success: true }.