feat: add job maintenance dashboard and automated stale job expiration system
This commit is contained in:
@@ -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 & 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 (≤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 (>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 (>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 }}`
|
||||
Reference in New Issue
Block a user