Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
Commit76ee7bc

fix(routing): unshadow /orgs/:slug/health so the org-health page is reachable

fix(routing): unshadow /orgs/:slug/health so the org-health page is reachable

org-health.tsx's `GET /orgs/:slug/health` was mounted after
healthDashboardRoutes' generic `GET /:owner/:repo/health`, so Hono bound
/orgs/<slug>/health as owner="orgs", repo="<slug>" → repoExists false →
404. The entire org-health feature was dead code (its own recompute POST
redirected into the 404). Move orgHealthRoutes ahead of the generic repo
health route, mirroring the orgInsightsRoutes-before-insightRoutes fix.

Adds a DB-gated regression test that seeds a real org and asserts the
org-health page renders (200 + "Engineering Health") rather than 404.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ccantynz-alt committed on July 24, 2026Parent: 2cc8e18
2 files changed+77276ee7bc35a025254c963ee56429380c8d78dd024
2 changed files+77−2
Addedsrc/__tests__/org-health-route.test.ts+67−0View fileUnifiedSplit
1/**
2 * Regression: /orgs/:slug/health must reach org-health, not be shadowed.
3 *
4 * org-health.tsx's `GET /orgs/:slug/health` was mounted AFTER
5 * healthDashboardRoutes' generic `GET /:owner/:repo/health`, so Hono bound
6 * `/orgs/acme/health` as owner="orgs", repo="acme" → repoExists("orgs","acme")
7 * false → 404. The entire org-health feature was dead (unreachable), and its
8 * own recompute POST redirected into that 404. Mount order now puts
9 * orgHealthRoutes first.
10 *
11 * An UNKNOWN slug can't distinguish the two handlers (both 404), so this test
12 * seeds a REAL org and asserts the org-health page renders (200 + its own
13 * "Engineering Health" markup). Under the old shadowed mount this 404'd.
14 * DB-gated: skips locally without DATABASE_URL, runs in CI/deploy.
15 */
16import { describe, it, expect } from "bun:test";
17import app from "../app";
18import { db } from "../db";
19import { users, organizations } from "../db/schema";
20import { eq } from "drizzle-orm";
21
22const HAS_DB = Boolean(process.env.DATABASE_URL);
23
24describe("org-health route is not shadowed by the repo health page", () => {
25 it.skipIf(!HAS_DB)(
26 "/orgs/:slug/health renders the org-health page (not a repo 404)",
27 async () => {
28 // Deterministic slug so a re-run can clean up first (no Math.random()).
29 const slug = "orghealth-route-test-org";
30 const uname = "orghealth-route-test-user";
31 // Clean any leftovers from a prior run.
32 await db.delete(organizations).where(eq(organizations.slug, slug));
33 await db.delete(users).where(eq(users.username, uname));
34
35 const [u] = await db
36 .insert(users)
37 .values({
38 username: uname,
39 email: `${uname}@example.test`,
40 passwordHash: "x",
41 })
42 .returning({ id: users.id });
43 await db.insert(organizations).values({
44 slug,
45 name: "Org Health Route Test",
46 createdById: u.id,
47 });
48
49 try {
50 const res = await app.request(`/orgs/${slug}/health`);
51 expect(res.status).toBe(200);
52 const body = await res.text();
53 expect(body).toContain("Engineering Health");
54 } finally {
55 await db.delete(organizations).where(eq(organizations.slug, slug));
56 await db.delete(users).where(eq(users.username, uname));
57 }
58 }
59 );
60
61 it("a genuine unknown repo health page still 404s through the repo handler", async () => {
62 // Proves orgHealthRoutes' literal /orgs prefix didn't swallow generic
63 // repo paths (this runs without a DB — it's a pure not-found path).
64 const res = await app.request("/nobody-xyz/nothing-xyz/health");
65 expect(res.status).toBe(404);
66 });
67});
Modifiedsrc/app.tsx+10−2View fileUnifiedSplit
716716// dashboard existing didn't stop this specific admin page being unreachable.
717717app.route("/", adminRoutes);
718718
719// Org health — MUST be mounted BEFORE healthDashboardRoutes. Its literal
720// `/orgs/:slug/health` was shadowed by healthDashboardRoutes' generic
721// `/:owner/:repo/health` (matching :owner=orgs :repo=<slug>), so every
722// org-health page 404'd and the whole feature was dead. Mirrors the
723// orgInsightsRoutes-before-insightRoutes fix below. org-health only matches
724// the literal `/orgs/...` prefix, so mounting it first is safe.
725app.route("/", orgHealthRoutes);
726
719727// Health dashboard (per-repo health page)
720728app.route("/", healthDashboardRoutes);
721729
835843app.route("/", marketplaceAgentsRoutes);
836844app.route("/", mergeQueueRoutes);
837845app.route("/", mirrorsRoutes);
838// orgInsightsRoutes is mounted earlier (before insightRoutes) — see the note there.
839app.route("/", orgHealthRoutes);
846// orgInsightsRoutes + orgHealthRoutes are mounted earlier (before the generic
847// repo routes) — see the notes there.
840848app.route("/", packagesRoutes);
841849app.route("/", packagesApiRoutes);
842850// OCI / Docker container registry — /v2/* (OCI Distribution Spec v1.0)
843851