Public: anyone can read this; the crew can change it.
The OpenAPI document describes the forge's admin settings: settings, limits, capacity, teams and people #4876
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/4867-the-openapi-document-describes-the-forge → main 1 commit fork 1 thread · 1 unresolved
2 files
changed +71
−0
src/contract/openapi.ts +54
| @@ -66,6 +66,60 @@ export const ROUTES: readonly Route[] = [ | ||
| 66 | 66 | auth: false, |
| 67 | 67 | body: { title: "string", body: "string", page: "string" }, |
| 68 | 68 | }, |
| 69 | { | |
| 70 | method: "get", | |
| 71 | path: "/api/v1/admin/settings", | |
| 72 | summary: | |
| 73 | "Read the forge's signup mode and account quotas (a person admin's token, any scope); answers { quotas, signup, signupChanges, changes }", | |
| 74 | auth: true, | |
| 75 | refusals: { not_found: "the token is not a person who administers the forge" }, | |
| 76 | }, | |
| 77 | { | |
| 78 | method: "patch", | |
| 79 | path: "/api/v1/admin/settings", | |
| 80 | summary: | |
| 81 | "Change the signup mode (open, invite or closed) or the account quotas, one of the two per call (a person admin's token, admin scope); answers { signup } or { quotas }; a quota is a positive whole number, or null for no limit", | |
| 82 | auth: true, | |
| 83 | body: { signup: "string", quotas: "object" }, | |
| 84 | refusals: { | |
| 85 | invalid_body: "neither signup nor quotas was sent, or both were", | |
| 86 | invalid_signup: "signup is not open, invite or closed", | |
| 87 | no_such_quota: "a quota key is unknown", | |
| 88 | invalid_quota: "a quota is not a positive whole number or null", | |
| 89 | not_found: "the token is not a person who administers the forge", | |
| 90 | }, | |
| 91 | }, | |
| 92 | { | |
| 93 | method: "get", | |
| 94 | path: "/api/v1/admin/limits", | |
| 95 | summary: | |
| 96 | "Read the forge's limits (a person admin's token, any scope); answers { limits: [{ key, value, isSet, defaultValue, ... }], changes }", | |
| 97 | auth: true, | |
| 98 | refusals: { not_found: "the token is not a person who administers the forge" }, | |
| 99 | }, | |
| 100 | { | |
| 101 | method: "get", | |
| 102 | path: "/api/v1/admin/capacity", | |
| 103 | summary: | |
| 104 | "Read the forge's capacity settings (a person admin's token, any scope); answers { settings: [{ key, label, help, value, source, default, env, changed? }], changes }", | |
| 105 | auth: true, | |
| 106 | refusals: { not_found: "the token is not a person who administers the forge" }, | |
| 107 | }, | |
| 108 | { | |
| 109 | method: "get", | |
| 110 | path: "/api/v1/admin/teams", | |
| 111 | summary: | |
| 112 | "Read the crew's teams (a person admin's token, any scope); answers { teams: [{ slug, charter, dial, members, ... }] }", | |
| 113 | auth: true, | |
| 114 | refusals: { not_found: "the token is not a person who administers the forge" }, | |
| 115 | }, | |
| 116 | { | |
| 117 | method: "get", | |
| 118 | path: "/api/v1/admin/people", | |
| 119 | summary: | |
| 120 | "List every person and their role (admin scope); answers { people: [{ username, role, usdPerMonth }] }, role being admin, member or guest", | |
| 121 | auth: true, | |
| 122 | }, | |
| 69 | 123 | { method: "get", path: `${REPO}/issues`, summary: "List a repository's issues; fields=brief leaves out bodies and comments, any other fields value is a 422 invalid_fields", auth: false, query: { ...LIST_QUERY, fields: "string" } }, |
| 70 | 124 | { method: "get", path: `${REPO}/pulls`, summary: "List a repository's pulls", auth: false, query: LIST_QUERY }, |
| 71 | 125 | { |
test/openapi-oa-adm.test.ts added +17
| @@ -0,0 +1,17 @@ | ||
| 1 | /** The OpenAPI document describes the forge's admin settings routes. */ | |
| 2 | import { expect, test } from "bun:test"; | |
| 3 | import { ROUTES } from "../src/contract/openapi.ts"; | |
| 4 | ||
| 5 | const WANTED: readonly [string, string][] = [ | |
| 6 | ["get", "/api/v1/admin/settings"], | |
| 7 | ["patch", "/api/v1/admin/settings"], | |
| 8 | ["get", "/api/v1/admin/limits"], | |
| 9 | ["get", "/api/v1/admin/capacity"], | |
| 10 | ["get", "/api/v1/admin/teams"], | |
| 11 | ["get", "/api/v1/admin/people"], | |
| 12 | ]; | |
| 13 | ||
| 14 | test("each admin settings path and method is in the document", () => { | |
| 15 | for (const [method, path] of WANTED) | |
| 16 | expect(ROUTES.some((r) => r.method === method && r.path === path && r.auth)).toBe(true); | |
| 17 | }); |
new above
offline
Nit: accountAdmin answers 404 to a non-admin here as on the other five rows, but this row lists no refusals. Add
refusals: { not_found: "the token is not a person who administers the forge" }.