mirror of
https://github.com/juherr/kill-the-news.git
synced 2026-06-20 22:03:48 +00:00
refactor(api): remove the deprecated /api/stats endpoint
The only consumer (the marketing landing) now uses /api/v1/stats, so drop the legacy /api/stats route and its handler. Delete src/routes/stats.ts and its test; repoint the index CORS test at /api/v1/stats. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+2
-2
@@ -45,9 +45,9 @@ describe("CORS middleware", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("makes /api/stats readable from any origin", async () => {
|
||||
it("makes /api/v1/stats readable from any origin", async () => {
|
||||
const res = await worker.fetch(
|
||||
req("/api/stats", { headers: { Origin: "https://example.com" } }),
|
||||
req("/api/v1/stats", { headers: { Origin: "https://example.com" } }),
|
||||
env as unknown as Env,
|
||||
);
|
||||
expect(res.status).toBe(200);
|
||||
|
||||
+1
-6
@@ -6,7 +6,6 @@ import { handle as handleAtom } from "./routes/atom";
|
||||
import { handle as handleAdmin } from "./routes/admin";
|
||||
import { handle as handleEntry } from "./routes/entries";
|
||||
import { handle as handleFiles } from "./routes/files";
|
||||
import { handle as handleStats } from "./routes/stats";
|
||||
import { handle as handleHome } from "./routes/home";
|
||||
import { handle as handleFavicon, handleFeedFavicon } from "./routes/favicon";
|
||||
import { hubRouter } from "./routes/hub";
|
||||
@@ -148,10 +147,6 @@ api.use("/inbound", async (c, next) => {
|
||||
// API routes (inbound webhook)
|
||||
api.post("/inbound", handleInbound);
|
||||
|
||||
// Public monitoring stats (JSON) — readable from any origin (landing page, embeds)
|
||||
api.use("/stats", cors({ origin: "*" }));
|
||||
api.get("/stats", handleStats);
|
||||
|
||||
// RSS feed routes (public)
|
||||
rss.get("/:feedId", handleRSS);
|
||||
|
||||
@@ -223,7 +218,7 @@ export default {
|
||||
logger.info("Feed TTL cleanup", { deleted: expiredIds.length });
|
||||
}
|
||||
|
||||
// Refresh the cached storage-usage snapshot for the status page / /api/stats.
|
||||
// Refresh the cached storage-usage snapshot for the status page / /api/v1/stats.
|
||||
try {
|
||||
const r2 = attachmentBucket
|
||||
? await scanR2Usage(attachmentBucket)
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import worker from "../index";
|
||||
import { createMockEnv } from "../test/setup";
|
||||
import { bumpCounters } from "../utils/stats";
|
||||
import { FEEDS_LIST_KEY } from "../config/constants";
|
||||
import type { Env, StatsResponse } from "../types";
|
||||
|
||||
function req(path: string, init: RequestInit = {}): Request {
|
||||
return new Request(`https://test.getmynews.app${path}`, init);
|
||||
}
|
||||
|
||||
describe("GET /api/stats", () => {
|
||||
it("returns zeroed stats for a fresh instance", async () => {
|
||||
const env = createMockEnv() as unknown as Env;
|
||||
const res = await worker.fetch(req("/api/stats"), env);
|
||||
expect(res.status).toBe(200);
|
||||
const body = (await res.json()) as StatsResponse;
|
||||
expect(body).toMatchObject({
|
||||
feeds_created: 0,
|
||||
feeds_deleted: 0,
|
||||
emails_received: 0,
|
||||
emails_rejected: 0,
|
||||
active_feeds: 0,
|
||||
websub_subscriptions_active: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it("reflects persisted counters and live values", async () => {
|
||||
const env = createMockEnv() as unknown as Env;
|
||||
await env.EMAIL_STORAGE.put(
|
||||
FEEDS_LIST_KEY,
|
||||
JSON.stringify({ feeds: [{ id: "a", title: "A" }] }),
|
||||
);
|
||||
await env.EMAIL_STORAGE.put("websub:a:hash", "{}");
|
||||
await bumpCounters(env.EMAIL_STORAGE, {
|
||||
emails_received: 3,
|
||||
emails_rejected: 1,
|
||||
feeds_created: 1,
|
||||
});
|
||||
|
||||
const res = await worker.fetch(req("/api/stats"), env);
|
||||
const body = (await res.json()) as StatsResponse;
|
||||
expect(body.active_feeds).toBe(1);
|
||||
expect(body.websub_subscriptions_active).toBe(1);
|
||||
expect(body.emails_received).toBe(3);
|
||||
expect(body.emails_rejected).toBe(1);
|
||||
expect(body.feeds_created).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET / (public status page)", () => {
|
||||
it("returns an HTML status page with counters and an admin link", async () => {
|
||||
const env = createMockEnv() as unknown as Env;
|
||||
await bumpCounters(env.EMAIL_STORAGE, { emails_received: 7 });
|
||||
|
||||
const res = await worker.fetch(req("/"), env);
|
||||
expect(res.status).toBe(200);
|
||||
expect(res.headers.get("Content-Type")).toContain("text/html");
|
||||
|
||||
const html = await res.text();
|
||||
expect(html).toContain('href="/admin"');
|
||||
expect(html).toContain("Active feeds");
|
||||
expect(html).toContain("Emails received");
|
||||
expect(html).toContain("7");
|
||||
});
|
||||
});
|
||||
@@ -1,7 +0,0 @@
|
||||
import { Context } from "hono";
|
||||
import { Env } from "../types";
|
||||
import { getStats } from "../utils/stats";
|
||||
|
||||
export async function handle(c: Context<{ Bindings: Env }>): Promise<Response> {
|
||||
return c.json(await getStats(c.env));
|
||||
}
|
||||
Reference in New Issue
Block a user