#5507 "Alert emails through the outbox, gathered for 2 minutes" (milestone 501). Replaces the in-memory core/alert_burst.py. - outbox.hold_alert: an alert joins each recipient's held alert email, or opens one due 2 minutes later (System 156 ruling). A Postgres advisory lock keeps two alerts at once from opening two windows for one reader. - email_outbox_events.alert_json (migration 0043) keeps the alert as it fired, so the email written when the window closes says what it said. - write_held writes it then, in the reader's zone: the usual alert email for one alert, the list for several (outbox.alert_words). - after_settle records on each AlertEvent, once every email carrying it has settled: email_sent, or email_error naming each reader it didn't reach and the server's reason. - A held email survives a restart and goes out when its window closes. - A refusal of a message's one recipient no longer repeats the address. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
32 lines
1.8 KiB
HTML
32 lines
1.8 KiB
HTML
{# Several alerts that arrived together (core.outbox.alert_words, #5465), as one
|
||
email's HTML part: alerts = [mail.alert_facts()], oldest first; said = how
|
||
many of each ("3 firing, 1 resolved"); link = the alerts page or "". #}
|
||
{% extends "_layout.html" %}
|
||
{% from "_parts.html" import badge, button with context %}
|
||
{% block title %}{{ alerts|length }} alerts: {{ said }}{% endblock %}
|
||
{% block body %}
|
||
<tr><td style="padding:14px 24px 4px 24px;font:600 20px/1.35 {{ c.font }};color:{{ c.text }};">{{ alerts|length }} alerts changed together: {{ said }}.</td></tr>
|
||
<tr><td style="padding:2px 24px 6px 24px;font:14px/1.5 {{ c.font }};color:{{ c.muted }};">Gathered into one email because they arrived within moments of each other.</td></tr>
|
||
<tr><td style="padding:6px 24px 4px 24px;">
|
||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0" style="border-top:1px solid {{ c.border }};">
|
||
{% for a in alerts %}
|
||
<tr><td style="padding:10px 0;border-bottom:1px solid {{ c.border }};">
|
||
<div>{{ badge(a.tone, a.state) }}</div>
|
||
<div style="padding-top:6px;font:600 15px/1.4 {{ c.font }};color:{{ c.text }};">{{ a.headline }}</div>
|
||
<div style="padding-top:2px;font:13px/1.5 {{ c.font }};color:{{ c.muted }};">{{ a.rule }} · fires when {{ a.condition }} · {{ a.when }}</div>
|
||
{% if a.note %}<div style="padding-top:2px;font:13px/1.5 {{ c.font }};color:{{ c.muted }};">{{ a.note }}</div>{% endif %}
|
||
</td></tr>
|
||
{% endfor %}
|
||
</table>
|
||
</td></tr>
|
||
{% if link %}
|
||
<tr><td style="padding:16px 24px 24px 24px;">{{ button(link, "View in Steward") }}</td></tr>
|
||
{% else %}
|
||
<tr><td style="padding:0 0 12px 0;"></td></tr>
|
||
{% endif %}
|
||
{% endblock %}
|
||
{% block footer %}
|
||
Steward sends this to everyone on its email list when alert rules change state.
|
||
Who gets it is set in Settings › Notifications.
|
||
{% endblock %}
|