feat(KB-129): dashboard performance optimizations
- Fix SSE hook cleanup to prevent memory leaks and stale connections - Cap agent log memory and optimize batch log processing - Memoize Board, Column, and TaskCard with custom comparator to reduce re-renders - Stabilize column task arrays and preserve pagination across live updates - Add TaskCardBadge component for PR/issue state display - Remove deprecated GitHub polling code and archive functionality from core store
This commit is contained in:
@@ -118,6 +118,38 @@ function buildMultipart(fieldName: string, filename: string, contentType: string
|
||||
return { body, boundary };
|
||||
}
|
||||
|
||||
describe("GET /tasks", () => {
|
||||
let store: TaskStore;
|
||||
|
||||
beforeEach(() => {
|
||||
store = createMockStore();
|
||||
});
|
||||
|
||||
function buildApp() {
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
app.use("/api", createApiRoutes(store));
|
||||
return app;
|
||||
}
|
||||
|
||||
it("returns tasks with optional pagination params", async () => {
|
||||
(store.listTasks as ReturnType<typeof vi.fn>).mockResolvedValueOnce([FAKE_TASK_DETAIL]);
|
||||
|
||||
const res = await GET(buildApp(), "/api/tasks?limit=10&offset=5");
|
||||
|
||||
expect(res.status).toBe(200);
|
||||
expect(res.body).toHaveLength(1);
|
||||
expect(store.listTasks).toHaveBeenCalledWith({ limit: 10, offset: 5 });
|
||||
});
|
||||
|
||||
it("returns 400 for invalid pagination params", async () => {
|
||||
const res = await GET(buildApp(), "/api/tasks?limit=-1");
|
||||
|
||||
expect(res.status).toBe(400);
|
||||
expect(res.body.error).toContain("limit");
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET /tasks/:id", () => {
|
||||
let store: TaskStore;
|
||||
|
||||
|
||||
@@ -582,9 +582,22 @@ export function createApiRoutes(store: TaskStore, options?: ServerOptions): Rout
|
||||
registerModelsRoute(router, options?.modelRegistry);
|
||||
|
||||
// List all tasks
|
||||
router.get("/tasks", async (_req, res) => {
|
||||
router.get("/tasks", async (req, res) => {
|
||||
try {
|
||||
const tasks = await store.listTasks();
|
||||
const limit = typeof req.query.limit === "string" ? Number.parseInt(req.query.limit, 10) : undefined;
|
||||
const offset = typeof req.query.offset === "string" ? Number.parseInt(req.query.offset, 10) : undefined;
|
||||
|
||||
if (limit !== undefined && (!Number.isFinite(limit) || limit < 0)) {
|
||||
res.status(400).json({ error: "limit must be a non-negative integer" });
|
||||
return;
|
||||
}
|
||||
|
||||
if (offset !== undefined && (!Number.isFinite(offset) || offset < 0)) {
|
||||
res.status(400).json({ error: "offset must be a non-negative integer" });
|
||||
return;
|
||||
}
|
||||
|
||||
const tasks = await store.listTasks({ limit, offset });
|
||||
res.json(tasks);
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ error: err.message });
|
||||
|
||||
Reference in New Issue
Block a user