mirror of
https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools.git
synced 2026-06-17 23:09:35 +00:00
Move from GO_PRIVATE_BETA (technical readiness) to PAID_BETA_READY (first revenue) — operational, not architectural. Deliverables: - docs/PAID_BETA_OPERATING_PLAYBOOK.md 10-section Arabic playbook: gate to Paid Beta, 7-day day-by-day plan (Staging → Outreach → Demos → Diagnostic → Pilot Sale → Pilot Day1/Day2 → Proof+Upsell), weekly targets (50-70 messages / 5-10 replies / 3-5 demos / 1+ payment), 8 hard operational rules, daily cadence, what NOT to add, Public Launch criteria. - docs/FIRST_PILOT_DELIVERY_WORKFLOW.md 48-hour Arabic Pilot delivery: T+0 intake (15 fields) → T+24 Free Diagnostic (3 opportunities + 1 Arabic message + 1 risk + 1 service recommendation) → T+48 Pilot 499 (10 opportunities + 7-day follow-up plan + Proof Pack) → T+7 final Proof Pack + 30min review + 3 upgrade paths. Pilot success criteria + 8-row metrics table. - docs/PRIVATE_BETA_OPERATING_BOARD.md 15-column Sheet template (company, person, segment, source, channel, message_sent, reply_status, demo_booked, diagnostic_sent, pilot_offered, price, paid, proof_pack_sent, next_step, notes) + status flow + ICP distribution + 3-wave follow-up templates + daily routine + PDPL privacy rules + CSV header. - landing/private-beta.html Pilot 499 SAR offer prominent at top (badge + hero CTA), dedicated 3-card pricing section (Pilot 499 / Free Diagnostic / Growth OS Monthly 2,999), 7-day refund/case-study guarantee, mailto CTAs with prefilled subject + body, removed duplicate pricing block. - scripts/paid_beta_daily_scorecard.py (274 lines) argparse with --messages, --replies, --demos, --pilots, --payments, --proof-packs, --as-of, --json. Computes reply_rate / demo_rate / pilot_rate / payment_rate, daily verdict (ON_TRACK / BEHIND / OFF_TRACK), weekly verdict (BLOCKERS / STRETCH_PENDING / WEEKLY_TARGETS_HIT), and rule-based next_actions in Arabic. Targets: 50-70 messages / 5-15 replies / 3-7 demos / 2-3 pilots / 1-2 paid / 1+ proof pack per week. - tests/unit/test_paid_beta_scorecard.py 12 tests: zero-input, on-track day, tone-action trigger, payment → proof-pack action, full-week target hit, conversion rates, Arabic text rendering, JSON validity, CLI text/json modes, --as-of today/explicit. Hard rules (unchanged): - No live WhatsApp / Gmail / Calendar send without env flag + approval. - No Moyasar API charge — manual invoice/payment-link only. - No LinkedIn scraping / auto-DM — Lead Gen Forms + manual outreach. - No cold WhatsApp without opt-in (PDPL hard-block). - Every message passes safety_eval + saudi_tone_eval. - Every action recorded in Action Ledger. Validation: - python -m compileall api auto_client_acquisition: clean. - pytest tests/unit (excl. tenacity-dep tests): 950 passed, 2 skipped. - python scripts/smoke_inprocess.py: SMOKE_INPROCESS_OK (8/8 endpoints). - python scripts/paid_beta_daily_scorecard.py text + --json: both render correctly with Arabic + verdict + next_actions. - tests/unit/test_positioning_lock.py: 10 passed (no prohibited phrases introduced in updated landing/private-beta.html). Test count: 949 → 962 (+12 new, 1 prior already counted). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
275 lines
9.5 KiB
Python
275 lines
9.5 KiB
Python
#!/usr/bin/env python3
|
||
"""Paid Beta Daily Scorecard — تتبّع التقدّم اليومي نحو أول إيراد.
|
||
|
||
كل يوم في Paid Beta، شغّل:
|
||
|
||
python scripts/paid_beta_daily_scorecard.py \\
|
||
--messages 25 --replies 4 --demos 2 --pilots 1 --payments 0 --proof-packs 0
|
||
|
||
أو بصيغة JSON للأتمتة:
|
||
|
||
python scripts/paid_beta_daily_scorecard.py \\
|
||
--messages 25 --replies 4 --demos 2 --pilots 1 --payments 1 --proof-packs 0 --json
|
||
|
||
الهدف خلال 7 أيام:
|
||
70 تواصل يدوي / 15 رد / 7 ديمو / 3 pilots / 1–2 paid / 1 Proof Pack على الأقل.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import argparse
|
||
import json
|
||
import sys
|
||
from dataclasses import asdict, dataclass
|
||
from datetime import date
|
||
|
||
|
||
# ----- Targets -----
|
||
|
||
WEEKLY_TARGETS = {
|
||
"messages": {"min": 50, "stretch": 70},
|
||
"replies": {"min": 5, "stretch": 15},
|
||
"demos": {"min": 3, "stretch": 7},
|
||
"pilots": {"min": 2, "stretch": 3},
|
||
"payments": {"min": 1, "stretch": 2},
|
||
"proof_packs": {"min": 1, "stretch": 1},
|
||
}
|
||
|
||
DAILY_TARGETS = {
|
||
# ÷ 7 (مدوّر للأعلى) لأي metric
|
||
"messages": 10,
|
||
"replies": 1,
|
||
"demos": 1,
|
||
"pilots": 0, # ≥1 خلال الأسبوع
|
||
"payments": 0, # ≥1 خلال الأسبوع
|
||
"proof_packs": 0, # ≥1 خلال الأسبوع
|
||
}
|
||
|
||
|
||
# ----- Computation -----
|
||
|
||
@dataclass
|
||
class Scorecard:
|
||
as_of: str
|
||
messages: int
|
||
replies: int
|
||
demos: int
|
||
pilots: int
|
||
payments: int
|
||
proof_packs: int
|
||
reply_rate: float
|
||
demo_rate: float
|
||
pilot_rate: float
|
||
payment_rate: float
|
||
daily_verdict: str
|
||
weekly_verdict: str
|
||
next_actions: list[str]
|
||
|
||
|
||
def _safe_div(a: int, b: int) -> float:
|
||
return round(a / b, 3) if b > 0 else 0.0
|
||
|
||
|
||
def _daily_verdict(metrics: dict[str, int]) -> str:
|
||
"""Compare today's metrics to daily targets."""
|
||
misses = []
|
||
for key, target in DAILY_TARGETS.items():
|
||
if target == 0:
|
||
continue
|
||
if metrics[key] < target:
|
||
misses.append(f"{key}: {metrics[key]}/{target}")
|
||
if not misses:
|
||
return "ON_TRACK"
|
||
if len(misses) == 1:
|
||
return f"BEHIND on {misses[0]}"
|
||
return f"OFF_TRACK: {', '.join(misses)}"
|
||
|
||
|
||
def _weekly_verdict(metrics: dict[str, int]) -> str:
|
||
"""Compare cumulative-week metrics to weekly targets (assumes the input is week-to-date totals)."""
|
||
blockers = []
|
||
misses = []
|
||
for key, t in WEEKLY_TARGETS.items():
|
||
v = metrics[key]
|
||
if v < t["min"]:
|
||
blockers.append(f"{key} {v}/{t['min']}")
|
||
elif v < t["stretch"]:
|
||
misses.append(f"{key} {v}/{t['stretch']}")
|
||
if not blockers and not misses:
|
||
return "WEEKLY_TARGETS_HIT"
|
||
if blockers:
|
||
return "BLOCKERS: " + ", ".join(blockers)
|
||
return "STRETCH_PENDING: " + ", ".join(misses)
|
||
|
||
|
||
def _next_actions(metrics: dict[str, int]) -> list[str]:
|
||
actions: list[str] = []
|
||
|
||
if metrics["messages"] < DAILY_TARGETS["messages"]:
|
||
deficit = DAILY_TARGETS["messages"] - metrics["messages"]
|
||
actions.append(
|
||
f"أرسل {deficit} رسالة إضافية اليوم (LinkedIn/Email/WhatsApp opt-in فقط)."
|
||
)
|
||
|
||
if metrics["messages"] >= 5 and metrics["replies"] == 0:
|
||
actions.append(
|
||
"0 ردود مع >5 رسائل — راجع نبرة الرسالة وعدّلها (saudi_tone_eval)."
|
||
)
|
||
|
||
if metrics["replies"] >= 2 and metrics["demos"] == 0:
|
||
actions.append(
|
||
"ردود إيجابية بدون ديمو — احجز ديمو 12 دقيقة لكل رد إيجابي اليوم."
|
||
)
|
||
|
||
if metrics["demos"] >= 2 and metrics["pilots"] == 0:
|
||
actions.append(
|
||
"ديمو ≥2 بدون عرض Pilot — أرسل عرض Pilot 499 + Free Diagnostic لكل ديمو."
|
||
)
|
||
|
||
if metrics["pilots"] >= 1 and metrics["payments"] == 0:
|
||
actions.append(
|
||
"Pilot معروض بدون دفع — تابع Moyasar invoice manual + رسالة متابعة دفع."
|
||
)
|
||
|
||
if metrics["payments"] >= 1 and metrics["proof_packs"] == 0:
|
||
actions.append(
|
||
"أول دفعة وصلت — ابدأ Pilot delivery + أعد Proof Pack v1 خلال 48 ساعة."
|
||
)
|
||
|
||
if not actions:
|
||
actions.append(
|
||
"اليوم ON_TRACK. حافظ على الإيقاع: 10 رسائل + 5 follow-ups + 1 ديمو."
|
||
)
|
||
|
||
return actions
|
||
|
||
|
||
def build_scorecard(
|
||
messages: int,
|
||
replies: int,
|
||
demos: int,
|
||
pilots: int,
|
||
payments: int,
|
||
proof_packs: int,
|
||
as_of: str | None = None,
|
||
) -> Scorecard:
|
||
metrics = {
|
||
"messages": messages,
|
||
"replies": replies,
|
||
"demos": demos,
|
||
"pilots": pilots,
|
||
"payments": payments,
|
||
"proof_packs": proof_packs,
|
||
}
|
||
return Scorecard(
|
||
as_of=as_of or date.today().isoformat(),
|
||
messages=messages,
|
||
replies=replies,
|
||
demos=demos,
|
||
pilots=pilots,
|
||
payments=payments,
|
||
proof_packs=proof_packs,
|
||
reply_rate=_safe_div(replies, messages),
|
||
demo_rate=_safe_div(demos, replies),
|
||
pilot_rate=_safe_div(pilots, demos),
|
||
payment_rate=_safe_div(payments, pilots),
|
||
daily_verdict=_daily_verdict(metrics),
|
||
weekly_verdict=_weekly_verdict(metrics),
|
||
next_actions=_next_actions(metrics),
|
||
)
|
||
|
||
|
||
# ----- Rendering -----
|
||
|
||
def render_text(card: Scorecard) -> str:
|
||
lines = [
|
||
"════════════════════════════════════════════════",
|
||
f" Paid Beta Daily Scorecard — {card.as_of}",
|
||
"════════════════════════════════════════════════",
|
||
"",
|
||
"اليوم:",
|
||
f" 📨 رسائل أُرسلت: {card.messages:>3} (يومي ≥10)",
|
||
f" 💬 ردود إيجابية: {card.replies:>3} (يومي ≥1)",
|
||
f" 📅 ديمو محجوز: {card.demos:>3} (يومي ≥1)",
|
||
f" 🚀 Pilots معروضة: {card.pilots:>3} (أسبوعي ≥2)",
|
||
f" 💳 دفعات وصلت: {card.payments:>3} (أسبوعي ≥1)",
|
||
f" 📦 Proof Packs مرسلة: {card.proof_packs:>3} (أسبوعي ≥1)",
|
||
"",
|
||
"Conversion Rates:",
|
||
f" reply_rate = {card.reply_rate:.1%}",
|
||
f" demo_rate = {card.demo_rate:.1%} (replies → demos)",
|
||
f" pilot_rate = {card.pilot_rate:.1%} (demos → pilots)",
|
||
f" payment_rate = {card.payment_rate:.1%} (pilots → paid)",
|
||
"",
|
||
f"Daily Verdict: {card.daily_verdict}",
|
||
f"Weekly Verdict: {card.weekly_verdict}",
|
||
"",
|
||
"Next Actions:",
|
||
]
|
||
for i, action in enumerate(card.next_actions, 1):
|
||
lines.append(f" {i}. {action}")
|
||
lines.extend([
|
||
"",
|
||
"════════════════════════════════════════════════",
|
||
"Targets: 50–70 messages / 5–15 replies / 3–7 demos /",
|
||
" 2–3 pilots / 1–2 paid / 1+ proof pack الأسبوع.",
|
||
"════════════════════════════════════════════════",
|
||
])
|
||
return "\n".join(lines)
|
||
|
||
|
||
def render_json(card: Scorecard) -> str:
|
||
return json.dumps(asdict(card), ensure_ascii=False, indent=2)
|
||
|
||
|
||
# ----- CLI -----
|
||
|
||
def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
|
||
p = argparse.ArgumentParser(
|
||
description="Paid Beta daily scorecard — track manual outreach progress.",
|
||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||
epilog=(
|
||
"Examples:\n"
|
||
" python scripts/paid_beta_daily_scorecard.py "
|
||
"--messages 25 --replies 4 --demos 2 --pilots 1 --payments 0 --proof-packs 0\n"
|
||
" python scripts/paid_beta_daily_scorecard.py "
|
||
"--messages 25 --replies 4 --demos 2 --pilots 1 --payments 1 --proof-packs 0 --json"
|
||
),
|
||
)
|
||
p.add_argument("--messages", type=int, default=0, help="رسائل أُرسلت")
|
||
p.add_argument("--replies", type=int, default=0, help="ردود إيجابية")
|
||
p.add_argument("--demos", type=int, default=0, help="ديمو محجوز")
|
||
p.add_argument("--pilots", type=int, default=0, help="Pilots معروضة")
|
||
p.add_argument("--payments", type=int, default=0, help="دفعات وصلت")
|
||
p.add_argument("--proof-packs", dest="proof_packs", type=int, default=0,
|
||
help="Proof Packs مُسلَّمة")
|
||
p.add_argument("--as-of", type=str, default=None,
|
||
help="تاريخ (YYYY-MM-DD أو 'today')")
|
||
p.add_argument("--json", action="store_true", help="إخراج JSON")
|
||
return p.parse_args(argv)
|
||
|
||
|
||
def main(argv: list[str] | None = None) -> int:
|
||
args = parse_args(argv)
|
||
as_of = None if (args.as_of in (None, "today")) else args.as_of
|
||
card = build_scorecard(
|
||
messages=args.messages,
|
||
replies=args.replies,
|
||
demos=args.demos,
|
||
pilots=args.pilots,
|
||
payments=args.payments,
|
||
proof_packs=args.proof_packs,
|
||
as_of=as_of,
|
||
)
|
||
output = render_json(card) if args.json else render_text(card)
|
||
try:
|
||
sys.stdout.reconfigure(encoding="utf-8")
|
||
except (AttributeError, OSError):
|
||
pass
|
||
print(output)
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main())
|