feat: add leaderboard router, gamification backfill, and shared content creation helpers

Introduce a new `/leaderboard` endpoint ranking top 50 members by total stars, wire it into the app router and documentation. Implement `_backfill_gamification()` in `database.py` to compute XP/levels for existing accounts from prior posts, comments, votes, and follows. Extract `is_owner()`, `create_content_item()`, and `detail_context()` into `content.py` to centralize content creation, reward awarding, mention notifications, and attachment linking. Update comment creation/deletion in `comments.py` to use `award_rewards()` with `XP_COMMENT` and the new `is_owner()` helper. Add shared template partials documentation for vote bars, star buttons, post headers, and topic selectors to `AGENTS.md`.
This commit is contained in:
2026-05-30 18:16:39 +00:00
parent ab4861562b
commit a136287d36
57 changed files with 1310 additions and 674 deletions
+2
View File
@@ -54,6 +54,7 @@
<a href="/news" class="topnav-link {% if 'news' in request.url.path %}active{% endif %}"><span class="icon">πŸ“°</span> News</a>
<a href="/gists" class="topnav-link {% if 'gists' in request.url.path %}active{% endif %}"><span class="icon">πŸ“„</span> Gists</a>
<a href="/projects" class="topnav-link {% if 'projects' in request.url.path %}active{% endif %}"><span class="icon">πŸš€</span> Projects</a>
<a href="/leaderboard" class="topnav-link {% if 'leaderboard' in request.url.path %}active{% endif %}"><span class="icon">πŸ†</span> Leaderboard</a>
{% if user %}
<a href="/messages" class="topnav-link {% if 'messages' in request.url.path %}active{% endif %}"><span class="icon">βœ‰οΈ</span> Messages</a>
{% if user.get('role') == 'Admin' %}
@@ -105,6 +106,7 @@
<a href="/news" class="topnav-mobile-link {% if 'news' in request.url.path %}active{% endif %}"><span class="icon">πŸ“°</span> News</a>
<a href="/gists" class="topnav-mobile-link {% if 'gists' in request.url.path %}active{% endif %}"><span class="icon">πŸ“„</span> Gists</a>
<a href="/projects" class="topnav-mobile-link {% if 'projects' in request.url.path %}active{% endif %}"><span class="icon">πŸš€</span> Projects</a>
<a href="/leaderboard" class="topnav-mobile-link {% if 'leaderboard' in request.url.path %}active{% endif %}"><span class="icon">πŸ†</span> Leaderboard</a>
{% if user %}
<a href="/messages" class="topnav-mobile-link {% if 'messages' in request.url.path %}active{% endif %}"><span class="icon">βœ‰οΈ</span> Messages</a>
<a href="/notifications" class="topnav-mobile-link {% if 'notifications' in request.url.path %}active{% endif %}"><span class="icon">&#x1F514;</span> Notifications</a>