Files
webmail-client/backend/scripts/backfill_delivery_id.py
T
lukasandClaude Opus 4.8 b4e07f11aa collapse cross-account dupes, Lato UI font, mail-list selection & density tuning
Backend:
- Collapse identical cross-account deliveries in a thread: new messages.delivery_id
  (migration 0011) preserves the real Message-ID even when message_id_hdr is
  synthesized (§7.1); get_thread groups by it and reports also_in_account_ids; the
  list count counts distinct deliveries. Backfill script for existing rows.

Frontend:
- Bundle Lato (SIL OFL) as the UI font; unread mail-list rows use Black weight.
- Mail-list selection: hover-avatar checkbox, tri-state "select all", bulk
  Archive/Pin/Delete (Restore/Delete in Archive/Trash/Spam) with a count in the
  reading pane; unread blue dot; "also delivered to" note in the thread.
- Spacing/size tuning: sender-column width, icon gaps, avatar size, bar heights,
  and a round of -1px font sizes across the sidebar, mail list, and reading pane.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U72FZiF1W1pb8XxyWBTREA
2026-07-22 21:49:48 +02:00

36 lines
1.1 KiB
Python

"""One-off: recover delivery_id for messages whose stored Message-ID was
synthesized (§7.1 cross-account duplicate). The real Message-ID is still in the
raw blob, so re-parse it. Non-synthetic rows were already backfilled by migration
0011; here we only touch rows left with delivery_id IS NULL that have a real
Message-ID in their raw bytes."""
import asyncio
from sqlalchemy import select
from app.db import session_scope
from app.indexer import blobstore
from app.indexer.mime import parse_message
from app.models import Message
async def main() -> None:
async with session_scope() as session:
rows = list(
await session.scalars(select(Message).where(Message.delivery_id.is_(None)))
)
fixed = 0
for m in rows:
try:
raw = blobstore.load(m.user_id, m.blob_sha256)
except FileNotFoundError:
continue
parsed = parse_message(raw)
if parsed.message_id:
m.delivery_id = parsed.message_id
fixed += 1
print(f"scanned {len(rows)} null rows, set delivery_id on {fixed}")
asyncio.run(main())