feat: add job maintenance dashboard and automated stale job expiration system

This commit is contained in:
2026-08-22 01:51:43 -07:00
parent 367929e7d0
commit 7ec91f384f
12 changed files with 633 additions and 56 deletions
+91
View File
@@ -0,0 +1,91 @@
package ui
const preferencesTabHTML = `{{ define "preferencesTab" }}
<div class="space-y-6 max-w-4xl">
<div>
<h2 class="text-base font-bold text-white flex items-center gap-2">
<span>⚙️</span> System Setup &amp; Maintenance
</h2>
<p class="text-xs text-slate-400 mt-0.5">Monitor database health and purge stale job postings not seen on target career sites</p>
</div>
<!-- Maintenance Result Alert Banner -->
<div id="maintenance-alert" class="hidden p-4 rounded-xl border transition-all"></div>
<!-- Statistics Overview Grid -->
<div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-3">
<div class="p-3.5 rounded-xl bg-slate-900/70 border border-slate-800">
<span class="text-[10px] uppercase font-bold text-slate-400 block tracking-wider">Total Ingested</span>
<span class="text-xl font-extrabold text-white mt-1 block">{{ .MaintenanceStats.total_jobs }}</span>
</div>
<div class="p-3.5 rounded-xl bg-slate-900/70 border border-slate-800">
<span class="text-[10px] uppercase font-bold text-emerald-400 block tracking-wider">Active (&le;7d)</span>
<span class="text-xl font-extrabold text-emerald-400 mt-1 block">{{ .MaintenanceStats.active_7d }}</span>
</div>
<div class="p-3.5 rounded-xl bg-slate-900/70 border border-slate-800">
<span class="text-[10px] uppercase font-bold text-amber-400 block tracking-wider">Stale (&gt;7d)</span>
<span class="text-xl font-extrabold text-amber-400 mt-1 block">{{ .MaintenanceStats.stale_7d }}</span>
</div>
<div class="p-3.5 rounded-xl bg-slate-900/70 border border-slate-800">
<span class="text-[10px] uppercase font-bold text-rose-400 block tracking-wider">Stale (&gt;30d)</span>
<span class="text-xl font-extrabold text-rose-400 mt-1 block">{{ .MaintenanceStats.stale_30d }}</span>
</div>
<div class="p-3.5 rounded-xl bg-slate-900/70 border border-slate-800">
<span class="text-[10px] uppercase font-bold text-slate-400 block tracking-wider">Expired / Closed</span>
<span class="text-xl font-extrabold text-slate-300 mt-1 block">{{ .MaintenanceStats.expired_count }}</span>
</div>
<div class="p-3.5 rounded-xl bg-slate-900/70 border border-slate-800">
<span class="text-[10px] uppercase font-bold text-violet-400 block tracking-wider">In Pipeline</span>
<span class="text-xl font-extrabold text-violet-300 mt-1 block">{{ .MaintenanceStats.in_pipeline }}</span>
</div>
</div>
<!-- Maintenance Tool: Purge Stale Postings (Worker Queue Driven) -->
<div class="p-6 rounded-xl bg-slate-900/60 border border-slate-800 space-y-5">
<div class="flex items-start justify-between">
<div class="flex items-center gap-3">
<span class="w-9 h-9 rounded-xl bg-amber-500/10 border border-amber-500/30 flex items-center justify-center text-lg">⚠️</span>
<div>
<h3 class="text-sm font-bold text-white">Purge Stale Postings (Mark Expired)</h3>
<p class="text-xs text-slate-400 mt-0.5">Enqueues worker queue tasks to mark job postings as <strong class="text-amber-300 font-semibold">Expired</strong> if they have not been discovered on target career boards for X days.</p>
</div>
</div>
</div>
<div class="pt-4 border-t border-slate-800/80 grid grid-cols-1 sm:grid-cols-3 gap-4 items-end">
<div>
<label for="expire-days" class="block text-xs font-semibold text-slate-300 mb-1.5">Not updated in:</label>
<select id="expire-days" class="w-full px-3 py-2 text-xs rounded-lg bg-slate-800 border border-slate-700 text-white focus:outline-none focus:border-indigo-500">
<option value="7">7+ days</option>
<option value="14" selected>14+ days</option>
<option value="30">30+ days</option>
<option value="60">60+ days</option>
</select>
</div>
<div class="flex items-center gap-2 pb-2">
<input type="checkbox" id="expire-protect-pipeline" checked class="rounded bg-slate-800 border-slate-700 text-indigo-600 focus:ring-0">
<label for="expire-protect-pipeline" class="text-xs text-slate-300">Protect active applications</label>
</div>
<div>
<button type="button"
onclick="runMaintenanceAction('/api/maintenance/stale-expire', 'expire-days', 'expire-protect-pipeline', this, '⚠️ Queue Expire Tasks')"
class="w-full py-2 bg-amber-600 hover:bg-amber-500 text-xs font-semibold text-white rounded-lg shadow-md transition-all active:scale-95">
⚠️ Queue Expire Tasks
</button>
</div>
</div>
</div>
<!-- Explanation Card -->
<div class="p-5 rounded-xl bg-slate-900/40 border border-slate-800/80 text-xs text-slate-400 space-y-2">
<h4 class="font-bold text-slate-200 uppercase tracking-wider text-[11px]">💡 How Job Verification Works</h4>
<p>
Every time <strong class="text-indigo-300">🔍 Discover</strong> runs, Hireme searches live listings directly on career sites (Google, Apple, Meta).
When an existing job appears in search results, its <strong class="text-emerald-400">Last Updated</strong> timestamp is refreshed.
If a role closes or is removed from search results, its Last Updated timestamp remains unchanged, allowing you to safely purge expired postings using the tool above.
</p>
</div>
</div>
{{ end }}`