File size: 4,003 Bytes
d618a6e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c55abce
d618a6e
 
c55abce
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d618a6e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
"""Render a sample Daily Brief email for client sign-off.

Runs the production `_build_brief_html()` with realistic synthetic data
covering all three section types: ambiguous routings, MTRs missing heat
codes, and processing errors.

Usage:  python -m scripts.preview_brief [output_path]

If output_path is omitted, writes to ./daily_brief_preview.html relative
to the repo root.
"""
from __future__ import annotations

import json
import sys
from pathlib import Path

# Make repo root importable when run via `python scripts/preview_brief.py`
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))

from app.lib.utils.brief_html import build_brief_html


# Synthetic items modeled on real `daily_brief` rows. Confidence scores are
# JSON-encoded strings because that's how they're stored in SQLite.
SAMPLE_ITEMS: list[dict] = [
    # Two ambiguous routings — multiple doc types crossed the threshold.
    {
        "id": 1,
        "sender_email": "ap@westlake.com",
        "subject": "RCM - Westlake PO 4502953154 and quote",
        "attachment_filename": "Westlake_PO_4502953154.pdf",
        "reason": "ambiguous",
        "confidence_scores": json.dumps({
            "po": 0.81, "invoice": 0.12, "mtr": 0.03, "quote": 0.74,
        }),
    },
    {
        "id": 2,
        "sender_email": "billing@halliburton.com",
        "subject": "RCM - Halliburton invoice 759085",
        "attachment_filename": "Halliburton_invoice_759085.pdf",
        "reason": "ambiguous",
        "confidence_scores": json.dumps({
            "po": 0.71, "invoice": 0.78, "mtr": 0.01, "quote": 0.05,
        }),
    },

    # Two MTRs where heat code couldn't be extracted.
    {
        "id": 3,
        "sender_email": "qa@woi-houston.com",
        "subject": "RCM - MTR for WOI order W000009810",
        "attachment_filename": "MTR W000009810.pdf",
        "reason": "mtr_no_heat_code",
        "confidence_scores": json.dumps({
            "po": 0.04, "invoice": 0.02, "mtr": 0.82, "quote": 0.00,
        }),
    },
    {
        "id": 4,
        "sender_email": "certs@flotite.com",
        "subject": "RCM - Material Test Report S3000CSPGGL015MP",
        "attachment_filename": "0.5_Full Port_Part No S3000CSPGGL015MP.pdf",
        "reason": "mtr_no_heat_code",
        "confidence_scores": json.dumps({
            "po": 0.03, "invoice": 0.01, "mtr": 0.79, "quote": 0.00,
        }),
    },

    # Two unmatched sender domains.
    {
        "id": 5,
        "sender_email": "purchasing@newvendor-inc.com",
        "subject": "RCM - PO from a vendor we haven't seen before",
        "attachment_filename": "NewVendor_PO_2026-04-22.pdf",
        "reason": "client_unmatched",
        "confidence_scores": json.dumps({
            "po": 0.86, "invoice": 0.08, "mtr": 0.02, "quote": 0.04,
        }),
    },
    {
        "id": 6,
        "sender_email": "billing@small-shop.com",
        "subject": "RCM - Invoice March 2026",
        "attachment_filename": "Invoice_March_2026.pdf",
        "reason": "client_unmatched",
        "confidence_scores": json.dumps({
            "po": 0.11, "invoice": 0.84, "mtr": 0.01, "quote": 0.03,
        }),
    },

    # One processing error.
    {
        "id": 7,
        "sender_email": "noreply@example-vendor.com",
        "subject": "RCM - corrupted attachment",
        "attachment_filename": "scan_2026-05-10_corrupted.pdf",
        "reason": "error",
        "error_message": (
            "PDFSyntaxError: No /Root object! - Is this really a PDF? "
            "(stack trace in /logs/processor.log.2026-05-10)"
        ),
        "confidence_scores": None,
    },
]


def main() -> None:
    out = Path(sys.argv[1]) if len(sys.argv) > 1 else (
        Path(__file__).resolve().parent.parent / "daily_brief_preview.html"
    )
    html = build_brief_html(SAMPLE_ITEMS)
    out.write_text(html, encoding="utf-8")
    print(f"Wrote {len(html)} bytes to {out}")
    print("Open the file in a browser to preview.")


if __name__ == "__main__":
    main()