Add global recent-deployments feed for the projects dashboard

The RECENT DEPLOYMENTS section queried the builds table, so
image-sourced services — which deploy without building — never
appeared and the dashboard reported "no deployments yet" while
containers were running.

- GET /api/v1/deployments lists latest deployments across the
  caller's services, joined with service + project names, ordered
  newest-first with a bounded limit
- ProjectsPage consumes it via listRecentDeployments; the DEPLOYS
  stat card now counts real deployments
- is_admin is now projected in register/upsert user responses, and
  the Better Auth mirror grants admin to the first mirrored account
  (previously only the legacy register path did)

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomas DvorakandDevin committed 2026-09-21 21:07:01 +02:00
1 parent b7e2e93261
commit 3bf44dbcd5
8 files changed
+258 -21

No files matched your search

+31
View File
@@ -1146,6 +1146,37 @@ export async function listDeployments(serviceId: string): Promise<DeploymentEnti
return normalizeDeploymentArray(payload.deployments);
}
export type RecentDeploymentEntity = {
id: string;
serviceId: string;
serviceName: string;
projectName: string;
status: string;
imageName?: string;
startedAt?: string;
completedAt?: string;
createdAt?: string;
};
export async function listRecentDeployments(limit = 10): Promise<RecentDeploymentEntity[]> {
const payload = await requestJson<{ deployments?: Array<Record<string, unknown>> }>(
`/deployments?limit=${limit}`,
);
return (payload.deployments ?? [])
.map((d) => ({
id: String(d.id ?? ''),
serviceId: String(d.service_id ?? ''),
serviceName: String(d.service_name ?? ''),
projectName: String(d.project_name ?? ''),
status: String(d.status ?? ''),
imageName: d.image_name ? String(d.image_name) : undefined,
startedAt: d.started_at ? String(d.started_at) : undefined,
completedAt: d.completed_at ? String(d.completed_at) : undefined,
createdAt: d.created_at ? String(d.created_at) : undefined,
}))
.filter((d) => d.id !== '');
}
export async function createDeployment(
serviceId: string,
input: CreateDeploymentInput = {},