feat: add infrastructure checks (DB exists, Spaces prefix) to customer overview
Some checks failed
Build & Release / build (push) Has been cancelled
Some checks failed
Build & Release / build (push) Has been cancelled
This commit is contained in:
@@ -624,7 +624,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
function renderDetail({ customer, status, sizeHistory }) {
|
||||
function renderDetail({ customer, status, infra, sizeHistory }) {
|
||||
// Header
|
||||
document.getElementById('detail-name').textContent = customer.name || customer.slug;
|
||||
document.getElementById('detail-slug').textContent = customer.slug;
|
||||
@@ -718,6 +718,30 @@
|
||||
${conditionsHtml}
|
||||
${podsHtml}
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="card-title">Infrastructure</div>
|
||||
<div class="stat-row">
|
||||
<span class="stat-label">Database</span>
|
||||
<span class="stat-value">${infra?.database?.exists
|
||||
? '<span class="badge badge-green">Exists</span>'
|
||||
: '<span class="badge badge-red">Not found</span>'}</span>
|
||||
</div>
|
||||
<div class="stat-row">
|
||||
<span class="stat-label">Storage</span>
|
||||
<span class="stat-value">${infra?.spaces?.configured
|
||||
? '<span class="badge badge-green">Configured</span>'
|
||||
: '<span class="badge badge-gray">Not configured</span>'}</span>
|
||||
</div>
|
||||
${infra?.spaces?.configured ? `
|
||||
<div class="stat-row">
|
||||
<span class="stat-label">Bucket</span>
|
||||
<span class="stat-value" style="font-family:monospace;font-size:0.8rem">${infra.spaces.bucket}</span>
|
||||
</div>
|
||||
<div class="stat-row">
|
||||
<span class="stat-label">Prefix</span>
|
||||
<span class="stat-value" style="font-family:monospace;font-size:0.8rem">${infra.spaces.prefix}</span>
|
||||
</div>` : ''}
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="card-title">Provisioning Steps</div>
|
||||
<div class="step-list">${stepsHtml}</div>
|
||||
|
||||
@@ -219,19 +219,44 @@ export async function customerRoutes(app: FastifyInstance) {
|
||||
statusEntry = { data: liveStatus, cachedAt: new Date().toISOString() };
|
||||
}
|
||||
|
||||
// ── Size history (last 30 days) ───────────────────────────────────────────
|
||||
const sizeHistory = await db`
|
||||
// ── Infrastructure checks ─────────────────────────────────────────────────
|
||||
const [dbCheck, sizeHistory, secrets] = await Promise.allSettled([
|
||||
// Try connecting to the customer DB
|
||||
(async () => {
|
||||
const sql = postgres(config.doadminDbUrl.replace(/\/([^/?]+)(\?|$)/, `/${slug}$2`), { max: 1, connect_timeout: 5 });
|
||||
try {
|
||||
await sql`SELECT 1`;
|
||||
return true;
|
||||
} finally {
|
||||
await sql.end();
|
||||
}
|
||||
})(),
|
||||
db`
|
||||
SELECT recorded_at, db_size_bytes, spaces_size_bytes, spaces_object_count
|
||||
FROM customer_size_snapshots
|
||||
WHERE slug = ${slug}
|
||||
ORDER BY recorded_at DESC
|
||||
LIMIT 30
|
||||
`;
|
||||
`,
|
||||
getSecret(namespace, "lunarfront-secrets").catch(() => null),
|
||||
]);
|
||||
|
||||
const dbExists = dbCheck.status === "fulfilled" ? dbCheck.value : false;
|
||||
const secretData = secrets.status === "fulfilled" ? secrets.value : null;
|
||||
const infra = {
|
||||
database: { exists: dbExists },
|
||||
spaces: {
|
||||
configured: !!(secretData?.["spaces-prefix"]),
|
||||
bucket: secretData?.["spaces-bucket"] ?? null,
|
||||
prefix: secretData?.["spaces-prefix"] ?? null,
|
||||
},
|
||||
};
|
||||
|
||||
return reply.send({
|
||||
customer,
|
||||
status: { ...statusEntry.data, cachedAt: statusEntry.cachedAt },
|
||||
sizeHistory,
|
||||
infra,
|
||||
sizeHistory: sizeHistory.status === "fulfilled" ? sizeHistory.value : [],
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user