mirror of
https://github.com/thegeneralist01/archivr
synced 2026-07-21 18:55:36 +02:00
feat: add orphan blob cleanup to Settings > Storage tab (#18)
- database.rs: add has_active_capture_jobs(), list_orphaned_blob_rows(),
all_referenced_file_relpaths(), delete_orphaned_blob_rows()
- routes.rs: GET/DELETE /api/archives/:id/blob-cleanup (ROLE_ADMIN)
- GET returns {orphaned_blob_rows, deletable_files, total_bytes}
- DELETE has two active-capture guards (before and after disk walk)
to prevent deleting files mid-capture; walks raw/ and raw_tweets/
- Referenced set = entry_artifacts.relpath ∪ live blobs' raw_relpath,
so a file is never deleted if any artifact still points at its path
- api.js: scanOrphanBlobs(), deleteOrphanBlobs()
- App.jsx: pass archiveId to SettingsView; add 'storage' to SETTINGS_TABS
so /settings/storage survives refresh/back navigation
- SettingsView.jsx: new Storage tab (admin-only) with idle→scanning→
scanned→deleting→done/error state machine; shows file/record counts
and human-readable byte sizes before a btn-danger confirm
Tests (14 new, 248 total passing):
- database.rs: has_active_capture_jobs for pending/running/completed,
list_orphaned_blob_rows, all_referenced_file_relpaths edge cases,
delete_orphaned_blob_rows preserves referenced rows
- routes.rs: auth (401), active-capture 409 on GET and DELETE,
end-to-end delete preserving referenced file and removing orphan
blob file + extra disk-only file
This commit is contained in:
parent
b8e496457f
commit
339076e6a2
8 changed files with 739 additions and 48 deletions
|
|
@ -18,7 +18,7 @@ import ToastStack from './components/ToastStack'
|
|||
export const AuthContext = createContext(null);
|
||||
|
||||
const VIEWS = ['archive','tags','collections','runs','admin','settings']
|
||||
const SETTINGS_TABS = ['profile','tokens','instance']
|
||||
const SETTINGS_TABS = ['profile','tokens','instance','storage']
|
||||
|
||||
function parseLocation() {
|
||||
const parts = window.location.pathname.split('/').filter(Boolean)
|
||||
|
|
@ -326,7 +326,7 @@ export default function App() {
|
|||
<CollectionsView archiveId={archiveId} />
|
||||
)}
|
||||
{view === 'settings' && (
|
||||
<SettingsView tab={settingsTab} onTabChange={setSettingsTab} />
|
||||
<SettingsView tab={settingsTab} onTabChange={setSettingsTab} archiveId={archiveId} />
|
||||
)}
|
||||
</div>
|
||||
<ContextRail
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue