Feature: Upgrade-Anfragen-System — User-Flow + Admin-Panel (SW by-v920)
- DB: upgrade_requests-Tabelle (user_id, tier, message, fulfilled_at)
- POST /api/upgrade-request: Anfrage speichern + Admin-Benachrichtigungsmail
- GET/POST /api/admin/upgrade-requests[/{id}/fulfill]: Admin-Endpunkte
— fulfill setzt subscription_tier + sendet Bestätigungsmail an User
- action-items: upgrades_pending zählt offene Anfragen → Badge im Admin
- Admin-Tab "Upgrades": Tabelle offener/erledigter Anfragen, Freischalten-Button
mit Confirm-Modal, automatischer Tier-Setzung und Bestätigungsmail
- Settings: Upgrade-Modal sendet echte API-Anfrage statt nur mailto
— doppelte Anfrage wird erkannt (already:true → Toast statt Fehler)
- api.js: API.auth.upgradeRequest(tier, message) hinzugefügt
- SW by-v920, APP_VER 920
This commit is contained in:
parent
d61fd155c5
commit
f6b37717b4
9 changed files with 268 additions and 27 deletions
|
|
@ -335,6 +335,46 @@ async def forgot_password(data: ForgotPasswordRequest, request: Request):
|
|||
return {"ok": True}
|
||||
|
||||
|
||||
class UpgradeRequestBody(BaseModel):
|
||||
tier: str
|
||||
message: Optional[str] = None
|
||||
|
||||
@router.post("/upgrade-request")
|
||||
async def create_upgrade_request(data: UpgradeRequestBody, user=Depends(get_current_user)):
|
||||
_VALID = {"pro", "breeder"}
|
||||
if data.tier not in _VALID:
|
||||
raise HTTPException(400, "Ungültiger Tarif.")
|
||||
with db() as conn:
|
||||
existing = conn.execute(
|
||||
"SELECT id FROM upgrade_requests WHERE user_id=? AND tier=? AND fulfilled_at IS NULL",
|
||||
(user["id"], data.tier)
|
||||
).fetchone()
|
||||
if existing:
|
||||
return {"ok": True, "already": True}
|
||||
conn.execute(
|
||||
"INSERT INTO upgrade_requests (user_id, tier, message) VALUES (?,?,?)",
|
||||
(user["id"], data.tier, data.message or None)
|
||||
)
|
||||
email = conn.execute("SELECT email FROM users WHERE id=?", (user["id"],)).fetchone()["email"]
|
||||
|
||||
tier_labels = {"pro": "Ban Yaro Pro", "breeder": "Züchter"}
|
||||
tier_label = tier_labels[data.tier]
|
||||
admin_email = os.getenv("ADMIN_EMAIL", "")
|
||||
if admin_email:
|
||||
try:
|
||||
from routes.outreach import _send_smtp
|
||||
subject = f"[Ban Yaro] Upgrade-Anfrage: {tier_label} — {user['name']}"
|
||||
body = (f"Neue Upgrade-Anfrage:\n\n"
|
||||
f"Nutzer: {user['name']} ({email})\n"
|
||||
f"Tarif: {tier_label}\n"
|
||||
f"Nachricht: {data.message or '—'}\n\n"
|
||||
f"Admin-Panel: https://banyaro.app/#admin")
|
||||
_send_smtp(admin_email, subject, body, "support")
|
||||
except Exception:
|
||||
pass
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@router.post("/reset-password")
|
||||
async def reset_password(data: ResetPasswordRequest, request: Request):
|
||||
rl_check(request, max_requests=5, window_seconds=3600, key="reset_pw")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue