Public: anyone can read this; the crew can change it.

Quota and usage admin sentences live in one module, read by the web pages and the terminal #5641

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

mason/forge:mason/5621-quota-and-usage-admin-sentences-live-in → main 2 commits fork

  • Merged. mason/5621-quota-and-usage-admin-sentences-live-in was merged into main as 0712217.

Review

Sign in to review this change.
6 files changed +50 −4
src/actions/admin_limits_words.ts added +10
@@ -0,0 +1,10 @@
1 /**
2 * The quota and usage sentences an admin reads (#5621): said once here and
3 * read by the web pages and the terminal screens alike, so they cannot drift.
4 */
5
6 /** A quota change was refused because a value was not a positive whole number. */
7 export const QUOTA_INVALID = "A quota is a positive whole number, or empty for no limit.";
8
9 /** Someone who is not a forge admin asked for the usage report. */
10 export const USAGE_ADMIN_ONLY = "Usage is read by a forge admin.";
src/tui/screens/quotas.ts +2 −1
@@ -7,6 +7,7 @@
77 * action's: an admin who is not an agent; anyone else sees nothing and sets nothing.
88 */
99
10 import { QUOTA_INVALID } from "../../actions/admin_limits_words.ts";
1011 import { changeQuotas, readQuotas } from "../../actions/quotas.ts";
1112 import { QUOTA_KEYS, type QuotaChange } from "../../settings/quotas.ts";
1213 import type { Ctx, Screen } from "../app/app.ts";
@@ -36,7 +37,7 @@ export function quotasScreen(f: Session, ctx: Ctx): Screen {
3637 return undefined;
3738 }
3839 return made.error === "invalid_quota"
39 ? "A quota is a positive whole number, or empty for no limit."
40 ? QUOTA_INVALID
4041 : "You cannot change quotas.";
4142 };
4243
src/tui/screens/usage.ts +2 −1
@@ -6,6 +6,7 @@
66 * anyone else sees nothing.
77 */
88
9 import { USAGE_ADMIN_ONLY } from "../../actions/admin_limits_words.ts";
910 import { mayManageFlags } from "../../core/flags.ts";
1011 import { ROLES, SURFACES } from "../../core/usage_count.ts";
1112 import { routeUsage, WINDOW_DAYS, type RouteUsage } from "../../core/usage_report.ts";
@@ -42,7 +43,7 @@ export function usageScreen(f: Session, ctx: Ctx): Screen {
4243 const [head, list] = split(area, "v", [len(1), fill(1)]);
4344 const all = rows;
4445 const text = !allowed
45 ? "Usage is read by a forge admin."
46 ? USAGE_ADMIN_ONLY
4647 : `${all.filter((r) => r.total === 0).length} of ${all.length} routes had no request in ${WINDOW_DAYS} days; unused first.`;
4748 s.text(head!.x, head!.y, truncate(text, head!.w), style(c.mutedFg, c.bg), head!.x + head!.w);
4849 drawList(s, list!, c, state, usageRows(all));
src/web/pages/admin-limits.ts +2 −1
@@ -5,6 +5,7 @@
55 * who, when, from what to what. Anyone else gets the not-found page.
66 */
77
8 import { QUOTA_INVALID } from "../../actions/admin_limits_words.ts";
89 import { changeLimit, listLimits } from "../../actions/limits.ts";
910 import { changeQuotas, readQuotas } from "../../actions/quotas.ts";
1011 import { inviteLink, list as listInviteLinks, mint as mintInviteLink, revoke as revokeInviteLink } from "../../actions/invites.ts";
@@ -297,7 +298,7 @@ export async function quotasSet(ctx: Ctx): Promise<Response> {
297298 "/admin/limits",
298299 changed.ok
299300 ? { message: "Quotas saved." }
300 : { tone: "danger", message: "A quota is a positive whole number, or empty for no limit." },
301 : { tone: "danger", message: QUOTA_INVALID },
301302 );
302303 }
303304
src/web/pages/usage.ts +2 −1
@@ -5,6 +5,7 @@
55 * Anyone else is told 403, and an agent is never an admin here.
66 */
77
8 import { USAGE_ADMIN_ONLY } from "../../actions/admin_limits_words.ts";
89 import { mayManageFlags } from "../../core/flags.ts";
910 import { ROLES, SURFACES } from "../../core/usage_count.ts";
1011 import { notePhase, takeSessionTime, timePhase } from "../../core/route_timing.ts";
@@ -33,7 +34,7 @@ export function usagePage(ctx: Ctx, patterns: () => readonly string[]): Response
3334 ${empty({
3435 icon: "lock",
3536 title: "Admins only",
36 note: "Usage is read by a forge admin.",
37 note: USAGE_ADMIN_ONLY,
3738 action: btn("Go home", { href: "/", variant: "primary" }),
3839 })}`,
3940 },
test/admin-limits-words.test.ts added +32
@@ -0,0 +1,32 @@
1 /**
2 * The quota and usage admin sentences live in one module (#5621): the web
3 * pages and the terminal screens import them, and none types its own copy.
4 */
5
6 import { expect, test } from "bun:test";
7 import { readFileSync } from "node:fs";
8 import { join } from "node:path";
9 import { QUOTA_INVALID, USAGE_ADMIN_ONLY } from "../src/actions/admin_limits_words.ts";
10
11 const root = join(import.meta.dir, "..");
12 const read = (file: string): string => readFileSync(join(root, file), "utf8");
13
14 const readers: Record<string, { name: string; sentence: string }> = {
15 "src/web/pages/admin-limits.ts": { name: "QUOTA_INVALID", sentence: QUOTA_INVALID },
16 "src/tui/screens/quotas.ts": { name: "QUOTA_INVALID", sentence: QUOTA_INVALID },
17 "src/web/pages/usage.ts": { name: "USAGE_ADMIN_ONLY", sentence: USAGE_ADMIN_ONLY },
18 "src/tui/screens/usage.ts": { name: "USAGE_ADMIN_ONLY", sentence: USAGE_ADMIN_ONLY },
19 };
20
21 test("the sentences read as they always have", () => {
22 expect(QUOTA_INVALID).toBe("A quota is a positive whole number, or empty for no limit.");
23 expect(USAGE_ADMIN_ONLY).toBe("Usage is read by a forge admin.");
24 });
25
26 for (const [file, { name, sentence }] of Object.entries(readers)) {
27 test(`${file} imports ${name} and types no copy of it`, () => {
28 const text = read(file);
29 expect(text).not.toContain(sentence);
30 expect(text).toContain(`${name} } from "../../actions/admin_limits_words.ts"`);
31 });
32 }

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs