diff --git a/VERSION b/VERSION index 6ee69cb..50a143c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1259 \ No newline at end of file +1260 \ No newline at end of file diff --git a/backend/routes/auth.py b/backend/routes/auth.py index 718d6cd..c0e7e5a 100644 --- a/backend/routes/auth.py +++ b/backend/routes/auth.py @@ -397,6 +397,85 @@ async def me(user=Depends(get_current_user)): return data +def _notify_partner_registration(user_id: int): + """Dank-Mail an den Partner (Code-Besitzer), wenn ein Geworbener seine + E-Mail bestätigt hat — inkl. kleiner Statistik. Best effort.""" + import html as _html + with db() as conn: + u = conn.execute( + "SELECT referred_by, referred_qr FROM users WHERE id=?", (user_id,) + ).fetchone() + if not u or (u["referred_by"] or 0) >= 0: + return # kein Partner-Code im Spiel + code_id = -u["referred_by"] + pc = conn.execute( + """SELECT pc.code, pc.label, pc.grants_founder, pc.owner_user_id, + o.name AS owner_name, o.email AS owner_email + FROM partner_codes pc + LEFT JOIN users o ON o.id = pc.owner_user_id + WHERE pc.id=?""", + (code_id,) + ).fetchone() + if not pc or not pc["owner_email"]: + return # Code ohne Besitzer → niemand zu benachrichtigen + total = conn.execute( + "SELECT COUNT(*) FROM users WHERE referred_by=? AND email_verified=1", + (-code_id,) + ).fetchone()[0] + month = conn.execute( + """SELECT COUNT(*) FROM users + WHERE referred_by=? AND email_verified=1 + AND strftime('%Y-%m', created_at) = strftime('%Y-%m', 'now')""", + (-code_id,) + ).fetchone()[0] + qr_line = "" + if u["referred_qr"]: + qr = conn.execute( + """SELECT q.seq, b.label FROM partner_qr_codes q + JOIN partner_qr_batches b ON b.id = q.batch_id + WHERE q.token=?""", + (u["referred_qr"],) + ).fetchone() + if qr: + qr_line = f"Gekommen über deinen gedruckten QR-Code #{qr['seq']} (Kontingent „{qr['label']}“)." + founder_line = "" + if pc["grants_founder"]: + founders = conn.execute( + "SELECT COUNT(*) FROM users WHERE is_founder=1" + ).fetchone()[0] + founder_line = f"Noch {max(0, 100 - founders)} von 100 Gründer-Plätzen frei." + + subject = "🐾 Danke! Neue Registrierung über deinen Partner-Code" + _oname = _html.escape(pc["owner_name"] or "Partner") + stats_html = ( + f"
Deine Bilanz mit dem Code {pc['code']}:
"
+ f"{total} bestätigte Registrierung{'en' if total != 1 else ''} insgesamt · "
+ f"{month} in diesem Monat.
Hallo {_oname},
++ gerade hat ein neuer Hundefreund seine Registrierung über deinen + Partner-Code bestätigt — danke, dass du Ban Yaro weiterträgst! 🎉 +
+ {f'{_html.escape(qr_line)}
' if qr_line else ''} + {stats_html} + {f'{_html.escape(founder_line)}
' if founder_line else ''}""" + plain = (f"Hallo {pc['owner_name'] or 'Partner'},\n\n" + f"gerade hat ein neuer Hundefreund seine Registrierung über deinen Partner-Code bestätigt — danke!\n" + + (f"\n{qr_line}\n" if qr_line else "") + + f"\nDeine Bilanz mit dem Code {pc['code']}: {total} bestätigte Registrierungen insgesamt, {month} in diesem Monat.\n" + + (f"{founder_line}\n" if founder_line else "") + + f"\nDeine Statistik: {_APP_URL}/#partner-profil\n") + try: + from routes.outreach import _send_smtp + from mailer import email_html + html = email_html(body_html, cta_url=f"{_APP_URL}/#partner-profil", cta_label="Meine Partner-Statistik") + _send_smtp(pc["owner_email"], subject, plain, "partner", html=html) + except Exception as exc: + _log_smtp_failure(pc["owner_email"], subject, plain, exc, context="partner_thank_you") + + @router.get("/verify-email/{token}") async def verify_email(token: str): with db() as conn: @@ -409,6 +488,9 @@ async def verify_email(token: str): "UPDATE users SET email_verified=1, verification_token=NULL WHERE id=?", (row["id"],) ) + # Dank-Mail an den Partner — nur beim ERSTEN Bestätigen (Link doppelt geklickt = kein Spam) + if not row["email_verified"]: + _notify_partner_registration(row["id"]) return RedirectResponse(f"{_APP_URL}/#settings?verified=1", status_code=302) diff --git a/backend/static/index.html b/backend/static/index.html index 08c14dc..4ed0115 100644 --- a/backend/static/index.html +++ b/backend/static/index.html @@ -86,14 +86,14 @@