-- Daily mail-reputation snapshots parsed from the postfix logs. -- -- WHY: Sender reputation lives at the RECEIVING operator (Microsoft 365, Google, -- Yahoo, ...), not at the recipient domain. The provider portals (SNDS, Postmaster, -- Yahoo CFL) show this but each needs a login and lags 24-48h. Our own postfix logs -- already contain the ground truth in real time: every send to a Microsoft tenant -- returns 250 (accepted) / 451 4.7.500 (throttled, "server busy") / 5xx (rejected), -- and the reject text tells us WHY (reputation 5.7.1, recipient unknown 5.1.1, etc.). -- A 2026-06-19 audit found 80% of Microsoft sends were getting 451 4.7.500 throttles -- on the warming IPs -- exactly the signal we need to watch ease as reputation builds. -- -- This table stores ONE row per (log_date, sending_ip, receiver_operator, outcome -- class) so we can chart accepted% / deferred% / reject-reason mix per operator over -- time without re-parsing logs (which rotate fast). Populated by -- scripts/mail_reputation_monitor.py (idempotent upsert per day). CREATE TABLE IF NOT EXISTS mail_reputation_daily ( id BIGSERIAL PRIMARY KEY, log_date DATE NOT NULL, -- the calendar day of the log lines (server TZ) sending_ip TEXT NOT NULL, -- our egress IP (207.174.124.94 / .107 / ...) receiver TEXT NOT NULL, -- normalized receiving operator: microsoft|google|yahoo|proofpoint|other outcome TEXT NOT NULL, -- accepted|throttled|reject_reputation|reject_recipient|reject_content|reject_other|deferred_other reason_code TEXT, -- representative enhanced status / code (e.g. 4.7.500, 5.7.1, 5.1.1) msg_count INTEGER NOT NULL DEFAULT 0, sample_text TEXT, -- one representative raw response, for debugging created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), UNIQUE (log_date, sending_ip, receiver, outcome, reason_code) ); CREATE INDEX IF NOT EXISTS idx_mail_rep_daily_date ON mail_reputation_daily (log_date); CREATE INDEX IF NOT EXISTS idx_mail_rep_daily_receiver ON mail_reputation_daily (receiver, log_date); COMMENT ON TABLE mail_reputation_daily IS 'Daily per-IP per-receiving-operator mail delivery outcome counts parsed from postfix logs (SNDS-equivalent reputation trend, no provider login needed). Populated by scripts/mail_reputation_monitor.py.'; COMMENT ON COLUMN mail_reputation_daily.receiver IS 'Normalized receiving operator: microsoft|google|yahoo|proofpoint|mimecast|other'; COMMENT ON COLUMN mail_reputation_daily.outcome IS 'accepted|throttled|reject_reputation|reject_recipient|reject_content|reject_other|deferred_other';