# Dashboard and maintenance

**For administrators.** The admin Dashboard — an at-a-glance answer to "what's in Kartotek?" and "what needs attention?" — and the shared design every corpus-wide repair/enrichment task on the site follows. See [Administrator quick start](/_docs/admin-quickstart) for where this sits among the rest of Admin.

## Dashboard

Logging in lands on the Dashboard, organized into six groups. Every number is itself a link into the relevant part of Admin, opening pre-filtered where that's meaningful (for example, the PrePub Posts tile opens the Posts list already filtered to PrePub). If one group's own data can't be loaded for any reason, that group alone shows as unavailable — the rest of the Dashboard still renders normally.

- **Needs attention** — PrePub Posts; the same translation-issue tiles the Translations dashboard itself shows (Failed, Stale, Missing per language, Awaiting review per language — see [Languages and translations](/_docs/translations), each its own separate tile here too, hidden individually when its count is zero); backup issues (a run that failed, or one overdue — see [Backup and disaster recovery](/_docs/backups)); unresolved import issues; and **Rotten links** (distinct current Links whose live destination is currently Missing, with a separate note for how many of those have no preserved copy at all — see [Links and web preservation](/_docs/links)). When every "Needs attention" count is genuinely zero, the whole group collapses into a single **No current issues** note instead of a wall of zeroes.
- **Backfill health** — how many of the corpus's required, ongoing operations (translations, archival, thumbnails, link checks, Dropbox cleanup) have never completed successfully, and the oldest last-successful-completion among the rest, with the most urgent named underneath. Optional or one-time operations (Visual classification, the one-off migration tools, GUI placeholder audit) don't count toward either number just for never having completed — that's expected for them — but any of them currently needing attention still turns the tile red and is named at the top of the list. Red whenever a required operation has never completed, the oldest such completion is more than 14 days old (exactly 14 days doesn't count as overdue), or an optional/one-time operation is currently needing attention; a neutral "No backfill jobs configured" state only if nothing is registered at all — this group is otherwise always shown, healthy or not. Every tile and job name links down to Backfill operations. A job that's been retired from the codebase stops counting here without losing its past history.
- **Content** — Published Posts, Hidden Posts, Categories, Tags, Content Elements, Versions, and Posts with HTML content (see [Text](/_docs/content-text) for what "HTML content" means) — always shown, including at zero. These counts are installation-wide rather than following the domain selector below, since Posts/Categories/Tags aren't owned by any one Domain in the first place — see [Domains, UIDs and addresses](/_docs/addressing). Categories, Content Elements, and Versions are plain counts for now; there's no cross-Post browsing view for any of the three yet, so those three tiles aren't clickable.
- **Activity and data** — visits (today and over the last 30 days; a domain selector at the top of the page scopes this count to one Domain, "All domains," or unconfigured traffic — see [Privacy and analytics](/_docs/privacy)), and the five most recently changed Posts.
- **Operations** — the last successful backup and how long ago that was, current Translation usage, and the most recent JSON import's status. Like Content, these are installation-wide values, not scoped to one Domain.
- **Link evidence** — total Links; how many are Queued/Partial/Complete/Failed overall; coverage counts for each evidence type (live status, PDF, WARC, Wayback, other Web Archive providers); the most recent successful verification across the whole corpus; and, only when nonzero, actionable provider errors and local artifacts awaiting review. Every tile opens the Link evidence matrix pre-filtered — see [Links and web preservation](/_docs/links).

The bar at the top of every admin page shows **Deployed** (when the running version of the site was deployed) and **Updated** — the most recent durable change to the site's database, of any kind: publishing or editing a Post, a Category/Tag/Domain change, a translation landing, a media or link operation, a settings change, or a backfill writing results. Visit-analytics collection deliberately never moves this timestamp — **Updated** answers "when did the site's actual data last change," not "when was it last visited."

## Backfill operations

Below the six groups, the Dashboard carries the site's one **Backfill operations** section — every corpus-wide repair and enrichment task, each as a compact row in one shared design, rather than scattered controls on individual feature pages (those pages link back here instead). Each row shows the operation's name and purpose, what it's actually scoped to right now (a short description of what's covered, plus either **Discovering — N found so far** while that scope is still being assembled, or **Scope: N {items}** once it's fixed and known in full — a handful of one-time audits/migrations are the only operations that ever reach a fixed scope; every ongoing operation stays "Discovering" indefinitely, since its own eligible set is continuously re-evaluated rather than counted once and closed), its current state, **Latest execution** and **Last fully satisfied** (two separate, explicit dates — a failed, cancelled, paused, or dry-run attempt never overwrites an earlier real success; "Never" means exactly that, not merely "not shown in this browser session"), a real n-of-total percentage for the few one-time bounded operations that have one (Dropbox backup cleanup's own scan), or current-state counts (outstanding/completed/skipped/failed/cancelled) for every ongoing operation, since an ongoing operation's own scope never has a fixed total a percentage could honestly represent, and the actions its state allows — Start, Pause, Resume, and (where the operation supports it) Retry failed or a dry run. A nonzero completed/skipped/failed/cancelled count is itself clickable: it expands into why, grouped by reason, and the actual items behind any one reason — no need to leave the Dashboard to see what's actually wrong. An operation that can't run right now says why, right on its row. A **Details** toggle expands whatever further per-operation specifics that row has (a Scope choice, an error summary) without making the summary rows any less dense. Starting anything with real cost (external translation-provider calls, capture work, deletion) asks for confirmation first.

![The Backfill operations section, sorted by name, with each row's own current state](/_docs/images/backfill-operations-normal-desktop-linux.png)

Rows are listed flat, sorted alphabetically by name — never grouped or reordered by an operation's own current state. An earlier design grouped rows by state, moving one into a separate "Needs attention" section the moment it needed attention and back out once resolved; each move unmounted and remounted the row, which surfaced in production as rows visibly jumping position, sometimes repeatedly, while nothing an admin was doing had changed. A row's own state is still shown on the row itself (see "state" below) — it simply never decides where in the page that row lives, which is what makes its position stable across every refresh.

![An operation that needs attention, expanded to show the reasons behind its counts](/_docs/images/backfill-operations-needs-attention-desktop-linux.png)

A **"What do these states mean?"** disclosure above the operations list gives the definition of every state a count can be in:

- **Pending** — discovered and eligible, not yet scheduled for processing.
- **Queued** — scheduled and waiting for a worker to pick it up.
- **Running** — actively being processed right now.
- **Waiting to retry** — a previous attempt failed transiently; waiting out a bounded backoff before trying again.
- **Completed** — the required result was produced or verified — including "already satisfied, nothing to do," which is a real completed outcome, not a skip.
- **Skipped** — deliberately excluded for a recorded reason (wrong type, no longer eligible, a manual override in place) — never a generic stand-in for "unchanged" or "failed."
- **Failed** — a genuine processing attempt errored and needs attention or a retry.
- **Cancelled** — excluded because the run itself was explicitly cancelled — not an error, and never retried automatically.

An operation's own current **state** is a separate concept from an item's state above — it describes the run as a whole: Idle, Discovering, Queued, Running, Pausing, Paused, Finished, **Finished with exclusions** (a run that completed but has at least one Skipped item — worth a look, not a failure), **Needs attention** (an unresolved Failed item remains), Cancelled. Two operations — Media probes and Video thumbnails — show **Legacy result — item accounting unavailable** instead of "Finished with exclusions" for the same underlying outcome: these were deliberately never migrated onto the per-item tracking every other operation's clickable counts rely on, so there's no per-item breakdown a click here could ever reveal.

**Every resumable operation keeps its checkpoint on the server, in the database** — pausing, reloading the page, or even a deploy landing mid-run never loses progress; Resume continues from exactly where the run left off. Running any of them repeatedly is always safe — an already-complete item is a fast no-op, never duplicated work. **Every operation's execution history — including the five that used to report only from browser memory (GUI translation fill, GUI placeholder audit, Image EXIF metadata, Media probes, Video thumbnails) — is now recorded durably in the database**, keyed by a stable identity independent of the row's own display name, so Latest execution/Last fully satisfied survive a page reload, an application restart, or a Render redeploy just as reliably as an operation's own resumable checkpoint does. A dry run is recorded (so its own row still shows a latest attempt) but never counts as a successful completion. The operations:

- **Post & Content translations**, **Tag translations**, **GUI translation fill**, and **GUI placeholder audit** — see [Languages and translations](/_docs/translations)'s "Backfill relationship."
- **Link health checks** and **Link evidence discovery** — see [Links and web preservation](/_docs/links).
- **Post WARC & Wayback archival** — generates any missing Post WARC capture and submits every associated-Domain URL to the Wayback Machine, described alongside the rest of archival in [Links and web preservation](/_docs/links).
- **Image EXIF metadata**, **Media probes**, and **Video thumbnails** — idempotent catch-up passes over already-ingested Post Media (the two media passes offer a dry run that reports scope without writing anything) — see [Media and the Media Archive](/_docs/media).
- **Missing thumbnails** and **Failed EXIF extraction** — the two backfills behind Post Media's own health metrics, with dry run/apply. Missing thumbnails targets only currently-missing-thumbnail Post Media Video via its canonical thumbnail pipeline; Failed EXIF extraction re-attempts only Post Media items where an extraction attempt genuinely errored, never a successfully-scanned-no-data or not-yet-attempted item, and also reconciles Video/Audio technical metadata. Neither covers Archive Media — its thumbnails and metadata arrive already prepared through the media import (see [Import, export and external publishing](/_docs/json-import)). See [Media and the Media Archive](/_docs/media)'s "Media health and storage" section.
- **Visual classification** — analyses Post Media Images for indoor/outdoor and potentially-identifiable-people signals, entirely locally. Defaults to not-yet-attempted/failed/stale Images; an optional, separately-confirmed setting re-analyses everything, including already-classified Images. Offers dry run/apply, and — because a full-corpus pass can run a while — can also be paused and resumed, or cancelled outright, without losing already-completed work. Archive Media's classification arrives already set through the media import instead. See [Media and the Media Archive](/_docs/media)'s "Visual classification" section.
- **Dropbox backup cleanup** — scans the Dropbox backup destination for temp/journal debris and superseded zero-byte artifacts; actually deleting anything requires a fresh scan's own confirmation token plus an explicit confirmation, and is never automatic — see [Backup and disaster recovery](/_docs/backups).

Archive Media has no operations of its own on this list: Kartotek doesn't scan, download, process, or automatically categorize it — every record, its metadata, its classification, and its thumbnail arrive already prepared through the media import (see [Import, export and external publishing](/_docs/json-import)'s "Media import (Archive Media)" and [Media and the Media Archive](/_docs/media)'s "Archive Media" section).

### About the screenshots on this page

The two screenshots above are not hand-captured. They are the same image files the automated visual-regression suite compares every build against, served directly rather than copied. That means they cannot quietly go out of date: if the Dashboard's appearance changes, that suite fails until the image is regenerated, and this page then shows the new one automatically.

## Database Browser

The sidebar's **Admin** tree's **Database** section is a read-only view over the site's underlying SQLite tables and rows — Posts, Categories, Content Elements, Versions, everything, including Hidden content. It's strictly a viewer: there's no way to edit or delete an individual row from here — real changes still go through the normal Post/Category admin flows.

## Storage

`/_admin/storage` (Backup sidebar section → **Storage**) shows live-measured disk consumption for every category Kartotek writes to disk — the live database, uploaded media originals, regenerable caches (Archive Media thumbnails, resized image/video variants), working/scratch space, backup exports, archived Link/Post captures, and Post PDF/JSON exports — each with a plain-language explanation of what it holds. Figures are cached and refreshed automatically in the background; **Refresh now** forces an immediate re-measurement.

Some categories offer a **Clear** action — regenerable caches, working/scratch directories, and confirmed-stale backup-export debris. Clicking it first shows exactly what would be removed (an estimated size and a sample of filenames) before anything is deleted, and requires an explicit acknowledgment. Nothing that holds an original, irreplaceable file (the live database, uploaded media, archived Link/Post captures) is ever offered a Clear action here.

## Troubleshooting

- **A Post isn't showing up on its Category's page.** Check its Stage (must be Published) and whether its current Version is marked Hidden — see [Posts and publishing](/_docs/posts).
- **A visitor reports the top navigation looks wrong, or the root address shows unexpected content.** Check the current hostname's Domain configuration (or, if none matches, the Primary Domain) — see [Domains, UIDs and addresses](/_docs/addressing) — a deleted or unpublished landing target/nav entry falls back automatically, but that Domain's own warnings panel will say so.
- **An import is stuck.** Open it under Imports (see [Import, export and external publishing](/_docs/json-import)) — a staged (not finalized) job means at least one media item needs attention; fix, retry, or finalize with it excluded.
- **Analytics numbers look wrong or empty.** Confirm every required setting is filled in under **Admin → Settings** (or its fallback environment variable) — the Analytics page states exactly which are missing — and that the change you're checking happened after analytics was actually enabled; nothing is backfilled retroactively. See [Privacy and analytics](/_docs/privacy).
