ui update and some backend functionality adding in accordance with research on adhd and ux design
This commit is contained in:
114
api/routes/rewards.py
Normal file
114
api/routes/rewards.py
Normal file
@@ -0,0 +1,114 @@
|
||||
"""
|
||||
Rewards API - variable reward system for routine completion
|
||||
"""
|
||||
|
||||
import os
|
||||
import uuid
|
||||
import random
|
||||
import flask
|
||||
import jwt
|
||||
import core.auth as auth
|
||||
import core.postgres as postgres
|
||||
|
||||
|
||||
def _get_user_uuid(token):
|
||||
try:
|
||||
payload = jwt.decode(token, os.getenv("JWT_SECRET"), algorithms=["HS256"])
|
||||
return payload.get("sub")
|
||||
except (jwt.ExpiredSignatureError, jwt.InvalidTokenError):
|
||||
return None
|
||||
|
||||
|
||||
def _auth(request):
|
||||
header = request.headers.get("Authorization", "")
|
||||
if not header.startswith("Bearer "):
|
||||
return None
|
||||
token = header[7:]
|
||||
user_uuid = _get_user_uuid(token)
|
||||
if not user_uuid or not auth.verifyLoginToken(token, userUUID=user_uuid):
|
||||
return None
|
||||
return user_uuid
|
||||
|
||||
|
||||
def register(app):
|
||||
|
||||
@app.route("/api/rewards/random", methods=["GET"])
|
||||
def api_getRandomReward():
|
||||
"""Get a weighted random reward. Query: ?context=completion"""
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
|
||||
context = flask.request.args.get("context", "completion")
|
||||
|
||||
# Fetch all rewards from pool
|
||||
all_rewards = postgres.select("reward_pool", where={})
|
||||
if not all_rewards:
|
||||
return flask.jsonify({"reward": None}), 200
|
||||
|
||||
# Weight by rarity: common=70%, uncommon=25%, rare=5%
|
||||
weights = {
|
||||
"common": 70,
|
||||
"uncommon": 25,
|
||||
"rare": 5,
|
||||
}
|
||||
weighted = []
|
||||
for reward in all_rewards:
|
||||
w = weights.get(reward.get("rarity", "common"), 70)
|
||||
weighted.extend([reward] * w)
|
||||
|
||||
if not weighted:
|
||||
return flask.jsonify({"reward": None}), 200
|
||||
|
||||
selected = random.choice(weighted)
|
||||
|
||||
# Record that user earned this reward
|
||||
try:
|
||||
postgres.insert("user_rewards", {
|
||||
"id": str(uuid.uuid4()),
|
||||
"user_uuid": user_uuid,
|
||||
"reward_id": selected["id"],
|
||||
"context": context,
|
||||
})
|
||||
except Exception:
|
||||
pass # Don't fail if recording fails
|
||||
|
||||
return flask.jsonify({
|
||||
"reward": {
|
||||
"id": selected["id"],
|
||||
"category": selected["category"],
|
||||
"content": selected["content"],
|
||||
"emoji": selected.get("emoji"),
|
||||
"rarity": selected.get("rarity", "common"),
|
||||
}
|
||||
}), 200
|
||||
|
||||
@app.route("/api/rewards/history", methods=["GET"])
|
||||
def api_getRewardHistory():
|
||||
"""Get user's past earned rewards."""
|
||||
user_uuid = _auth(flask.request)
|
||||
if not user_uuid:
|
||||
return flask.jsonify({"error": "unauthorized"}), 401
|
||||
|
||||
earned = postgres.select(
|
||||
"user_rewards",
|
||||
where={"user_uuid": user_uuid},
|
||||
order_by="earned_at DESC",
|
||||
limit=50,
|
||||
)
|
||||
|
||||
# Enrich with reward content
|
||||
result = []
|
||||
for entry in earned:
|
||||
reward = postgres.select_one("reward_pool", {"id": entry["reward_id"]})
|
||||
if reward:
|
||||
result.append({
|
||||
"earned_at": entry["earned_at"],
|
||||
"context": entry.get("context"),
|
||||
"category": reward["category"],
|
||||
"content": reward["content"],
|
||||
"emoji": reward.get("emoji"),
|
||||
"rarity": reward.get("rarity"),
|
||||
})
|
||||
|
||||
return flask.jsonify(result), 200
|
||||
Reference in New Issue
Block a user