feat(panel): give a delivery its history and its own log lines
test / test (push) Has been cancelled

The delivery page was a list of the fields the send-log table has no
column for, stacked one per line down the reading measure. Six values of
a few characters each — domain, application, queue id, journal id and two
timestamps — came to a page of mostly empty rows, and none of them
answered the question the log raises when a row is opened: what actually
happened to this message.

So the page states that instead. The subject heads it and the sender,
recipient and outcome are the line under it, which puts what the message
was and how it ended on the first line. Below, two columns: what the
journal recorded on the left, as a grid of tiles rather than a stack, and
on the right the two timestamps stated as the steps they stand for —
accepted and queued, then delivered, deferred, bounced, or refused before
queueing. Each step carries its status in the panel's own
ok/warn/error/unknown vocabulary, so a colour means here what it means on
the status page. A message still queued shows the report it is waiting
for as a step that has not happened, rather than dating it with the
moment the row was written.

Under both, at full width, the mail.log lines for the message's queue id.
The queue id was printed on this page as something to go and search the
system log for by hand; logtail.QueueLines does that search. It scans a
bounded tail of the current file — finding one message's lines means
reading rather than seeking — and anchors the match on the character
before the id, since queue ids are hexadecimal runs and a shorter one is
regularly the tail of a longer one. Send-log rows outlive mail.log
(retention ninety days, rotation fourteen files), so a message with
nothing left to show says so; that is the normal end state, not a fault,
and only a log that cannot be read at all is reported as one.

Two cards abreast and a block of raw log lines do not fit the reading
measure, so the page now declares itself wide — the opposite of what it
did when the column width was unified, where it was the page that stayed
prose. The mechanism is unchanged and is why the reversal costs one line:
how wide a page needs to be is the page's own property, not the
navigation entry's.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
mixeme
2026-08-08 10:14:27 +03:00
parent 57d09ce1e2
commit 928d065d13
11 changed files with 702 additions and 59 deletions
+30
View File
@@ -5,6 +5,36 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
## [Unreleased]
### Added
- A **Delivery log** on each delivery's page (`/deliveries/{id}`): the
`mail.log` lines Postfix wrote about that message, oldest first — the
connection to the receiving server, its reply, and the status that reply was
filed as. The queue id was printed on this page as something to go and search
the system log for by hand; the search is done for the operator instead
(`logtail.QueueLines`). The read is a bounded tail of the current log and
matches only lines carrying this message's queue id, anchored so a shorter id
is not found inside a longer one. Send-log rows outlive `mail.log` — retention
is ninety days, rotation keeps fourteen files — so a message with no lines
left says so rather than reporting a failure.
- A **History** block on the same page: the journal's two timestamps stated as
the steps they stand for — accepted and queued, then delivered, deferred,
bounced, or refused before queueing — each with the status it reached in the
panel's own ok/warn/error/unknown badge vocabulary. A message still queued
shows the delivery report it is waiting for as a step that has not happened.
### Changed
- The delivery page is laid out in two columns: what the journal recorded on
the left, what happened to the message on the right, and the delivery log at
full width under both. The facts the page used to stack one per line — domain,
application, queue id, journal id and the two timestamps — are a grid of tiles
instead, since a page of mostly empty rows was what the full-width stack came
to for six short values. The subject heads the page and the sender, recipient
and outcome are the line under it, so what the message was and how it ended
are both on the first line. The page takes the whole column rather than the
reading measure, as the other three monitoring pages already did.
## [0.6.0] - 2026-08-08
### Added