feat: add issue_usage tracking and metrics for AI ticket enhancement and planning

Add `issue_usage` table with columns for user_uid, tokens, cost, and latency metrics, including a unique index on user_uid. Wire `accumulate_usage` into `enhance_ticket` and `generate_plan` to capture per-request AI usage, persist totals via `add_issue_usage` in both `IssueCreateService` and `PlanningReportService`, and expose aggregated usage as metric cards through `IssueTrackerService.collect_metrics`. Update planning API docs summary to reflect the new phased implementation document format.
This commit is contained in:
2026-06-19 11:59:40 +00:00
parent 7bbaf51450
commit ff3cbbbfe2
16 changed files with 503 additions and 122 deletions
+4 -20
View File
@@ -508,27 +508,11 @@ def test_strip_md_fence_unwraps_only_full_fence():
assert _strip_md_fence(embedded) == embedded
def test_accumulate_usage_handles_headers_and_missing():
from devplacepy.services.news import _new_usage_totals, _accumulate_usage
totals = _new_usage_totals()
_accumulate_usage(totals, FakeRespHeaders(headers=GATEWAY_HEADERS))
_accumulate_usage(totals, FakeRespHeaders(headers=GATEWAY_HEADERS))
assert totals["calls"] == 2
assert totals["total_tokens"] == 1200
assert abs(totals["cost_usd"] - 0.0002) < 1e-9
_accumulate_usage(None, FakeRespHeaders(headers=GATEWAY_HEADERS))
_accumulate_usage(totals, FakeRespHeaders(headers={}))
_accumulate_usage(totals, object())
assert totals["calls"] == 2
def test_grade_article_accumulates_usage(local_db, monkeypatch):
from devplacepy.services.news import _new_usage_totals
from devplacepy.services.openai_gateway.usage import new_usage_totals
monkeypatch.setattr(news_mod, "get_setting", _settings_stub())
totals = _new_usage_totals()
totals = new_usage_totals()
grade = run_async(
NewsService()._grade_article(
{"title": "HighArticle deep dive", "description": "d", "content": "c"},
@@ -544,10 +528,10 @@ def test_grade_article_accumulates_usage(local_db, monkeypatch):
def test_format_article_returns_markdown_and_accumulates(local_db, monkeypatch):
from devplacepy.services.news import _new_usage_totals
from devplacepy.services.openai_gateway.usage import new_usage_totals
monkeypatch.setattr(news_mod, "get_setting", _settings_stub())
totals = _new_usage_totals()
totals = new_usage_totals()
article = {
"title": "A solid technical headline",
"description": "d" * 120,