Diff -- /var/www/vhosts/3dshawn.com/site1/TEMPLATES/alerts.html

O Operator
Diff

/var/www/vhosts/3dshawn.com/site1/TEMPLATES/alerts.html

modified on local at 2026-07-12 00:02:07

Added
+16
lines
Removed
-0
lines
Context
184
unchanged
Blobs
from e8e28508e1fc
to 817bbf649595
Restore this content →
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.
11<div class="page-head">
22 <span class="page-eyebrow"><span class="dot"></span> Notify</span>
33 <h1 class="page-title">Alert rules</h1>
44 <p class="page-subtitle">Route file + schema changes to Slack, Discord, or any HTTP webhook. Rules fire in near-real-time (as the cron dispatcher runs every minute). Every attempt is logged.</p>
55</div>
66
77<div class="dash-grid" style="grid-template-columns:1fr 1fr;margin-bottom:20px">
88
99 <!-- Rule form -->
1010 <div class="module glow-teal">
1111 <div class="module-head"><div class="left">
1212 <div class="module-icon"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg></div>
1313 <div class="module-title">[if:$is_edit]Edit rule #$edit_id[/if][if:!$is_edit]New rule[/if]</div>
1414 <span class="module-subtitle">Combine a matcher (kind + path glob) with a delivery target. Save, then wait for the next capture tick.</span>
1515 </div></div>
1616 <div class="module-body">
1717 <form method="post" action="/alerts.cgi" style="display:flex;flex-direction:column;gap:12px">
1818 <input type="hidden" name="op" value="$form_op">
1919 [if:$is_edit]<input type="hidden" name="alert_rule_id" value="$edit_id">[/if]
2020
2121 <label style="display:flex;flex-direction:column;gap:4px">
2222 <span class="rb-label">Name</span>
2323 <input type="text" name="rule_name" value="$rule_name" placeholder="e.g. Prod nginx config changes" required
2424 style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px;font-family:inherit">
2525 </label>
2626
2727 <div style="display:flex;gap:12px">
2828 <label style="flex:1;display:flex;flex-direction:column;gap:4px">
2929 <span class="rb-label">Match kind</span>
3030 <select name="match_kind" style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px">
3131 <option value="either" $mk_either_sel>Either (file + schema)</option>
3232 <option value="file" $mk_file_sel>File changes only</option>
3333 <option value="schema" $mk_schema_sel>Schema DDL only</option>
3434 </select>
3535 </label>
3636 <label style="flex:1;display:flex;flex-direction:column;gap:4px">
3737 <span class="rb-label">Path glob</span>
3838 <input type="text" name="match_path_glob" value="$match_path_glob" placeholder="e.g. /etc/nginx/** or drift_sense.**"
3939 style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px;font-family:var(--mono);font-size:12px">
4040 </label>
4141 </div>
4242
4343 <div style="display:flex;gap:12px">
4444 <label style="flex:1;display:flex;flex-direction:column;gap:4px">
4545 <span class="rb-label">Status filter <span class="dim" style="text-transform:none;letter-spacing:0;font-size:10.5px">(files only)</span></span>
4646 <input type="text" name="match_status_list" value="$match_status_list" placeholder="added,modified,deleted"
4747 style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px;font-family:var(--mono);font-size:12px">
4848 </label>
4949 <label style="flex:1;display:flex;align-items:center;gap:8px;margin-top:16px">
5050 <input type="checkbox" name="exclude_ts_only" value="1" $exclude_ts_only_checked>
5151 <span style="font-size:12.5px;color:var(--text-dim)">Exclude timestamp-only changes</span>
5252 </label>
5353 </div>
5454
5555 <hr style="border:none;border-top:1px solid var(--border);margin:4px 0">
5656
5757 <div style="display:flex;gap:12px">
5858 <label style="flex:1;display:flex;flex-direction:column;gap:4px">
5959 <span class="rb-label">Delivery</span>
6060 <select name="delivery_kind" style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px">
6161 <option value="generic_webhook" $dk_generic_webhook_sel>Generic HTTP webhook</option>
6262 <option value="slack" $dk_slack_sel>Slack incoming webhook</option>
6363 <option value="discord" $dk_discord_sel>Discord webhook</option>
6464 <option value="email" $dk_email_sel>Email (not yet implemented)</option>
6565 </select>
6666 </label>
6767 <label style="flex:2;display:flex;flex-direction:column;gap:4px">
6868 <span class="rb-label">Webhook URL</span>
6969 <input type="text" name="delivery_url" value="$delivery_url" placeholder="https://hooks.slack.com/..."
7070 style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px;font-family:var(--mono);font-size:11.5px">
7171 </label>
7272 </div>
7373
7474 <div style="display:flex;gap:12px">
7575 <label style="flex:1;display:flex;flex-direction:column;gap:4px">
7676 <span class="rb-label">Rate limit / min</span>
7777 <input type="number" name="rate_limit_per_min" value="$rate_limit_per_min" min="0"
7878 style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px">
7979 </label>
8080 <label style="flex:1;display:flex;flex-direction:column;gap:4px">
8181 <span class="rb-label">Coalesce window (s)</span>
8282 <input type="number" name="coalesce_window_s" value="$coalesce_window_s" min="0"
8383 style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px">
8484 </label>
8585 <label style="flex:1;display:flex;align-items:center;gap:8px;margin-top:16px">
8686 <input type="checkbox" name="is_active" value="1" $is_active_checked>
8787 <span style="font-size:12.5px;color:var(--text-dim)">Rule is active</span>
88 </label>
89 </div>
90
91 <hr style="border:none;border-top:1px solid var(--border);margin:4px 0">
92
93 <div class="rb-label" style="margin-bottom:-4px">Frequency mode <span class="dim" style="text-transform:none;letter-spacing:0;font-size:10.5px">&mdash; when threshold &gt; 0, this rule fires whenever a matching file crosses N changes in M minutes (instead of firing per row)</span></div>
94 <div style="display:flex;gap:12px">
95 <label style="flex:1;display:flex;flex-direction:column;gap:4px">
96 <span class="rb-label">Threshold (changes)</span>
97 <input type="number" name="frequency_threshold" value="$frequency_threshold" min="0"
98 style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px">
99 </label>
100 <label style="flex:1;display:flex;flex-direction:column;gap:4px">
101 <span class="rb-label">Window (minutes)</span>
102 <input type="number" name="frequency_window_min" value="$frequency_window_min" min="1"
103 style="background:var(--bg-1);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:8px 12px">
88104 </label>
89105 </div>
90106
91107 <div style="display:flex;gap:8px;justify-content:flex-end;margin-top:8px">
92108 [if:$is_edit]<a href="/alerts.cgi" class="tr-chip">Cancel</a>[/if]
93109 <button type="submit" class="tr-chip is-active" style="border:none">[if:$is_edit]Save changes[/if][if:!$is_edit]Create rule[/if]</button>
94110 </div>
95111 </form>
96112 </div>
97113 </div>
98114
99115 <!-- Delivery history -->
100116 <div class="module glow-emerald">
101117 <div class="module-head"><div class="left">
102118 <div class="module-icon"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg></div>
103119 <div class="module-title">Recent deliveries</div>
104120 <span class="module-subtitle">Last 30 fire attempts across every rule. Audit trail for compliance / debugging.</span>
105121 </div></div>
106122 <div class="module-body tight" style="max-height:520px;overflow:auto">
107123 [if:$has_deliveries]
108124 <table class="tbl">
109125 <thead><tr>
110126 <th style="width:80px">Status</th>
111127 <th>Rule / target</th>
112128 <th style="width:120px">Result</th>
113129 <th style="width:150px">When</th>
114130 </tr></thead>
115131 <tbody>
116132 [loop:@deliveries]
117133 <tr>
118134 <td><span class="pill $delivery_pill">$delivery_status</span></td>
119135 <td class="mono" style="font-size:11.5px"><a href="$source_url" style="color:var(--accent-hi);text-decoration:none">$summary_h</a></td>
120136 <td class="dim mono" style="font-size:11px">$err_h</td>
121137 <td class="mono dim"><span class="ts" data-ts="$fired_epoch" data-fmt="relative">$fired_at</span></td>
122138 </tr>
123139 [/loop]
124140 </tbody>
125141 </table>
126142 [/if]
127143 [if:!$has_deliveries]
128144 <div style="padding:36px 14px;text-align:center;color:var(--text-dim);font-size:13.5px">
129145 No deliveries yet. Create a rule and wait for a change to fire it.
130146 </div>
131147 [/if]
132148 </div>
133149 </div>
134150</div>
135151
136152<!-- Rule list -->
137153<div class="module glow-sky">
138154 <div class="module-head"><div class="left">
139155 <div class="module-icon"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></svg></div>
140156 <div class="module-title">Rules</div>
141157 <span class="module-subtitle">Click a row to edit. Deactivating a rule stops it firing but keeps its history.</span>
142158 </div></div>
143159 <div class="module-body tight">
144160 [if:$has_rules]
145161 <table class="tbl">
146162 <thead><tr>
147163 <th style="width:80px">Status</th>
148164 <th>Name</th>
149165 <th>Matches</th>
150166 <th style="width:110px">Delivery</th>
151167 <th>Target</th>
152168 <th style="width:70px">Fires</th>
153169 <th style="width:150px">Last fired</th>
154170 <th style="width:60px">Actions</th>
155171 </tr></thead>
156172 <tbody>
157173 [loop:@rules]
158174 <tr>
159175 <td><span class="pill $status_pill">$status_label</span></td>
160176 <td><a href="$edit_url" style="color:var(--accent-hi);text-decoration:none">$rule_name</a></td>
161177 <td class="mono dim" style="font-size:11.5px">$match_kind &middot; $match_glob_h</td>
162178 <td><span class="pill $kind_pill">$delivery_kind</span></td>
163179 <td class="mono dim" style="font-size:11px">$url_h</td>
164180 <td class="mono">$fire_count</td>
165181 <td class="mono dim"><span class="ts" data-ts="$last_fired_epoch" data-fmt="relative">$last_fired_h</span></td>
166182 <td>
167183 <form method="post" action="/alerts.cgi" style="display:inline">
168184 <input type="hidden" name="op" value="toggle">
169185 <input type="hidden" name="alert_rule_id" value="$alert_rule_id">
170186 <button type="submit" class="tr-chip" title="Toggle active" style="padding:3px 8px;font-size:11px">⏻</button>
171187 </form>
172188 </td>
173189 </tr>
174190 [/loop]
175191 </tbody>
176192 </table>
177193 [/if]
178194 [if:!$has_rules]
179195 <div style="padding:36px 14px;text-align:center;color:var(--text-dim);font-size:13.5px">
180196 No rules yet. Use the form above to create your first.
181197 </div>
182198 [/if]
183199 </div>
184200</div>