--- title: Repo Sync Health --- # Repo Sync Health ```js const repoData = await FileAttachment("data/repos.json").json(); const inventory = await FileAttachment("data/gitea-inventory.json").json(); const repos = Array.isArray(repoData) ? repoData : (repoData.repos ?? []); ``` ```js // Helpers function ageMs(ts) { if (!ts) return Infinity; return Date.now() - new Date(ts).getTime(); } function fmtAge(ts) { if (!ts) return "never"; const ms = ageMs(ts); const m = Math.floor(ms / 60000); if (m < 60) return `${m}m ago`; const h = Math.floor(m / 60); if (h < 24) return `${h}h ago`; return `${Math.floor(h / 24)}d ago`; } function syncColor(ts) { if (!ts) return "var(--theme-red)"; const h = ageMs(ts) / 3600000; if (h < 1) return "var(--theme-green)"; if (h < 24) return "var(--theme-orange)"; return "var(--theme-red)"; } ``` ## Registered Repos — Sync Status ```js const activeRepos = repos.filter(r => r.status === "active"); const staleCount = activeRepos.filter(r => !r.last_state_synced_at || ageMs(r.last_state_synced_at) > 86400000).length; const freshCount = activeRepos.filter(r => r.last_state_synced_at && ageMs(r.last_state_synced_at) < 3600000).length; const sbomCount = activeRepos.filter(r => r.last_sbom_at).length; const noSbomCount = activeRepos.length - sbomCount; ``` ```js display(html`
${freshCount}
state synced < 1h
${staleCount}
state stale / never
${sbomCount}
SBOM ingested
${noSbomCount}
no SBOM yet
${activeRepos.length}
total active
`); ``` ```js const table = html` ${activeRepos .sort((a, b) => ageMs(a.last_state_synced_at) - ageMs(b.last_state_synced_at)) .map(r => html``) }
Repo Domain Last Synced Last SBOM Entries Status
${r.slug} ${r.domain_slug} ${fmtAge(r.last_state_synced_at)} ${fmtAge(r.last_sbom_at)} ${r.sbom_entry_count > 0 ? r.sbom_entry_count.toLocaleString() : "—"} ${r.status}
`; display(table); ``` --- ## Gitea Inventory — Unregistered Repos _Repos on Gitea (`coulomb` org) not yet tracked by the state-hub._ ```js const unregistered = inventory.unregistered ?? []; ``` ```js if (unregistered.length === 0) { display(html`

🎉 All Gitea repos are registered!

`); } else { display(html` ${unregistered.map(r => html``)}
Repo Language Description Onboard
${r.gitea_name} ${r.language || "—"} ${r.description || "—"} make register-project DOMAIN=? PROJECT_PATH=/home/worsch/${r.gitea_name}
`); } ``` --- ## Hub-Only Repos _Registered in the state-hub but no matching Gitea repo found._ ```js const hubOnly = inventory.hub_only ?? []; ``` ```js if (hubOnly.length === 0) { display(html`

None — all hub repos have a Gitea counterpart.

`); } else { display(html``); } ``` --- _Sync legend: 🟢 < 1h   🟠 1–24h   🔴 > 24h or never_ _Gitea token required for full inventory — set GITEA_TOKEN in state-hub/.env._