CI / lint (push) Successful in 2s
CI / extension-version (push) Successful in 3s
Build images / sign-extension (push) Successful in 3s
Build images / build-agent (push) Successful in 6s
CI / frontend-build (push) Successful in 26s
CI / backend-lint-and-test (push) Successful in 33s
Build images / build-web (push) Successful in 59s
Build images / smoke-web (push) Skipped
Build images / build-ml (push) Successful in 1m55s
Build images / promote (push) Skipped
CI / integration (push) Successful in 2m22s
Milestone #421 built a sweep that compared each image's `artist_id` to the name of the directory holding its file, and called every mismatch a misplaced image. It reported 33,789 of 63,605 as wrongly filed. That number described the comparison, not the library. What it actually was: 32,475 (97.1%) one artist's own folder, spelled differently — Telepurte/ vs telepurte/. Same artist, same art. 657 ( 2.0%) loose at the images root 328 ( 1.0%) in a folder named after a different artist And the 1% did not mean what the tool assumed either. `ImageProvenance` records the post and source every file was downloaded from — the authoritative answer, which the tool never consulted. Querying it for all 328: 144 provenance agrees with the record (move would be right) 87 provenance agrees with the FOLDER (the record is wrong; move wrong) 53 provenance names SEVERAL artists (no single correct folder) 41 no provenance at all 3 agrees with neither So the sweep would have misfiled or arbitrarily picked for ~41% of the only set it was really needed for. The system already knew where each file came from; the tool inferred it from a column and a directory name instead. Operator, 2026-09-21: *"the current system consistently records where items are and where they came from this is just complicating something works and doesn't need fixing."* Correct on both counts. Removed: the service, the tasks, the model and migration 0099's table, the /api/cleanup/layout and /placement/* endpoints, the Maintenance card and its store actions, and the tests. 0100 drops the table (rule #22 — no legacy). KEPT deliberately, per the operator: - `utils.paths.canonical_subdir` — new filesystem imports derive their directory from the artist's slug, matching what the downloader always did. Not part of this tool; removing it would be churn that fixes nothing. - The 327 files run 1 moved (InsoUwu/ -> insouwu/). Same artist either way, and the gallery renders them correctly. - Everything from #4223 (three-gate dedup, 256-bit pHash) and #4234 (backup credential exclusion). Those fixed problems that were actually reported. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LVjrnpQjRgHdvq95rASoiR
81 lines
2.5 KiB
JavaScript
81 lines
2.5 KiB
JavaScript
import { defineStore } from 'pinia'
|
|
import { ref } from 'vue'
|
|
import { useApi } from '../composables/useApi.js'
|
|
|
|
export const useCleanupStore = defineStore('cleanup', () => {
|
|
const api = useApi()
|
|
|
|
// Defaults sourced from ImportSettings on mount. Cards pre-fill from
|
|
// these so the common case ("apply current import filters
|
|
// retroactively") is one click; operator can override per-audit.
|
|
const defaults = ref({
|
|
min_width: 0,
|
|
min_height: 0,
|
|
transparency_threshold: 0.9,
|
|
single_color_threshold: 0.95,
|
|
single_color_tolerance: 30,
|
|
})
|
|
|
|
const recentRuns = ref([])
|
|
|
|
async function loadDefaults() {
|
|
const s = await api.get('/api/settings/import')
|
|
defaults.value = {
|
|
min_width: s.min_width ?? 0,
|
|
min_height: s.min_height ?? 0,
|
|
transparency_threshold: s.transparency_threshold ?? 0.9,
|
|
single_color_threshold: s.single_color_threshold ?? 0.95,
|
|
single_color_tolerance: s.single_color_tolerance ?? 30,
|
|
}
|
|
}
|
|
|
|
async function previewMinDim(min_width, min_height) {
|
|
return await api.post('/api/cleanup/min-dimension/preview', {
|
|
body: { min_width, min_height },
|
|
})
|
|
}
|
|
|
|
async function deleteMinDim(min_width, min_height, confirm) {
|
|
return await api.post('/api/cleanup/min-dimension/delete', {
|
|
body: { min_width, min_height, confirm },
|
|
})
|
|
}
|
|
|
|
async function startAudit(rule, params) {
|
|
return await api.post('/api/cleanup/audit', { body: { rule, params } })
|
|
}
|
|
|
|
async function getAudit(id) {
|
|
return await api.get(`/api/cleanup/audit/${id}`)
|
|
}
|
|
|
|
async function loadHistory(limit = 20) {
|
|
const body = await api.get(`/api/cleanup/audit?limit=${limit}`)
|
|
recentRuns.value = body.runs
|
|
return body.runs
|
|
}
|
|
|
|
// The most recent audit run for a given rule, or null. Cards call this on
|
|
// mount to reconnect to a scan that's still running (or to show the last
|
|
// completed result) after the user navigates away and back.
|
|
async function latestAuditForRule(rule) {
|
|
const body = await api.get('/api/cleanup/audit', { params: { rule, limit: 1 } })
|
|
return (body.runs && body.runs[0]) || null
|
|
}
|
|
|
|
async function applyAudit(id, confirm) {
|
|
return await api.post(`/api/cleanup/audit/${id}/apply`, { body: { confirm } })
|
|
}
|
|
|
|
async function cancelAudit(id) {
|
|
return await api.post(`/api/cleanup/audit/${id}/cancel`)
|
|
}
|
|
|
|
return {
|
|
defaults, recentRuns,
|
|
loadDefaults,
|
|
previewMinDim, deleteMinDim,
|
|
startAudit, getAudit, loadHistory, latestAuditForRule, applyAudit, cancelAudit,
|
|
}
|
|
})
|