fix(dashboard): paginate CEO dashboard ticket fetch to respect API cap

The CEO dashboard requested /api/tickets?page_size=500, but the API caps
page_size at 200 (le=200 in app/routers/tickets.py), so the request
returned 422 and every KPI/chart rendered zeros.

- ceo.html: fetch all tickets by looping pages of page_size=200 until
  total items are collected (with a safety bound), keeping KPIs accurate
  as volume grows past 200.
- tests: add test suite anchoring the pagination contract — page_size=500
  returns 422, page_size=200 returns items/total/page/page_size, and a
  page loop collects every ticket without duplicates.
- pyproject: enable pytest-asyncio auto mode and tests/ discovery.
- .gitignore: un-ignore committed tests/test_*.py.
This commit is contained in:
root
2026-07-31 09:53:35 +00:00
parent f84021bc14
commit 47be148240
5 changed files with 143 additions and 4 deletions
+16 -4
View File
@@ -171,10 +171,22 @@
async loadData() {
try {
const allData = await app().apiGet('/api/tickets?page_size=500');
if (!allData?.items) return;
const all = allData.items;
const total = allData.total || all.length;
// Fetch ALL tickets via pagination. The API caps page_size at 200
// (app/routers/tickets.py), so a single page_size=500 request returns 422
// and the dashboard renders empty KPIs. Loop pages until we have `total`
// tickets so KPIs stay accurate as volume grows past 200.
const all = [];
const pageSize = 200;
let page = 1;
let total = Infinity;
while (all.length < total && page <= 1000) { // 1000-page safety bound
const allData = await app().apiGet(`/api/tickets?page=${page}&page_size=${pageSize}`);
if (!allData?.items || !allData.items.length) break;
all.push(...allData.items);
total = allData.total ?? all.length;
page += 1;
}
if (!all.length) return;
// Basic KPIs
const open = all.filter(t => !['Closed', 'Completed'].includes(t.status));