feat(backups): archive download endpoint + GitHub App install surfacing

- GET /databases/:id/backups/:bid/download streams the archive out of the
  containr-db-backups volume via a stopped utility container and
  CopyFromContainer; daemon logs sanitize non-UTF-8 so binary through
  container logs was not viable. Verified e2e: byte-identical payload,
  404 missing/cross-user, 401 unauthenticated.
- Settings Git Providers gains an Install GitHub App action that opens the
  install_url and completes the installation_id return via connect endpoint.
- ROADMAP: mark both items done with verification evidence.

Authored By: TDvorak <[email protected]>
This commit is contained in:
Tomas Dvorak committed 2026-09-17 17:30:30 +02:00
1 parent 18fe56f948
commit bcd3a83aa4
8 files changed
+304 -24

No files matched your search

+19
View File
@@ -1326,6 +1326,25 @@ export type ConnectGitRepositoryInput = components['schemas']['ConnectGitRepoReq
export type CreateGitWebhookInput = components['schemas']['CreateWebhookRequest'];
export type GitWebhookEntity = components['schemas']['GitWebhook'];
export async function getGitHubAppInstallUrl(): Promise<string> {
const payload = await requestJson<{ install_url?: string }>('/git/github-app/install-url');
if (!payload.install_url) {
throw new ApiError('GitHub App install URL unavailable', 500);
}
return payload.install_url;
}
export async function connectGitHubApp(installationId: number, displayName?: string): Promise<GitProviderEntity> {
const payload = await requestJson<{ provider?: GitProviderEntity }>('/git/github-app/connect', {
method: 'POST',
body: JSON.stringify({ installation_id: installationId, display_name: displayName }),
});
if (!payload.provider?.id) {
throw new ApiError('GitHub App connect response is invalid', 500);
}
return payload.provider;
}
export async function connectGitRepository(
input: ConnectGitRepositoryInput,
): Promise<GitRepositoryEntity> {