feat: add safe application env upsert#4581
Conversation
26abf3e to
9134c9d
Compare
|
Rebased on latest Checks run:
CI may remain in |
|
Update: screenshot attachment is no longer applicable after the latest routing-focused update. This PR is API/server-side only; the current PR body has been updated with the relevant route and verification details. |
|
@Siumauricio this PR is linked to the existing issue (#4525), was rebased on the latest |
|
Update (2026-07-06): I pushed the API routing alignment into this PR after the additional validation pass. Current confirmed shape:
Related MCP PR Dokploy/mcp#56 has also been updated to call Focused checks passed for the updated implementation: targeted env upsert Vitest, scoped Biome, Merge gate remains the same: the MCP PR should not merge until this core API lands or maintainers confirm the final API/OpenAPI contract. |
Что: - Добавил прямой Next API handler для safe application env upsert и slash/compatibility routes `/api/application/env/upsert` и `/api/application.env.upsert`. - Подключил exact-match обработку этих routes в OpenAPI catch-all и custom HTTP server, сохранив auth, permission checks, dry-run и redeploy gating. Зачем: - MCP и внешние клиенты должны вызывать безопасный partial env upsert без full environment replacement и без возврата raw secret values. Риски: - Route selection в custom server учитывает exact-match request path и `x-forwarded-uri` для self-hosted proxy setups; auth, permissions и schema validation остаются обязательными. Проверки: - Команды и результаты: `git diff --cached --check` прошел; `corepack pnpm --filter=dokploy exec vitest run --config __test__/vitest.config.ts __test__/env/upsert.test.ts __test__/env/application-env-upsert.test.ts` прошел, 2 файла и 7 тестов; `CI=true corepack pnpm exec biome check ...` прошел на 10 scoped files с существующими warnings/infos; `corepack pnpm --filter=dokploy run build-server` прошел; независимый Agent Flow QA вернул pass-with-risks без блокирующих findings. - Ограничения: full typecheck и generate:openapi в core не прошли из-за существующих unrelated project/dependency failures; live HTTP smoke через custom server не запускался. What: - Added a direct Next API handler for safe application env upsert and slash/compatibility routes `/api/application/env/upsert` and `/api/application.env.upsert`. - Wired exact-match handling for those routes through the OpenAPI catch-all and custom HTTP server while preserving auth, permission checks, dry-run, and redeploy gating. Why: - MCP and external clients need to call safe partial env upsert without full environment replacement and without returning raw secret values. Risks: - Custom-server route selection considers exact-match request path and `x-forwarded-uri` for self-hosted proxy setups; auth, permissions, and schema validation remain mandatory. Checks: - Commands and results: `git diff --cached --check` passed; `corepack pnpm --filter=dokploy exec vitest run --config __test__/vitest.config.ts __test__/env/upsert.test.ts __test__/env/application-env-upsert.test.ts` passed, 2 files and 7 tests; `CI=true corepack pnpm exec biome check ...` passed on 10 scoped files with existing warnings/infos; `corepack pnpm --filter=dokploy run build-server` passed; independent Agent Flow QA returned pass-with-risks with no blocking findings. - Limitations: full core typecheck and generate:openapi did not pass because of existing unrelated project/dependency failures; live HTTP smoke through the custom server was not run.
|
Code update pushed for the API routing part. What changed in this PR now:
MCP support in Dokploy/mcp#56 has also been updated to call the slash route Latest local checks passed: targeted Vitest env upsert tests, scoped Biome check, |
What is this PR about?
This PR adds a safe partial environment variable upsert API for applications. API and MCP clients can add or update selected application environment variables without reading or replacing the full env block, which avoids deleting existing secrets when the current env is redacted.
The new
application.env.upsertmutation reads the current env server-side, merges submitted variables by key, and returns metadata only. It supportsdryRun, optionalexpectedRevisionconflict protection, and optionalredeploywhen the caller also has deployment permission.This update also exposes direct API routing for the new contract:
POST /api/application/env/upsertfor the slash route used by MCP and OpenAPI clients.POST /api/application.env.upsertas a compatibility route for the dot-style operation name.POST /application/env/upsert.Checklist
Before submitting this PR, please make sure that:
canarybranch.Issues related (if applicable)
Closes #4525
Screenshots (if applicable)
N/A. This is an API/server-side change.
MCP support status
Dependent MCP support is already implemented in Dokploy/mcp#56.
That MCP PR is ready for review, but should remain blocked for merge until this core API lands or maintainers confirm the final API/OpenAPI shape. The intended MCP behavior is server-side partial env upsert only: no full env read, no client-side full env reconstruction, no fallback to
application.saveEnvironment, and no raw secret values returned to the client.I also verified the flow in a self-hosted Dokploy + MCP setup using
dryRun, so MCP can send only selected variables without reading or rewriting the full env block.Verification
Passed locally:
git diff --cached --checkcorepack pnpm --filter=dokploy exec vitest run --config __test__/vitest.config.ts __test__/env/upsert.test.ts __test__/env/application-env-upsert.test.tsCI=true corepack pnpm exec biome check 'apps/dokploy/pages/api/[...trpc].ts' apps/dokploy/pages/api/application.env.upsert.ts apps/dokploy/pages/api/application/env/upsert.ts apps/dokploy/server/api/routers/application.ts apps/dokploy/server/server.ts packages/server/src/db/schema/application.ts packages/server/src/services/application.ts packages/server/src/utils/env-upsert.ts apps/dokploy/__test__/env/upsert.test.ts apps/dokploy/__test__/env/application-env-upsert.test.tscorepack pnpm --filter=dokploy run build-serverNot completed locally because of existing unrelated baseline/dependency issues:
corepack pnpm --filter=dokploy run typecheckstops on the TypeScript 6baseUrldeprecation before project type checking.tsc --noEmit --ignoreDeprecations 6.0still reports existing unrelated project type errors.corepack pnpm --filter=dokploy run generate:openapicurrently stops on the existing@react-email/componentsrenderAsyncexport issue.Note: I did not commit
openapi.jsonbecause the repository has a post-mergeGenerate and Sync OpenAPIworkflow that regenerates and syncs the OpenAPI artifact to Dokploy, MCP, CLI, SDK, and docs repositories after changes land oncanary.