fix(audit-g5a): small architectural cleanups bundle
CI / lint (push) Failing after 3s
CI / backend-lint-and-test (push) Successful in 17s
CI / frontend-build (push) Successful in 31s
CI / intimp (push) Successful in 3m45s
CI / intapi (push) Successful in 7m46s
CI / intcore (push) Successful in 8m23s

Five small G5 findings from the 2026-06-02 audit. Each is local and
follows an established FC pattern.

- download_service: replace hardcoded ('discord','pixiv') tuple with
  auth_type_for(platform) == 'token'. A 7th token-platform now picks
  up the right credential path without touching this site.

- /api/tags/<source_id>/merge enqueues recompute_centroid.delay after
  merge so the target's centroid reflects its new image set
  immediately. Daily list_drifted catches it within 24h, but eager
  recompute closes the suggestion-quality dip in the meantime.

- backfill_thumbnails added to beat_schedule (daily). The task
  docstring claimed periodic Beat but the entry was never registered,
  so the library got no self-healing thumbnail repair; only the
  manual admin-UI button fired it.

- modal.createAndAdd pushes a kind='fandom' tag into
  tagsStore.fandomCache so FandomPicker sees the new fandom on next
  open. Was: cache-gated load (length===0) skipped refetch, new
  fandom invisible until full page reload.

- cleanup cluster:
  - Drop .webp from cleanup_service.unlink — thumbnailer only writes
    .jpg/.png; the third tuple member was dead code.
  - Drop effective_date from /api/gallery/scroll response — no FE
    consumer reads it. Service still computes the attribute for
    timeline ordering; this just trims the JSON.
  - Rename store.recentMinute → store.recentRuns across the
    systemActivity store + three consumers (SystemActivitySummary,
    QueuesTable, SystemActivityTab). The data is the last 200 runs
    (not actually "last minute"), so the name lied.

NOT in this bundle: the duplicate tag-merge endpoint
(/api/tags vs /api/admin/tags) is harder — has 1 FE caller and 3 tests
on the admin variant; consolidation is its own change.
This commit is contained in:
2026-06-02 16:46:46 -04:00
parent 4bff1d8558
commit 98673d4dca
10 changed files with 53 additions and 15 deletions
@@ -35,7 +35,7 @@ import { computed } from 'vue'
const props = defineProps({
queues: { type: Object, default: null }, // store.queues
workers: { type: Object, default: null }, // store.workers
recentMinute: { type: Array, default: () => [] }, // store.recentMinute
recentRuns: { type: Array, default: () => [] }, // store.recentRuns
compact: { type: Boolean, default: false },
})
@@ -80,7 +80,7 @@ function activeCount(name) {
const recentByQueue = computed(() => {
const out = {}
for (const r of props.recentMinute) {
for (const r of props.recentRuns) {
if (!out[r.queue]) out[r.queue] = { ok: 0, err: 0 }
if (r.status === 'ok') out[r.queue].ok++
else if (r.status === 'error' || r.status === 'timeout') out[r.queue].err++
@@ -24,7 +24,7 @@
<QueuesTable
:queues="store.queues"
:workers="store.workers"
:recent-minute="store.recentMinute"
:recent-runs="store.recentRuns"
compact
/>
</v-card-text>
@@ -47,7 +47,7 @@ function pollOnce() {
if (document.hidden) return
store.loadQueues()
store.loadWorkers()
store.loadRecentMinute()
store.loadRecentRuns()
}
onMounted(() => {
@@ -14,7 +14,7 @@
<QueuesTable
:queues="store.queues"
:workers="store.workers"
:recent-minute="store.recentMinute"
:recent-runs="store.recentRuns"
/>
</v-card-text>
</v-card>
@@ -202,7 +202,7 @@ function pollQueues() {
if (document.hidden) return
store.loadQueues()
store.loadWorkers()
store.loadRecentMinute()
store.loadRecentRuns()
}
function pollFailures() {
if (document.hidden) return