Repository navigation
fix: repair s3 backup connection test, file listing and failure logs - #6
Merged
Merged
Conversation
5 tasks done
Что: - destination.testConnection принимает необязательный destinationId. Если форма прислала заглушку __DOKPLOY_REDACTED_SECRET__, роутер берёт сохранённый секрет этого destination после той же проверки organizationId, что в one и update. В облаке доступ к серверу проверяется до загрузки секрета. - Заглушка без destinationId отклоняется ошибкой BAD_REQUEST с понятным текстом до запуска rclone. - Форма редактирования destination передаёт destinationId при нажатии Test. Зачем: - API отдаёт форме секрет в виде заглушки, форма отправляла её обратно, и rclone подписывал запрос заглушкой. Поэтому Test для сохранённого S3 destination всегда падал с 403 SignatureDoesNotMatch. Риски: - Секрет, введённый в форме заново, используется как раньше; сохранённый подставляется только вместо заглушки. Значимых рисков не выявлено. Проверки: - Команды и результаты: CI=true bunx vitest run --config __test__/vitest.config.ts __test__/destination __test__/backup __test__/backups __test__/security - 22 файла, 182 теста прошли; 4 из 6 новых тестов падают на старом роутере. bun run typecheck - 4 из 4 workspace без ошибок. bun run format-and-lint - exit 0, только прежние предупреждения в чужих файлах. CI=true bun run test - 2064 прошли, 8 упали только в *.real.test.ts (нет локального Docker daemon, таймауты реальной сборки). - Ограничения: проверки запускались на дереве со всеми исправлениями этой серии; кнопка Test не нажималась в браузере против реального S3; ничего не выкатывалось. What: - destination.testConnection accepts an optional destinationId. When the form sends the __DOKPLOY_REDACTED_SECRET__ placeholder, the router uses the stored secret of that destination after the same organizationId check as one and update. In cloud mode server access is checked before the secret is loaded. - The placeholder without destinationId is rejected with a clear BAD_REQUEST before rclone runs. - The destination edit form sends destinationId when Test is pressed. Why: - The API returns the secret to the form as a placeholder, the form sent it back, and rclone signed the request with the placeholder. Test on a saved S3 destination therefore always failed with 403 SignatureDoesNotMatch. Risks: - A secret typed again in the form is used as before; the stored one only replaces the placeholder. No significant risks identified. Checks: - Commands and results: CI=true bunx vitest run --config __test__/vitest.config.ts __test__/destination __test__/backup __test__/backups __test__/security - 22 files, 182 tests passed; 4 of the 6 new tests fail on the old router. bun run typecheck - 4 of 4 workspaces clean. bun run format-and-lint - exit 0, only existing warnings in unrelated files. CI=true bun run test - 2064 passed, 8 failed only in *.real.test.ts (no local Docker daemon, real build timeouts). - Limitations: checks ran on the tree with every fix of this series; the Test button was not pressed in a browser against a real S3 endpoint; nothing was deployed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Что: - getAccessibleBackupListingPrefixes загружает из связей application и compose запроса volumeBackups только appName. - Тест собирает настоящий SQL обоих запросов listBackupFiles через drizzle.mock с реальной схемой и проверяет, что ни один json_build_array не получает больше 100 аргументов. Зачем: - В таблице application 101 колонка. Drizzle упаковывает все колонки вложенной связи в один json_build_array, и Postgres отклонял запрос с 54023 "cannot pass more than 100 arguments to a function". Из-за этого backup.listBackupFiles всегда отвечал 400 и восстановление из бэкапа нельзя было начать. Риски: - Запрос backups (связи compose, postgres и другие) не менялся: сейчас максимум 49 аргументов, и тест упадёт, если он перейдёт порог. Тот же класс ошибки остаётся в других запросах с application: true (findDeploymentById, проверка восстановления volume backup) - они вне этой правки. Проверки: - Команды и результаты: CI=true bunx vitest run --config __test__/vitest.config.ts __test__/backup/restore-security.test.ts - 40 тестов прошли; на старом роутере новый тест падает с "expected 101 to be less than or equal to 100". Общие прогоны те же, что в предыдущем коммите серии: 182 теста в затронутых областях прошли, bun run typecheck 4/4 без ошибок, bun run format-and-lint exit 0. - Ограничения: проверки запускались на дереве со всеми исправлениями этой серии; запрос не выполнялся против живой базы; ничего не выкатывалось. What: - getAccessibleBackupListingPrefixes loads only appName from the application and compose relations of the volumeBackups query. - A test compiles the real SQL of both listBackupFiles queries with drizzle.mock and the real schema and checks that no json_build_array call gets more than 100 arguments. Why: - The application table has 101 columns. Drizzle packs every column of a nested relation into one json_build_array call, and Postgres rejected the query with 54023 "cannot pass more than 100 arguments to a function". backup.listBackupFiles therefore always answered 400 and a restore could not be started. Risks: - The backups query (compose, postgres and other relations) is unchanged: it peaks at 49 arguments now, and the test fails if it crosses the limit. The same error class remains in other application: true queries (findDeploymentById, the volume backup restore check), which are outside this fix. Checks: - Commands and results: CI=true bunx vitest run --config __test__/vitest.config.ts __test__/backup/restore-security.test.ts - 40 tests passed; on the old router the new test fails with "expected 101 to be less than or equal to 100". Shared runs are the same as in the previous commit of the series: 182 tests passed in the touched areas, bun run typecheck 4/4 clean, bun run format-and-lint exit 0. - Limitations: checks ran on the tree with every fix of this series; the query was not run against a live database; nothing was deployed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Что: - Скрипт getBackupCommand делает дамп и выгрузку один раз: удалён второй блок "Starting upload to S3...", который заново запускал дамп и rclone rcat. - При ошибке скрипт пишет в лог "Backup failed", удаляет недокачанный файл через уже передаваемый rcloneDeleteCommand (как в upstream) и печатает UPLOAD_OUTPUT в stderr, а не в лог. - Новый runBackupCommand в backups/utils запускает скрипт локально или на удалённом сервере, при ошибке пропускает stderr через redactSensitiveText и дописывает его в logPath деплоя (локально через appendFile, удалённо через printf с экранированием). Шесть раннеров (postgres, mysql, mariadb, mongo, libsql, compose) вызывают его вместо своей копии if/else. Зачем: - Причина ошибки pg_dump или rclone сохранялась в UPLOAD_OUTPUT и терялась: в логе бэкапа было только "Check server logs for details", в логах сервера деталей тоже не было. Дамп и выгрузка шли дважды, удваивая нагрузку и время. Повторный блок и потеря очистки появились при слиянии upstream f633d4b. Риски: - Удалённый лог дописывается вторым SSH-вызовом; если он не удался, ошибка пишется в лог сервера, а исходная ошибка бэкапа пробрасывается без изменений. Маскировка покрывает только шаблоны redactSensitiveText. Проверки: - Команды и результаты: CI=true bunx vitest run --config __test__/vitest.config.ts __test__/backup/backup-failure-output.test.ts __test__/backup/rclone-command-boundary.test.ts - все прошли. Новый тест запускает настоящий скрипт в bash с поддельными docker и rclone; на старом utils.ts он показывает второй docker exec и rclone rcat и отсутствие deletefile. Общие прогоны серии: 182 теста в затронутых областях прошли, bun run typecheck 4/4 без ошибок, bun run format-and-lint exit 0. - Ограничения: проверки запускались на дереве со всеми исправлениями этой серии; настоящий бэкап в S3 не запускался; ничего не выкатывалось. What: - The getBackupCommand script dumps and uploads once: the second "Starting upload to S3..." block that re-ran the dump and rclone rcat is removed. - On failure the script logs "Backup failed", removes the partial upload with the already passed rcloneDeleteCommand (as upstream does) and prints UPLOAD_OUTPUT to stderr instead of the log. - A new runBackupCommand in backups/utils runs the script locally or on a remote server and, on failure, passes stderr through redactSensitiveText and appends it to the deployment logPath (appendFile locally, quoted printf remotely). The six runners (postgres, mysql, mariadb, mongo, libsql, compose) call it instead of their own if/else copy. Why: - The pg_dump or rclone failure reason was captured in UPLOAD_OUTPUT and lost: the backup log only said "Check server logs for details", and the server logs had no details either. The dump and upload ran twice, doubling load and time. The duplicate block and the lost cleanup came from merging upstream f633d4b. Risks: - The remote log is appended with a second SSH call; if it fails, the error goes to the server log and the original backup error is rethrown unchanged. Masking covers only the redactSensitiveText patterns. Checks: - Commands and results: CI=true bunx vitest run --config __test__/vitest.config.ts __test__/backup/backup-failure-output.test.ts __test__/backup/rclone-command-boundary.test.ts - all passed. The new test runs the real script in bash with fake docker and rclone; against the old utils.ts it shows a second docker exec and rclone rcat and no deletefile. Shared runs of the series: 182 tests passed in the touched areas, bun run typecheck 4/4 clean, bun run format-and-lint exit 0. - Limitations: checks ran on the tree with every fix of this series; no real backup to S3 was run; nothing was deployed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Что: - redactSensitiveText больше не маскирует слово после флагов вида --no-password: правило для флагов CLI пропускает флаги --no-*, а правило PASSWORD не срабатывает на no-password. - Тест проверяет, что имя БД после --no-password остаётся видимым, а --password, --db-password=, -password, PASSWORD '...' и IDENTIFIED BY '...' по-прежнему маскируются. Зачем: - В логе команды бэкапа postgres имя базы после --no-password заменялось на заглушку, хотя это не секрет: флаг булев и значения не принимает. Риски: - Правка общей функции маскировки. Исключение узкое: только флаги, начинающиеся с no-, которые по соглашению не принимают значений. Прочие правила не менялись. Проверки: - Команды и результаты: CI=true bunx vitest run --config __test__/vitest.config.ts __test__/security/secret-redaction.test.ts - 14 тестов прошли; на старом redaction.ts новый тест падает. Общие прогоны серии: 182 теста в затронутых областях прошли, bun run typecheck 4/4 без ошибок, bun run format-and-lint exit 0, CI=true bun run test - 2064 прошли, 8 упали только в *.real.test.ts (нет локального Docker daemon, таймауты реальной сборки). - Ограничения: проверки запускались на дереве со всеми исправлениями этой серии; ничего не выкатывалось. What: - redactSensitiveText no longer masks the word after flags such as --no-password: the CLI flag rule skips --no-* flags, and the PASSWORD rule does not match no-password. - A test checks that the database name after --no-password stays visible while --password, --db-password=, -password, PASSWORD '...' and IDENTIFIED BY '...' are still masked. Why: - The postgres backup command log replaced the database name after --no-password with the placeholder, although it is not a secret: the flag is boolean and takes no value. Risks: - This changes the shared masking function. The exception is narrow: only flags starting with no-, which by convention take no value. Other rules are unchanged. Checks: - Commands and results: CI=true bunx vitest run --config __test__/vitest.config.ts __test__/security/secret-redaction.test.ts - 14 tests passed; the new test fails on the old redaction.ts. Shared runs of the series: 182 tests passed in the touched areas, bun run typecheck 4/4 clean, bun run format-and-lint exit 0, CI=true bun run test - 2064 passed, 8 failed only in *.real.test.ts (no local Docker daemon, real build timeouts). - Limitations: checks ran on the tree with every fix of this series; nothing was deployed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
agentHits
force-pushed
the
fix/s3-backups
branch
from
October 6, 2026 17:55
6b90c3b to
89adf5b
Compare
agentHits
added a commit
that referenced
this pull request
Oct 6, 2026
Что: - findDeploymentById берёт из трёх вложенных связей application (у самого деплоя, у schedule и у volumeBackup) только serverId: другие поля этих связей вызывающий код не читает. - Проверка восстановления volume backup (assertVolumeRestoreObjectBound) берёт из связей application и compose только appName. - Поиск preview-деплоя в monitoring-access берёт из связи application только applicationId и serverId. - Новый тестовый хелпер __test__/helpers/postgres-function-args.ts собирает настоящий SQL через drizzle.mock с реальной схемой и считает аргументы json_build_array. Для каждого из трёх запросов добавлен тест, который проверяет, что аргументов не больше 100. Зачем: - В таблице application 101 колонка. Drizzle кладёт все выбранные колонки вложенной связи в один вызов json_build_array, а Postgres принимает не больше 100 аргументов и отвечает ошибкой 54023 "cannot pass more than 100 arguments to a function". - Из-за findDeploymentById не работали WebSocket логов деплоя (закрывался молча), deployment.readLogs, killProcess и removeDeployment, откат через rollback и создание rollback при деплое с rollback registry. Удаление старых rollback молча пропускалось. - Из-за проверки восстановления не запускалось восстановление volume backup. - Поиск preview-деплоя выполняется для каждого имени, которое не нашлось среди application. Поэтому мониторинг compose, баз данных и preview-деплоев (WebSocket docker stats, user.getContainerMetrics) отвечал ошибкой. - Upstream уже сужал связи в findDeploymentById (97885ee), но при слиянии upstream 430c888 конфликт разрешился в пользу application: true. Риски: - Если код начнёт читать из этих связей другие поля, их там не будет. Typecheck это ловит: при выборе appName вместо serverId tsc падает в listen-deployment.ts. - backup.listBackupFiles в AgentHits-Dev падает с той же ошибкой. Его чинит открытый PR #6 (2802c33), здесь он не менялся. В тесте PR #6 своя копия подсчёта аргументов, после слияния её можно заменить общим хелпером. Проверки: - Команды и результаты: CI=true bunx vitest run --config __test__/vitest.config.ts __test__/deployment/find-deployment-by-id.test.ts __test__/volume-backups/restore-security.test.ts __test__/server/container-resource-stats-access.test.ts - 28 тестов прошли; на старом коде три новых теста падают с "expected 101 to be less than or equal to 100" (для monitoring - 102). Полный прогон CI=true bunx vitest run --config __test__/vitest.config.ts: 2055 тестов прошли, 1 пропущен, 8 упали только в __test__/deploy/application.real.test.ts и __test__/setup/monitoring-setup.real.test.ts из-за отсутствия сокета Docker Desktop (connect ECONNREFUSED /Users/agent/.docker/run/docker.sock). bun run typecheck - 4/4 пакета без ошибок. bun run format-and-lint - 0 ошибок (33 предупреждения в других файлах, в изменённых файлах их нет). Временный vitest-аудит через toSQL (удалён перед коммитом) проверил остальные вложенные связи с application из grep: у них не больше 50 аргументов. - Ограничения: запросы не выполнялись против живой базы; *.real.test.ts без локального Docker не проверены; ничего не пушилось и не выкатывалось. What: - findDeploymentById loads only serverId from its three nested application relations (on the deployment itself, on schedule and on volumeBackup); callers read no other field from them. - The volume backup restore check (assertVolumeRestoreObjectBound) loads only appName from the application and compose relations. - The preview deployment lookup in monitoring-access loads only applicationId and serverId from the application relation. - A new test helper, __test__/helpers/postgres-function-args.ts, compiles the real SQL with drizzle.mock and the real schema and counts json_build_array arguments. Each of the three queries gets a test that checks there are no more than 100. Why: - The application table has 101 columns. Drizzle puts every selected column of a nested relation into one json_build_array call, and Postgres accepts at most 100 arguments and fails with 54023 "cannot pass more than 100 arguments to a function". - Because of findDeploymentById, the deployment log WebSocket (closed silently), deployment.readLogs, killProcess and removeDeployment, rolling back, and rollback creation during deploys with a rollback registry all failed. Removing old rollbacks was silently skipped. - Because of the restore check, a volume backup restore could not start. - The preview deployment lookup runs for every name that is not found among applications. Monitoring for compose services, databases and preview deployments (the docker stats WebSocket, user.getContainerMetrics) therefore failed. - Upstream had already narrowed the relations in findDeploymentById (97885ee), but the upstream merge 430c888 resolved the conflict in favour of application: true. Risks: - Code that starts reading other fields from these relations will not find them there. Typecheck catches this: selecting appName instead of serverId makes tsc fail in listen-deployment.ts. - backup.listBackupFiles fails with the same error in AgentHits-Dev. Open PR #6 (2802c33) fixes it, so it is unchanged here. The PR #6 test has its own copy of the argument counter, which can switch to the shared helper after both are merged. Checks: - Commands and results: CI=true bunx vitest run --config __test__/vitest.config.ts __test__/deployment/find-deployment-by-id.test.ts __test__/volume-backups/restore-security.test.ts __test__/server/container-resource-stats-access.test.ts - 28 tests passed; on the old code the three new tests fail with "expected 101 to be less than or equal to 100" (102 for monitoring). Full run CI=true bunx vitest run --config __test__/vitest.config.ts: 2055 passed, 1 skipped, 8 failed, all in __test__/deploy/application.real.test.ts and __test__/setup/monitoring-setup.real.test.ts because the Docker Desktop socket is missing (connect ECONNREFUSED /Users/agent/.docker/run/docker.sock). bun run typecheck - 4/4 packages clean. bun run format-and-lint - 0 errors (33 warnings in other files, none in the changed files). A temporary vitest audit with toSQL (removed before the commit) checked the other nested application relations found by grep: they peak at 50 arguments. - Limitations: the queries were not run against a live database; the *.real.test.ts tests were not verified without a local Docker; nothing was pushed or deployed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
agentHits
force-pushed
the
fix/s3-backups
branch
from
October 6, 2026 18:12
89adf5b to
e602d86
Compare
agentHits
force-pushed
the
AgentHits-Dev
branch
from
October 6, 2026 18:12
befcbd7 to
58219e3
Compare
agentHits
added a commit
that referenced
this pull request
Oct 6, 2026
Что: - findDeploymentById берёт из трёх вложенных связей application (у самого деплоя, у schedule и у volumeBackup) только serverId: другие поля этих связей вызывающий код не читает. - Проверка восстановления volume backup (assertVolumeRestoreObjectBound) берёт из связей application и compose только appName. - Поиск preview-деплоя в monitoring-access берёт из связи application только applicationId и serverId. - Новый тестовый хелпер __test__/helpers/postgres-function-args.ts собирает настоящий SQL через drizzle.mock с реальной схемой и считает аргументы json_build_array. Для каждого из трёх запросов добавлен тест, который проверяет, что аргументов не больше 100. Зачем: - В таблице application 101 колонка. Drizzle кладёт все выбранные колонки вложенной связи в один вызов json_build_array, а Postgres принимает не больше 100 аргументов и отвечает ошибкой 54023 "cannot pass more than 100 arguments to a function". - Из-за findDeploymentById не работали WebSocket логов деплоя (закрывался молча), deployment.readLogs, killProcess и removeDeployment, откат через rollback и создание rollback при деплое с rollback registry. Удаление старых rollback молча пропускалось. - Из-за проверки восстановления не запускалось восстановление volume backup. - Поиск preview-деплоя выполняется для каждого имени, которое не нашлось среди application. Поэтому мониторинг compose, баз данных и preview-деплоев (WebSocket docker stats, user.getContainerMetrics) отвечал ошибкой. - Upstream уже сужал связи в findDeploymentById (97885ee), но при слиянии upstream 5a1d8ea (2026-10-01) конфликт разрешился в пользу application: true. Риски: - Если код начнёт читать из этих связей другие поля, их там не будет. Typecheck это ловит: при выборе appName вместо serverId tsc падает в listen-deployment.ts. - backup.listBackupFiles в AgentHits-Dev падает с той же ошибкой. Его чинит открытый PR #6, здесь он не менялся. В тесте PR #6 своя копия подсчёта аргументов, после слияния её можно заменить общим хелпером. Проверки: - Команды и результаты: CI=true bunx vitest run --config __test__/vitest.config.ts __test__/deployment/find-deployment-by-id.test.ts __test__/volume-backups/restore-security.test.ts __test__/server/container-resource-stats-access.test.ts - 28 тестов прошли; на старом коде три новых теста падают с "expected 101 to be less than or equal to 100" (для monitoring - 102). Полный прогон CI=true bunx vitest run --config __test__/vitest.config.ts: 2055 тестов прошли, 1 пропущен, 8 упали только в __test__/deploy/application.real.test.ts и __test__/setup/monitoring-setup.real.test.ts из-за отсутствия сокета Docker Desktop (connect ECONNREFUSED /Users/agent/.docker/run/docker.sock). bun run typecheck - 4/4 пакета без ошибок. bun run format-and-lint - 0 ошибок (33 предупреждения в других файлах, в изменённых файлах их нет). Временный vitest-аудит через toSQL (удалён перед коммитом) проверил остальные вложенные связи с application из grep: у них не больше 50 аргументов. - Ограничения: запросы не выполнялись против живой базы; *.real.test.ts без локального Docker не проверены; ничего не пушилось и не выкатывалось. What: - findDeploymentById loads only serverId from its three nested application relations (on the deployment itself, on schedule and on volumeBackup); callers read no other field from them. - The volume backup restore check (assertVolumeRestoreObjectBound) loads only appName from the application and compose relations. - The preview deployment lookup in monitoring-access loads only applicationId and serverId from the application relation. - A new test helper, __test__/helpers/postgres-function-args.ts, compiles the real SQL with drizzle.mock and the real schema and counts json_build_array arguments. Each of the three queries gets a test that checks there are no more than 100. Why: - The application table has 101 columns. Drizzle puts every selected column of a nested relation into one json_build_array call, and Postgres accepts at most 100 arguments and fails with 54023 "cannot pass more than 100 arguments to a function". - Because of findDeploymentById, the deployment log WebSocket (closed silently), deployment.readLogs, killProcess and removeDeployment, rolling back, and rollback creation during deploys with a rollback registry all failed. Removing old rollbacks was silently skipped. - Because of the restore check, a volume backup restore could not start. - The preview deployment lookup runs for every name that is not found among applications. Monitoring for compose services, databases and preview deployments (the docker stats WebSocket, user.getContainerMetrics) therefore failed. - Upstream had already narrowed the relations in findDeploymentById (97885ee), but the upstream merge 5a1d8ea (2026-10-01) resolved the conflict in favour of application: true. Risks: - Code that starts reading other fields from these relations will not find them there. Typecheck catches this: selecting appName instead of serverId makes tsc fail in listen-deployment.ts. - backup.listBackupFiles fails with the same error in AgentHits-Dev. Open PR #6 fixes it, so it is unchanged here. The PR #6 test has its own copy of the argument counter, which can switch to the shared helper after both are merged. Checks: - Commands and results: CI=true bunx vitest run --config __test__/vitest.config.ts __test__/deployment/find-deployment-by-id.test.ts __test__/volume-backups/restore-security.test.ts __test__/server/container-resource-stats-access.test.ts - 28 tests passed; on the old code the three new tests fail with "expected 101 to be less than or equal to 100" (102 for monitoring). Full run CI=true bunx vitest run --config __test__/vitest.config.ts: 2055 passed, 1 skipped, 8 failed, all in __test__/deploy/application.real.test.ts and __test__/setup/monitoring-setup.real.test.ts because the Docker Desktop socket is missing (connect ECONNREFUSED /Users/agent/.docker/run/docker.sock). bun run typecheck - 4/4 packages clean. bun run format-and-lint - 0 errors (33 warnings in other files, none in the changed files). A temporary vitest audit with toSQL (removed before the commit) checked the other nested application relations found by grep: they peak at 50 arguments. - Limitations: the queries were not run against a live database; the *.real.test.ts tests were not verified without a local Docker; nothing was pushed or deployed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What is this PR about?
Fixes three S3 backup problems found while setting up an S3 backup destination on dev, one commit each, plus a small log fix:
secretAccessKeyto the edit form as the__DOKPLOY_REDACTED_SECRET__placeholder, the form sent it back, and rclone signed the request with the placeholder.destination.testConnectionnow accepts an optionaldestinationId. When the placeholder arrives, it uses that destination's stored secret after the same organization check asoneandupdate; cloud server access is still checked first. The placeholder withoutdestinationIdis rejected with a clearBAD_REQUESTbefore rclone runs. The edit form sendsdestinationId.backup.listBackupFilesalways answered 400 (2802c33). Theapplicationtable has 101 columns. ThevolumeBackupslisting query loadedapplication: true, and Drizzle packed every column into onejson_build_array(...), above the Postgres limit of 100 arguments (54023 cannot pass more than 100 arguments to a function). The nestedapplicationandcomposerelations now select onlyappName.getBackupCommandand dropped the partial-upload cleanup. The script now dumps once. On failure it deletes the partial object (as upstream does) and printsUPLOAD_OUTPUTto stderr instead of the log. The newrunBackupCommandpasses that output throughredactSensitiveTextand appends it to the deployment log, locally or over SSH. All six database runners use it.redactSensitiveTextno longer masks the database name afterpg_dump --no-password. Real password arguments stay masked.No database migrations and no new environment variables; only the
dokployservice image changes.Checks
drizzle.mockand the real schema (old code: 101 arguments), the backup script run in bash with fakedockerandrclone(old code: dump and upload twice, no cleanup),runBackupCommandlog appends, redaction.__test__/destination,__test__/backup,__test__/backupsand__test__/security: 22 files, 182 tests pass.bun run typecheck: 4/4 packages pass.bun run format-and-lint: no errors.bun run test: 2064 pass; the 8 failures are only in*.real.test.ts(no local Docker daemon, real build timeouts).Rollout notes
dokployimage and take a database backup.Not in this PR
findDeploymentByIdand the volume-backup restore check still loadapplication: trueand hit the same 54023 error (deployment log viewer,readLogs, kill and remove deployment, rollbacks, volume restore). They are being fixed in a separate branch.🤖 Generated with Claude Code