system-prompts-and-models-o.../dealix/scripts/paid_beta_daily_scorecard.py
Sami Assiri b13cb389cc feat(dealix): sync full Dealix package to repo
- API routers, ACA modules, integrations (draft operators)
- Docs, landing pages, scripts (launch readiness, scorecard)
- Tests and CI workflow updates for Dealix

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-01 21:01:17 +03:00

164 lines
5.0 KiB
Python

#!/usr/bin/env python3
"""Print Dealix Private/Paid Beta daily scorecard metrics (stdin for ops, no network).
Reads counts from CLI flags, environment variable DEALIX_DAILY_SCORECARD_JSON,
or a JSON file (--file). Missing keys default to 0.
Example:
python scripts/paid_beta_daily_scorecard.py --messages 10 --replies 2 --demos 1
python scripts/paid_beta_daily_scorecard.py --file .dealix/daily_scorecard.json
"""
from __future__ import annotations
import argparse
import json
import os
import sys
from pathlib import Path
_REPO = Path(__file__).resolve().parents[1]
if str(_REPO) not in sys.path:
sys.path.insert(0, str(_REPO))
def _configure_stdio_utf8() -> None:
for stream in (sys.stdout, sys.stderr):
try:
stream.reconfigure(encoding="utf-8", errors="replace")
except (AttributeError, OSError):
pass
def _load_json_file(path: Path) -> dict[str, object]:
raw = json.loads(path.read_text(encoding="utf-8"))
if not isinstance(raw, dict):
raise ValueError("JSON root must be an object")
return {str(k): v for k, v in raw.items()}
def _coerce_int(val: object) -> int:
if val is None:
return 0
if isinstance(val, bool):
return int(val)
if isinstance(val, int):
return val
if isinstance(val, float):
return int(val)
s = str(val).strip()
if not s:
return 0
try:
return int(float(s))
except ValueError:
return 0
def build_metrics(
*,
messages_sent: int = 0,
replies: int = 0,
demos: int = 0,
pilots: int = 0,
payments: int = 0,
proof_packs: int = 0,
) -> dict[str, int]:
return {
"messages_sent": max(0, messages_sent),
"replies": max(0, replies),
"demos": max(0, demos),
"pilots": max(0, pilots),
"payments": max(0, payments),
"proof_packs": max(0, proof_packs),
}
def merge_from_mapping(base: dict[str, int], data: dict[str, object]) -> dict[str, int]:
aliases = {
"messages_sent": ("messages_sent", "messages", "msgs"),
"replies": ("replies", "positive_replies", "reply"),
"demos": ("demos", "demos_booked", "demo"),
"pilots": ("pilots", "pilots_offered", "pilot"),
"payments": ("payments", "payments_received", "paid"),
"proof_packs": ("proof_packs", "proof_pack", "proofs"),
}
out = dict(base)
for canonical, keys in aliases.items():
for k in keys:
if k in data:
out[canonical] = max(out.get(canonical, 0), _coerce_int(data[k]))
break
return out
def print_scorecard(m: dict[str, int], *, as_json: bool) -> None:
if as_json:
print(json.dumps(m, ensure_ascii=False, indent=2))
return
lines = [
"Dealix — Daily scorecard",
"------------------------",
f"messages_sent {m['messages_sent']}",
f"replies {m['replies']}",
f"demos {m['demos']}",
f"pilots {m['pilots']}",
f"payments {m['payments']}",
f"proof_packs {m['proof_packs']}",
]
print("\n".join(lines))
def main() -> int:
_configure_stdio_utf8()
p = argparse.ArgumentParser(description="Print daily beta scorecard metrics")
p.add_argument("--file", type=Path, help="JSON file with metric keys (see docs/PRIVATE_BETA_OPERATING_BOARD.md)")
p.add_argument("--json", action="store_true", help="Print JSON only")
p.add_argument("--messages", type=int, default=None)
p.add_argument("--replies", type=int, default=None)
p.add_argument("--demos", type=int, default=None)
p.add_argument("--pilots", type=int, default=None)
p.add_argument("--payments", type=int, default=None)
p.add_argument("--proof-packs", type=int, default=None)
args = p.parse_args()
m = build_metrics()
env_blob = os.environ.get("DEALIX_DAILY_SCORECARD_JSON", "").strip()
if env_blob:
try:
parsed = json.loads(env_blob)
if isinstance(parsed, dict):
m = merge_from_mapping(m, parsed)
except json.JSONDecodeError as exc:
print(f"Invalid DEALIX_DAILY_SCORECARD_JSON: {exc}", file=sys.stderr)
return 1
if args.file:
try:
file_data = _load_json_file(args.file)
# file uses string keys; merge
m = merge_from_mapping(m, {str(k): v for k, v in file_data.items()})
except (OSError, ValueError, json.JSONDecodeError) as exc:
print(f"--file error: {exc}", file=sys.stderr)
return 1
cli_overrides = {
"messages_sent": args.messages,
"replies": args.replies,
"demos": args.demos,
"pilots": args.pilots,
"payments": args.payments,
"proof_packs": args.proof_packs,
}
for key, val in cli_overrides.items():
if val is not None:
m[key] = max(0, int(val))
print_scorecard(m, as_json=args.json)
return 0
if __name__ == "__main__":
raise SystemExit(main())