Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@moonlight-protocol/provider-platform",
"version": "0.7.2",
"version": "0.7.3",
"license": "MIT",
"exports": "./src/main.ts",
"tasks": {
Expand Down
86 changes: 1 addition & 85 deletions src/http/v1/dashboard/routes.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,11 @@
import { type Context, Router, Status } from "@oak/oak";
import { Router } from "@oak/oak";
import type { Logger } from "@/utils/logger/index.ts";
import { handlePostChallenge } from "./auth/challenge.ts";
import { handlePostVerify } from "./auth/verify.ts";
import { handleDiscoverCouncil } from "./council.ts";
import { handleListPps, handleRegisterPp } from "./pp.ts";
import { jwtMiddleware } from "@/http/middleware/auth/index.ts";

/**
* Per-PP endpoints whose canonical home is /providers/:ppPublicKey/... now
* answer 410 Gone here. The body names the new URL pattern so callers can
* migrate. This is a temporary deprecation surface; a follow-up PR removes
* these stubs once metrics confirm zero traffic.
*
* Two routes are bare-deleted instead of stubbed (per PM scope decision):
* - POST /dashboard/bundles/expire (no external callers; admin-only)
* - GET /dashboard/bundles (duplicated by PR #106's URL-scoped variant)
*/
function gone(newPath: string): (ctx: Context) => void {
return (ctx) => {
ctx.response.status = Status.Gone;
ctx.response.body = {
message:
`This endpoint has moved. Use ${newPath} (per-PP URL-scoped path).`,
};
};
}

export function buildDashboardRouter(deps: { log: Logger }): Router {
const dashboardRouter = new Router();

Expand All @@ -52,69 +32,5 @@ export function buildDashboardRouter(deps: { log: Logger }): Router {
handleDiscoverCouncil(deps),
);

// --- 410 Gone stubs for migrated per-PP routes ---
dashboardRouter.post(
"/dashboard/pp/delete",
gone("DELETE /api/v1/providers/:ppPublicKey"),
);
dashboardRouter.get(
"/dashboard/channels",
gone("GET /api/v1/providers/:ppPublicKey/channels"),
);
dashboardRouter.get(
"/dashboard/mempool",
gone("GET /api/v1/providers/:ppPublicKey/mempool"),
);
dashboardRouter.get(
"/dashboard/operations",
gone("GET /api/v1/providers/:ppPublicKey/operations"),
);
dashboardRouter.get(
"/dashboard/treasury",
gone("GET /api/v1/providers/:ppPublicKey/treasury"),
);
dashboardRouter.get(
"/dashboard/utxos",
gone("GET /api/v1/providers/:ppPublicKey/utxos?channelContractId=..."),
);
dashboardRouter.get(
"/dashboard/transactions",
gone("GET /api/v1/providers/:ppPublicKey/transactions"),
);
dashboardRouter.get(
"/dashboard/transactions/:id",
gone("GET /api/v1/providers/:ppPublicKey/transactions/:id"),
);
dashboardRouter.get(
"/dashboard/bundles/:id",
gone("GET /api/v1/providers/:ppPublicKey/bundles/:id"),
);
dashboardRouter.get(
"/dashboard/audit-export",
gone("GET /api/v1/providers/:ppPublicKey/audit-export"),
);
dashboardRouter.get(
"/dashboard/metrics",
gone("GET /api/v1/providers/:ppPublicKey/metrics"),
);
dashboardRouter.post(
"/dashboard/council/join",
gone("POST /api/v1/providers/:ppPublicKey/council/join"),
);
dashboardRouter.get(
"/dashboard/council/membership",
gone("GET /api/v1/providers/:ppPublicKey/council/membership"),
);
dashboardRouter.post(
"/dashboard/council/membership",
gone("POST /api/v1/providers/:ppPublicKey/council/membership"),
);

// NOTE: POST /dashboard/bundles/expire and GET /dashboard/bundles (query
// variant) are intentionally NOT registered here — bare-deleted per PM
// scope. The canonical bundle list endpoints are URL-scoped:
// GET /providers/:ppPublicKey/bundles (provider/operator view)
// GET /providers/:ppPublicKey/entity/bundles (entity/submitter view)

return dashboardRouter;
}
26 changes: 0 additions & 26 deletions src/http/v1/entities/routes.ts

This file was deleted.

26 changes: 0 additions & 26 deletions src/http/v1/events/routes.ts

This file was deleted.

14 changes: 0 additions & 14 deletions src/http/v1/v1.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import { buildPayRouter } from "@/http/v1/pay/routes.ts";
import healthRouter from "@/http/v1/health/routes.ts";
import { buildWaitlistRouter } from "@/http/v1/waitlist/routes.ts";
import { buildCouncilRouter } from "@/http/v1/council/routes.ts";
import { buildEventsRouter } from "@/http/v1/events/routes.ts";
import { buildEntitiesRouter } from "@/http/v1/entities/routes.ts";
import { buildProvidersRouter } from "@/http/v1/providers/routes.ts";

export function buildApiRouter(deps: { log: Logger }): Router {
Expand All @@ -20,8 +18,6 @@ export function buildApiRouter(deps: { log: Logger }): Router {
const payRouter = buildPayRouter(deps);
const waitlistRouter = buildWaitlistRouter(deps);
const councilRouter = buildCouncilRouter(deps);
const eventsRouter = buildEventsRouter(deps);
const entitiesRouter = buildEntitiesRouter(deps);
const providersRouter = buildProvidersRouter(deps);

apiRouter.use(
Expand Down Expand Up @@ -55,16 +51,6 @@ export function buildApiRouter(deps: { log: Logger }): Router {
waitlistRouter.routes(),
waitlistRouter.allowedMethods(),
);
apiRouter.use(
"/api/v1",
eventsRouter.routes(),
eventsRouter.allowedMethods(),
);
apiRouter.use(
"/api/v1",
entitiesRouter.routes(),
entitiesRouter.allowedMethods(),
);
apiRouter.use(
"/api/v1",
providersRouter.routes(),
Expand Down
10 changes: 0 additions & 10 deletions tests/integration/http/bundle-admin.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import "../../ensure_test_env.ts";
import { Application, Router } from "@oak/oak";
import { assertEquals } from "@std/assert";
import { newNoop } from "@/utils/logger/index.ts";
import { buildDashboardRouter } from "@/http/v1/dashboard/routes.ts";
import { ensureInitialized, resetDb } from "../../test_helpers.ts";
Expand Down Expand Up @@ -76,12 +75,3 @@ Deno.test("GET /dashboard/bundles (query variant) is not routed (bare-deleted)",
throw new Error(`expected 404/405, got ${res.status}`);
}
});

Deno.test("GET /dashboard/bundles/:id is 410 Gone", async () => {
const app = await setup();
const res = await app.handle(
new Request(`${LIST_PATH}/some-id`, { method: "GET" }),
);
if (!res) throw new Error("No response from Oak app");
assertEquals(res.status, 410);
});
25 changes: 0 additions & 25 deletions tests/integration/http/dashboard-metrics.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,28 +237,3 @@ Deno.test("returns 401 when JWT is missing", async () => {
if (!response) throw new Error("No response from Oak app");
assertEquals(response.status, 401);
});

Deno.test("legacy /dashboard/metrics returns 410 Gone", async () => {
// Wired in the dashboard router; we just confirm the path-shape contract.
// Full coverage of the dashboard 410-stub surface lives in dashboard-routes
// — this assertion is here to flag any accidental re-enable.
const { buildDashboardRouter } = await import(
"@/http/v1/dashboard/routes.ts"
);
const app = new Application();
const apiRouter = new Router();
const dashboardRouter = buildDashboardRouter({ log: newNoop() });
apiRouter.use(
"/api/v1",
dashboardRouter.routes(),
dashboardRouter.allowedMethods(),
);
app.use(apiRouter.routes());
app.use(apiRouter.allowedMethods());

const res = await app.handle(
new Request("http://localhost/api/v1/dashboard/metrics", { method: "GET" }),
);
if (!res) throw new Error("No response");
assertEquals(res.status, 410);
});
20 changes: 0 additions & 20 deletions tests/integration/http/events-ws.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,23 +273,3 @@ Deno.test({
}
},
});

Deno.test("legacy /events/ws returns 410 Gone", async () => {
const { buildEventsRouter } = await import("@/http/v1/events/routes.ts");
const app = new Application();
const apiRouter = new Router();
const eventsRouter = buildEventsRouter({ log: newNoop() });
apiRouter.use(
"/api/v1",
eventsRouter.routes(),
eventsRouter.allowedMethods(),
);
app.use(apiRouter.routes());
app.use(apiRouter.allowedMethods());

const res = await app.handle(
new Request("http://localhost/api/v1/events/ws", { method: "GET" }),
);
if (!res) throw new Error("No response");
assertEquals(res.status, 410);
});
Loading