Repository navigation
fix(admin): make database VACUUM actually run - #388
Merged
Merged
Conversation
The backend runs VACUUM as the least-privilege app role, which owns no tables. PostgreSQL skipped every table with only a warning, so "Vacuum all tables" and per-table vacuum did nothing while the page reported success. - Grant MAINTAIN on public tables (and future ones) to the app role. - Check MAINTAIN before vacuuming and return 403 instead of a false success; name every public table explicitly for "all". - Expose last_vacuum/last_analyze and show the later of manual and automatic runs, so a manual vacuum is visible on the page. - ADR-262. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018QJtaKQ6oXhXgrVsDF6tTG
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018QJtaKQ6oXhXgrVsDF6tTG
Coverage Report for backend
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||
EraPartner
marked this pull request as ready for review
October 29, 2026 19:53
EraPartner
enabled auto-merge (squash)
October 29, 2026 19:53
Owner
Author
|
Generated by Claude Code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by EraPartner · project thread
Summary
"Vacuum all tables" (and per-table vacuum) on
/admin/dbdid nothing. The backend pool runs as the least-privilege app role, which owns no tables. PostgreSQL then skips each table withWARNING: permission denied to vacuum "<t>", skipping itand the statement succeeds, so the route returned{ vacuumed: "all" }and the page toasted "Vacuum completed". The42501handler never fired. The page also showed onlylast_autovacuum/last_autoanalyze, so even a working manual run would not change what you saw.Reproduced on a local PostgreSQL 16 cluster (owner role + DML-only app role): both
VACUUM ANALYZEandVACUUM ANALYZE tas the app role exit 0 with the skip warning, andlast_vacuumstays NULL. PostgreSQL 18 uses the same warn-and-skip path, gated byMAINTAIN.Changes (ADR-262, option chosen by Tor in the thread):
config/postgres/app-role-grants.sql.tpl:GRANT MAINTAIN ON ALL TABLES IN SCHEMA public+ matching default privilege.roleBootstrap.ts: the per-relation expansion of ALL TABLES grants now takes privileges from the template statement and applies only those valid for the relation kind (matview: SELECT, MAINTAIN; view/foreign table: no MAINTAIN). Existing installs get the grant on next launch.routes/admin.ts: checkshas_table_privilege(relid, 'MAINTAIN')first; any requested table without it →403, nothing runs. "All" names every public table explicitly (a bare VACUUM also tries system catalogs).last_vacuum,last_analyze(contract, openapi, generated types); the page shows the later of manual and automatic.Type of change
fix— bug fixChecklist
lint:backend, frontend lint 0 errors,lint:dead)docs/pages updated (docs/features/database-maintenance.md,docs/api/admin.md,docs/guides/native-macos-runtime.md,docs/reference/api-endpoint-matrix.md)Architecture & data
docs/adr/262-app-role-maintain-for-admin-vacuum.mdDbTableStat; 403 now actually returnedVerification
adminValidation.test.ts10/10 (new: 403 for missing MAINTAIN, explicit table list for "all"); frontendDbMaintenancePage, msw contracts, admin pages 175/175.roleBootstrap.db.test.tsMAINTAIN assertions,aiAuditRowContracts.db.test.tsvacuum →last_vacuumset). Not run locally (PG18 unavailable here).Residual risk & follow-ups
🤖 Generated with Claude Code
https://claude.ai/code/session_018QJtaKQ6oXhXgrVsDF6tTG