homelab-codex-ws/kb/runbooks/gmail-header-backfill-run.md
oskar 0b18d2fc3b feat(kb): SPLIT service+runbook — 10 serwisow -> 20 dokumentow
Wzorzec mechaniczny: sekcje deploy/verify/install/testy wycinane do
kb/runbooks/<serwis>-*.md, reszta zostaje dokumentem type: service.
Wzajemne `links` w obie strony. Tresc sekcji nietknieta — przenoszone
doslownie, dodany wylacznie naglowek H1 nowego runbooka.

kb-query, paperless-worker, planner-agent, ha-diag-agent, ollama-piha,
narty27, home-assistant, ha-mcp, job-gmail-header-backfill, job-mail-body-ingest.

Weryfikacja: dla kazdego pliku multizbior niepustych linii
(main + runbook) == oryginal z HEAD. Zero zgubionych, zero dodanych.

Recon szacowal 13 splitow service+runbook; faktycznie 2-typowych jest 10,
pozostale 5 (paperless, nextcloud, gokapi, fleet-prometheus, deploy-runner)
sa 3-typowe i ida osobno jako splity wielotypowe.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 16:19:30 +02:00

1.6 KiB

okf type visibility status updated links
0.1 runbook private active 2026-07-14
../services/job-gmail-header-backfill.md

gmail-header-backfill — uruchomienie i testy

Usage

# Dry run (default) — parse and count only, no DB writes:
gmail-header-backfill --dsn postgresql://kb:<pw>@localhost:5433/kb --limit 100

# Real run — apply the UPDATE for this slice:
gmail-header-backfill --dsn ... --limit 1000 --offset 0 --apply

# Next slice — offset is stable/deterministic (ORDER BY id), independent of
# how many rows in earlier slices were already backfilled:
gmail-header-backfill --dsn ... --limit 1000 --offset 1000 --apply

DSN can also come from the KB_DSN env var instead of --dsn.

--limit/--offset exist so the full 225 030-row backfill can be run in verifiable partitions instead of one long unattended run (plan §5.3) — start small (--limit 100), check the result in the DB, then widen.

Tests

pip install -e jobs/gmail-header-backfill/
cd jobs/gmail-header-backfill && pytest

Pure unit tests, no DB or filesystem outside tmp_path/synthetic .eml bytes — run() is tested by monkeypatching asyncpg.connect with an in-memory fake connection. Covers: header parsing (multi-address To/Cc, quoted display names with commas, multiple Delivered-To occurrences, RFC 2047 encoded-words including Polish diacritics, malformed encoded-words that must not raise, missing/multiple From, date_raw preserving literal text vs. Date header reformatting), idempotency (rows already carrying a headers entity are skipped and never re-appended), batch flushing, and --limit/--offset query shape.