feat(admin): add subscription history, status override, and statuses constant
Adds four new DB helpers for the admin panel: - SUBSCRIPTION_STATUSES: tuple of valid subscription statuses - list_by_user(): retrieve all subscriptions for a user (newest first) - set_status(): override a subscription's status and updated_at timestamp - get_subscriber_state(): public wrapper for internal _get_state() Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -123,6 +123,27 @@ def get_current(user_id: int) -> sqlite3.Row | None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
SUBSCRIPTION_STATUSES = ("active", "trial", "cancelled", "expired", "pending")
|
||||||
|
|
||||||
|
|
||||||
|
def list_by_user(user_id: int) -> list[sqlite3.Row]:
|
||||||
|
return (
|
||||||
|
get_conn()
|
||||||
|
.execute(
|
||||||
|
"SELECT * FROM subscriptions WHERE user_id = ? ORDER BY id DESC",
|
||||||
|
(user_id,),
|
||||||
|
)
|
||||||
|
.fetchall()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def set_status(subscription_id: int, status: str) -> None:
|
||||||
|
get_conn().execute(
|
||||||
|
"UPDATE subscriptions SET status = ?, updated_at = ? WHERE id = ?",
|
||||||
|
(status, _now(), subscription_id),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_by_handle(subscription_handle: str) -> sqlite3.Row | None:
|
def get_by_handle(subscription_handle: str) -> sqlite3.Row | None:
|
||||||
return (
|
return (
|
||||||
get_conn()
|
get_conn()
|
||||||
@@ -210,6 +231,10 @@ def _get_state(user_id: int) -> sqlite3.Row | None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_subscriber_state(user_id: int) -> sqlite3.Row | None:
|
||||||
|
return _get_state(user_id)
|
||||||
|
|
||||||
|
|
||||||
def freeze_votes_cursor(user_id: int) -> None:
|
def freeze_votes_cursor(user_id: int) -> None:
|
||||||
"""Réactivation après une période sans abonnement : repart de maintenant.
|
"""Réactivation après une période sans abonnement : repart de maintenant.
|
||||||
|
|
||||||
|
|||||||
@@ -326,3 +326,51 @@ def test_trial_to_active_does_not_reset_then_grants_two(users_db_path):
|
|||||||
db.update_from_webhook(handle, "active", _future())
|
db.update_from_webhook(handle, "active", _future())
|
||||||
# fin d'essai : credit_pending accorde les +INITIAL_VOTES initiaux
|
# fin d'essai : credit_pending accorde les +INITIAL_VOTES initiaux
|
||||||
assert db.credit_pending(uid) == db.INITIAL_VOTES
|
assert db.credit_pending(uid) == db.INITIAL_VOTES
|
||||||
|
|
||||||
|
|
||||||
|
def test_list_by_user_returns_most_recent_first(users_db_path):
|
||||||
|
uid = _make_user()
|
||||||
|
db.init_schema()
|
||||||
|
_handle1, sub_id1 = db.create_pending(uid, "cust-1", "simple")
|
||||||
|
_handle2, sub_id2 = db.create_pending(uid, "cust-1", "soutien")
|
||||||
|
|
||||||
|
rows = db.list_by_user(uid)
|
||||||
|
|
||||||
|
assert [r["id"] for r in rows] == [sub_id2, sub_id1]
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_status_updates_status(users_db_path):
|
||||||
|
uid = _make_user()
|
||||||
|
db.init_schema()
|
||||||
|
_handle, sub_id = db.create_pending(uid, "cust-1", "simple")
|
||||||
|
|
||||||
|
db.set_status(sub_id, "active")
|
||||||
|
|
||||||
|
row = db.get_current(uid)
|
||||||
|
assert row["status"] == "active"
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_subscriber_state_returns_row_after_create_pending(users_db_path):
|
||||||
|
uid = _make_user()
|
||||||
|
db.init_schema()
|
||||||
|
db.create_pending(uid, "cust-1", "simple")
|
||||||
|
|
||||||
|
state = db.get_subscriber_state(uid)
|
||||||
|
|
||||||
|
assert state is not None
|
||||||
|
assert state["user_id"] == uid
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_subscriber_state_returns_none_for_unknown_user(users_db_path):
|
||||||
|
db.init_schema()
|
||||||
|
assert db.get_subscriber_state(999999) is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_subscription_statuses_constant():
|
||||||
|
assert db.SUBSCRIPTION_STATUSES == (
|
||||||
|
"active",
|
||||||
|
"trial",
|
||||||
|
"cancelled",
|
||||||
|
"expired",
|
||||||
|
"pending",
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user