mirror of
https://github.com/juherr/kill-the-news.git
synced 2026-06-20 22:03:48 +00:00
feat(api): expose app version in /api/v1/stats
Add version to StatsResponse and getStats so the canonical public monitoring endpoint reports the running build alongside the footer and /health. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -192,7 +192,7 @@ Breakdown of the _"Per-feed favicon from the last sender's domain"_ item above (
|
||||
|
||||
Self-host operational quality-of-life: knowing which version you run, when to update, and how many people run KTN.
|
||||
|
||||
- [x] `P3·S` **Display the running version** **[table-stakes, easy]** — surface the deployed app version (from `package.json` `version`, currently `0.2.1`) somewhere visible: the admin UI footer and/or the public status page (`src/routes/home.tsx`), and ideally the `/health` JSON. Bundle the version at build time (inline the `package.json` version into the Worker, since there's no filesystem at runtime) and render it. Foundation for the update-notification item below. — **Shipped:** `package.json` version is inlined at bundle time via `src/config/version.ts` (`import pkg from "../../package.json"`, `resolveJsonModule`), exposed as `APP_VERSION`; rendered in the shared admin/status footer (`src/routes/admin/ui.tsx` Layout, so both the status page and admin show it) and added to the `/health` JSON. — _origin: internal_
|
||||
- [x] `P3·S` **Display the running version** **[table-stakes, easy]** — surface the deployed app version (from `package.json` `version`, currently `0.2.1`) somewhere visible: the admin UI footer and/or the public status page (`src/routes/home.tsx`), and ideally the `/health` JSON. Bundle the version at build time (inline the `package.json` version into the Worker, since there's no filesystem at runtime) and render it. Foundation for the update-notification item below. — **Shipped:** `package.json` version is inlined at bundle time via `src/config/version.ts` (`import pkg from "../../package.json"`, `resolveJsonModule`), exposed as `APP_VERSION`; rendered in the shared admin/status footer (`src/routes/admin/ui.tsx` Layout, so both the status page and admin show it), added to the `/health` JSON, and to the canonical monitoring endpoint `/api/v1/stats` (`StatsResponse.version`, public). — _origin: internal_
|
||||
|
||||
- [ ] `P3·M` **Notify when an update is available** **[differentiating for self-hosters]** — compare the running version against the latest GitHub Release tag and show a discreet "update available → vX.Y.Z" banner in the admin UI when behind. Fetch `https://api.github.com/repos/<owner>/<repo>/releases/latest` (cache aggressively — Cache API / KV with a long TTL — to respect GitHub rate limits and avoid a call per page load), compare semver against the bundled version. Depends on the "display version" item. Keep it opt-out-able (it makes one outbound call). — _origin: internal_
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Counters, Env, StatsResponse } from "../types";
|
||||
import { APP_VERSION } from "../config/version";
|
||||
import { logger } from "../infrastructure/logger";
|
||||
import { FeedRepository } from "../infrastructure/feed-repository";
|
||||
import { CountersRepository } from "../infrastructure/counters-repository";
|
||||
@@ -77,6 +78,7 @@ export async function getStats(env: Env): Promise<StatsResponse> {
|
||||
active_feeds: feeds.length,
|
||||
websub_subscriptions_active: websubCount,
|
||||
attachments_enabled: !!getAttachmentBucket(env),
|
||||
version: APP_VERSION,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -295,10 +295,12 @@ describe("REST API (/api/v1)", () => {
|
||||
feeds_created: number;
|
||||
active_feeds: number;
|
||||
attachments_enabled: boolean;
|
||||
version: string;
|
||||
};
|
||||
expect(stats.feeds_created).toBeGreaterThanOrEqual(1);
|
||||
expect(stats.active_feeds).toBeGreaterThanOrEqual(1);
|
||||
expect(typeof stats.attachments_enabled).toBe("boolean");
|
||||
expect(stats.version).toMatch(/^\d+\.\d+\.\d+/);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -154,6 +154,9 @@ export const StatsSchema = z
|
||||
active_feeds: z.number(),
|
||||
websub_subscriptions_active: z.number(),
|
||||
attachments_enabled: z.boolean(),
|
||||
version: z.string().openapi({
|
||||
description: "Running app version (package.json), inlined at build time.",
|
||||
}),
|
||||
last_email_at: z.string().optional(),
|
||||
last_feed_created_at: z.string().optional(),
|
||||
first_seen: z.string().optional(),
|
||||
|
||||
@@ -125,6 +125,7 @@ export interface StatsResponse extends Counters {
|
||||
active_feeds: number;
|
||||
websub_subscriptions_active: number;
|
||||
attachments_enabled: boolean;
|
||||
version: string; // Running app version (package.json), inlined at build time
|
||||
}
|
||||
|
||||
// WebSub (PubSubHubbub) subscription configuration
|
||||
|
||||
Reference in New Issue
Block a user