Add a statistic for oldest question waiting for a helper response (#152)

* Silence type error (that was annoying me)

* Add new metric: oldest_unanswered_ticket_age_minutes

* Fix datetime subtraction exception
This commit is contained in:
Mish 2026-01-29 14:45:45 +00:00 committed by GitHub
parent e77a60e1ec
commit 1dd26d70f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 15 additions and 3 deletions

View file

@ -30,6 +30,7 @@ async def stats(req: Request):
],
"average_hang_time_minutes": total_stats.avg_hang_time_minutes,
"mean_resolution_time_minutes": total_stats.mean_resolution_time_minutes,
"oldest_unanswered_ticket_age_minutes": total_stats.oldest_unanswered_ticket_age_minutes,
"prev_day_total": prev_day_stats.new_tickets_total,
"prev_day_open": prev_day_stats.new_tickets_still_open,
"prev_day_in_progress": prev_day_stats.new_tickets_in_progress,

View file

@ -113,7 +113,7 @@ you managed to close a whopping *{stats.closed_today}* tickets in the last 24 ho
await env.slack_client.files_upload_v2(
channel=env.slack_bts_channel,
file=pie_chart,
file=pie_chart, # type: ignore (we requested a raw pie chart so type is bytes)
title="ticket status",
initial_comment=msg,
)

View file

@ -6,7 +6,7 @@ from prisma.enums import UserType
from prisma.models import Ticket
async def get_unanswered_tickets(since: datetime) -> list[Ticket]:
async def get_unanswered_tickets(since: datetime | None = None) -> list[Ticket]:
"""
Finds tickets that have been awaiting a response from a helper for a while.
@ -16,7 +16,7 @@ async def get_unanswered_tickets(since: datetime) -> list[Ticket]:
unanswered_tickets = await env.db.ticket.find_many(
where={
"status": TicketStatus.OPEN,
"lastMsgAt": {"lt": since},
"lastMsgAt": {"lt": since} if since else {},
"AND": [{"NOT": [{"lastMsgBy": UserType.HELPER}]}],
},
order={"lastMsgAt": "asc"},

View file

@ -4,6 +4,7 @@ from statistics import fmean
from typing import TypedDict
from nephthys.utils.env import env
from nephthys.utils.old_tickets import get_unanswered_tickets
from prisma.enums import TicketStatus
from prisma.models import Ticket
from prisma.models import User
@ -23,6 +24,7 @@ class OverallStatsResult:
helpers_leaderboard: list[LeaderboardEntry]
avg_hang_time_minutes: float | None
mean_resolution_time_minutes: float | None
oldest_unanswered_ticket_age_minutes: float | None
def calculate_hang_times(
@ -72,6 +74,14 @@ async def calculate_overall_stats() -> OverallStatsResult:
hang_times = calculate_hang_times(tickets, include_closed_tickets=False)
resolution_times = calculate_resolution_times(tickets)
oldest_unanswered_tickets = await get_unanswered_tickets()
now = datetime.now().astimezone()
oldest_unanswered_ticket_age = (
(now - oldest_unanswered_tickets[0].createdAt).total_seconds() / 60
if oldest_unanswered_tickets
else None
)
return OverallStatsResult(
tickets_total=total,
tickets_open=total_open,
@ -82,6 +92,7 @@ async def calculate_overall_stats() -> OverallStatsResult:
mean_resolution_time_minutes=fmean(resolution_times)
if resolution_times
else None,
oldest_unanswered_ticket_age_minutes=oldest_unanswered_ticket_age,
)