Audit and fix Swagger/OpenAPI accuracy; regenerate served spec #40
Reference in New Issue
Block a user
No description provided.
Delete Branch "docs/swagger-audit"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Audit of the Swagger/OpenAPI docs. Route-level annotations were already 100% present across all 67 endpoints — the issues were accuracy, not coverage. This aligns the annotations with actual controller behavior and regenerates the committed/served spec.
Stale served spec (was 64/67 operations)
swagger-output.jsonpredated three routes. Regenerating picks them up:POST /api/v1/auth/sso/totpGET /api/v1/admin/discord-bot/configPUT /api/v1/admin/discord-bot/configPlus a stale
/auth/logoutsummary.Response-shape corrections (annotation now matches controller)
Mutation endpoints do not return the generic
{ message }envelope:{ id }/{ slug }; toggles return{ deleted },{ unlinked },{ totp_enabled }, or{ ip, removed }— documented as-is via newDeletedId/DeletedSlug/DeletedFlag/UnlinkedFlag/TotpState/UnbanResultcomponents.POST /account/totp/setup:otpauth_url→otpauthUrl(TotpSetup)PUT /admin/site-mode:{ mode }→{ site_mode, changed_at, changed_by }(SiteModeState)GET /admin/account: fullUser→AccountStatusGET /account/identities: addlinked_at(LinkedIdentity)GET /public/status: addstatus_message(PublicStatus)POST /auth/sso/totp:userisSafeUser, not fullUserGET /dashboard: description/shape corrected (posts + users counts, no wiki)Schema completeness
Provider(public discovery):{ id, name, icon, loginUrl, priority }, not{ id, name, kind }ProviderConfig: addhasSecret,builtin,health(ProviderHealth)Post: addexcerpt,author_id,published_atMobileTokenResponse.expiresIn: duration string ("15m"), not integer secondsConfig
Admin · Discord Bottag (was used by routes but undeclared).Verified correct — left unchanged
extractTokenreads both; mobile access tokens are full sessions), so the dualcookieAuth+bearerAuthannotations are accurate and the schemes stay distinct./internal/*(returns the decrypted Discord bot token) runs on a separate listener and is already excluded from the scan — nothing to redact from the public spec.Note for reviewers
The mutation responses are genuinely inconsistent across the API (
{id}vs{slug}vs{deleted}vs{unlinked}vs{totp_enabled}). They're documented as-is here (a pure docs change). Standardizing them to a common envelope would be a separate code change — happy to propose it if wanted.🤖 Generated with Claude Code
https://claude.ai/code/session_019rao86n5cXpwAyjdBFEshV
The route-level annotations were 100% present, but the committed/served spec (swagger-output.json) was stale and several response schemas had drifted from the controllers. This aligns the docs with actual behavior and regenerates the spec. Served spec was stale (64/67 operations). Regenerating picks up three routes that were added after the last generation: - POST /api/v1/auth/sso/totp - GET /api/v1/admin/discord-bot/config - PUT /api/v1/admin/discord-bot/config plus a stale /auth/logout summary. Response-shape corrections (annotation now matches controller output): - Mutation endpoints do NOT return the generic { message } envelope. Deletes echo { id } / { slug }; toggles return { deleted }, { unlinked }, { totp_enabled }, or { ip, removed }. Documented as-is via new DeletedId/DeletedSlug/DeletedFlag/UnlinkedFlag/TotpState/ UnbanResult components. (The API is intentionally inconsistent here; recorded rather than normalized — see follow-up note.) - POST /account/totp/setup: otpauth_url -> otpauthUrl (TotpSetup) - PUT /admin/site-mode: { mode } -> { site_mode, changed_at, changed_by } - GET /account: full User -> AccountStatus (id/username/role/totp_enabled) - GET /account/identities: add linked_at (LinkedIdentity) - GET /public/status: add status_message (PublicStatus) - POST /auth/sso/totp: user is SafeUser, not full User - GET /dashboard: description/shape corrected (posts+users, no wiki) Schema completeness: - Provider (public discovery): { id, name, icon, loginUrl, priority }, not { id, name, kind } - ProviderConfig: add hasSecret, builtin, health (ProviderHealth) - Post: add excerpt, author_id, published_at - MobileTokenResponse.expiresIn: duration string ("15m"), not integer Config: declare the Admin · Discord Bot tag (was used but undeclared). Auth model and the internal/external boundary were verified correct and left unchanged: cookie + bearer are both accepted on session routes (dual security annotations are accurate), and /internal/* runs on a separate listener already excluded from the scan. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rao86n5cXpwAyjdBFEshV