some basic statistics and invite tree, plus watch new data
This commit is contained in:
@@ -154,6 +154,33 @@ def delete_user(db: sqlite3.Connection, handle: str) -> None:
|
||||
db.commit()
|
||||
|
||||
|
||||
def get_member_tree(db: sqlite3.Connection) -> list[dict]:
|
||||
"""Return users with their inviter handle and join timestamp.
|
||||
|
||||
Each entry: {handle, display_name, created_at, invited_by (handle or None)}.
|
||||
Ordered oldest-first so callers can build the tree top-down.
|
||||
"""
|
||||
users = {r["handle"]: r for r in db.execute(
|
||||
"SELECT handle, display_name, created_at FROM users ORDER BY created_at"
|
||||
).fetchall()}
|
||||
# Map invitee → inviter from the used invites
|
||||
invited_by: dict[str, str] = {}
|
||||
for row in db.execute(
|
||||
"SELECT created_by, used_by FROM invites WHERE used_by IS NOT NULL"
|
||||
).fetchall():
|
||||
invited_by[row["used_by"]] = row["created_by"]
|
||||
|
||||
return [
|
||||
{
|
||||
"handle": r["handle"],
|
||||
"display_name": r["display_name"],
|
||||
"created_at": r["created_at"],
|
||||
"invited_by": invited_by.get(r["handle"]),
|
||||
}
|
||||
for r in users.values()
|
||||
]
|
||||
|
||||
|
||||
def count_users(db: sqlite3.Connection) -> int:
|
||||
"""Return the total number of registered users."""
|
||||
row = db.execute("SELECT COUNT(*) FROM users").fetchone()
|
||||
|
||||
Reference in New Issue
Block a user