Feature: Referral-System — User wirbt User
- DB: referral_code (8-stellig, eindeutig) + referred_by zu users Bestehende User erhalten automatisch einen Code - GET /api/auth/referral: Code, Link und Anzahl geworbener User - POST /api/auth/register: ref_code Parameter für Zuordnung - Settings: 'App empfehlen'-Karte mit Link, Teilen-Button und Botschafter-Badges (Botschafter ab 1, Super ab 5, Top ab 10 Einladungen) - app.js: ?ref=CODE aus URL in sessionStorage speichern - APP_VER 222, SW by-v244
This commit is contained in:
parent
82d9e26823
commit
6d757b86c2
6 changed files with 121 additions and 7 deletions
|
|
@ -1,5 +1,10 @@
|
|||
"""BAN YARO — Auth Routes"""
|
||||
|
||||
import os
|
||||
import secrets
|
||||
import string
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, HTTPException, Response, Depends
|
||||
from pydantic import BaseModel, EmailStr
|
||||
from database import db
|
||||
|
|
@ -20,6 +25,12 @@ class RegisterRequest(BaseModel):
|
|||
email: EmailStr
|
||||
password: str
|
||||
name: str
|
||||
ref_code: Optional[str] = None
|
||||
|
||||
|
||||
def _gen_referral_code() -> str:
|
||||
alphabet = string.ascii_uppercase + string.digits
|
||||
return ''.join(secrets.choice(alphabet) for _ in range(8))
|
||||
|
||||
|
||||
def _set_cookie(response: Response, token: str):
|
||||
|
|
@ -45,10 +56,11 @@ async def register(data: RegisterRequest, response: Response):
|
|||
"SELECT 1 FROM users WHERE name=? COLLATE NOCASE", (name,)
|
||||
).fetchone():
|
||||
raise HTTPException(400, "Dieser Name ist bereits vergeben. Bitte wähle einen anderen.")
|
||||
code = _gen_referral_code()
|
||||
try:
|
||||
conn.execute(
|
||||
"INSERT INTO users (email, pw_hash, name) VALUES (?,?,?)",
|
||||
(data.email, hash_password(data.password), name)
|
||||
"INSERT INTO users (email, pw_hash, name, referral_code) VALUES (?,?,?,?)",
|
||||
(data.email, hash_password(data.password), name, code)
|
||||
)
|
||||
except Exception:
|
||||
# Fallback falls UNIQUE-Index greift (Race Condition)
|
||||
|
|
@ -56,6 +68,16 @@ async def register(data: RegisterRequest, response: Response):
|
|||
user = conn.execute(
|
||||
"SELECT id, rolle FROM users WHERE email=?", (data.email,)
|
||||
).fetchone()
|
||||
new_user_id = user["id"]
|
||||
|
||||
if data.ref_code:
|
||||
referrer = conn.execute(
|
||||
"SELECT id FROM users WHERE referral_code=? AND id != ?",
|
||||
(data.ref_code.strip().upper(), new_user_id)
|
||||
).fetchone()
|
||||
if referrer:
|
||||
conn.execute("UPDATE users SET referred_by=? WHERE id=?",
|
||||
(referrer['id'], new_user_id))
|
||||
|
||||
token = create_token(user["id"], user["rolle"])
|
||||
_set_cookie(response, token)
|
||||
|
|
@ -90,6 +112,21 @@ async def logout(response: Response):
|
|||
return {"ok": True}
|
||||
|
||||
|
||||
@router.get("/referral")
|
||||
async def get_referral_info(user=Depends(get_current_user)):
|
||||
with db() as conn:
|
||||
row = conn.execute(
|
||||
"SELECT referral_code, (SELECT COUNT(*) FROM users WHERE referred_by=?) AS count FROM users WHERE id=?",
|
||||
(user['id'], user['id'])
|
||||
).fetchone()
|
||||
base = os.getenv("APP_URL", "https://banyaro.app")
|
||||
return {
|
||||
"code": row["referral_code"],
|
||||
"count": row["count"],
|
||||
"link": f"{base}/?ref={row['referral_code']}",
|
||||
}
|
||||
|
||||
|
||||
@router.get("/me")
|
||||
async def me(user=Depends(get_current_user)):
|
||||
with db() as conn:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue