Skip to content

Commit ee74ea0

Browse files
fix(ci): resolve all 4 failing CI checks for PR #1280
- Fix package-lock.json out-of-sync: regenerated clean lockfile so npm ci passes (was failing with @babel/types version mismatch) - Fix ESLint errors in dashboard/calendar/page.tsx: refactor fetchStreams into async IIFE inside useEffect to avoid react-hooks/set-state-in-effect and preserve-manual-memoization errors - Fix TypeScript errors: add non-null assertions in batch-stream-wizard.test.tsx and remove unused React import in settings-content.test.tsx Verified locally: - npm ci passes (clean install) - Frontend: lint clean (0 errors), build passes, 38 test files / 324 tests pass - Backend: 51 test files / 395 tests pass (16 skipped) - npm audit: 0 vulnerabilities at --audit-level=high 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
1 parent c2abdee commit ee74ea0

4 files changed

Lines changed: 63 additions & 69 deletions

File tree

frontend/src/__tests__/batch-stream-wizard.test.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ GBBDIOEJGZHV5GFZQB4T7NKZQKRVNDQYXKW6Z3VJXZAVFQKZ5HM5J2EU,100.00,86400,0`;
3232
expect(result.totalRows).toBe(2);
3333
expect(result.validRows).toBe(1);
3434
expect(result.invalidRows).toBe(1);
35-
expect(result.entries[0].isValid).toBe(false);
36-
expect(result.entries[1].isValid).toBe(true);
35+
expect(result.entries[0]!.isValid).toBe(false);
36+
expect(result.entries[1]!.isValid).toBe(true);
3737
});
3838

3939
it("identifies invalid amounts", () => {
@@ -45,7 +45,7 @@ GBBDIOEJGZHV5GFZQB4T7NKZQKRVNDQYXKW6Z3VJXZAVFQKZ5HM5J2EU,-100,86400,0`;
4545
expect(result.totalRows).toBe(1);
4646
expect(result.validRows).toBe(0);
4747
expect(result.invalidRows).toBe(1);
48-
expect(result.entries[0].errors).toContainEqual(
48+
expect(result.entries[0]!.errors).toContainEqual(
4949
expect.objectContaining({ field: "amount" })
5050
);
5151
});
@@ -59,7 +59,7 @@ GBBDIOEJGZHV5GFZQB4T7NKZQKRVNDQYXKW6Z3VJXZAVFQKZ5HM5J2EU,100.00,0,0`;
5959
expect(result.totalRows).toBe(1);
6060
expect(result.validRows).toBe(0);
6161
expect(result.invalidRows).toBe(1);
62-
expect(result.entries[0].errors).toContainEqual(
62+
expect(result.entries[0]!.errors).toContainEqual(
6363
expect.objectContaining({ field: "durationSeconds" })
6464
);
6565
});

frontend/src/__tests__/settings-content.test.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { describe, it, expect, vi, beforeEach } from "vitest";
22
import { render, screen, fireEvent } from "@testing-library/react";
3-
import React from "react";
43

54
const pushMock = vi.fn();
65
vi.mock("next/navigation", () => ({

frontend/src/app/dashboard/calendar/page.tsx

Lines changed: 45 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import React, { useState, useEffect, useCallback } from "react";
3+
import React, { useState, useEffect } from "react";
44
import Link from "next/link";
55
import { ArrowLeft, Calendar as CalendarIcon, Filter } from "lucide-react";
66
import { useWallet } from "@/context/wallet-context";
@@ -38,61 +38,56 @@ export default function DashboardCalendarPage() {
3838
const [direction, setDirection] = useState<"all" | "incoming" | "outgoing">("all");
3939
const [projectionDays, setProjectionDays] = useState<7 | 30 | 90>(30);
4040

41-
// Fetch streams
42-
const fetchStreams = useCallback(async (signal?: AbortSignal) => {
43-
if (!session?.publicKey) return;
44-
45-
try {
46-
setLoading(true);
47-
const response = await fetch(
48-
`${API_BASE_URL}/streams?user=${session.publicKey}`,
49-
{ signal }
50-
);
51-
52-
if (!response.ok) {
53-
throw new Error("Failed to fetch streams");
54-
}
55-
56-
const data = await response.json();
57-
const streamList = Array.isArray(data) ? data : data.data ?? [];
58-
59-
// Map API response to our Stream type
60-
const mappedStreams: Stream[] = streamList.map((s: Record<string, unknown>) => ({
61-
id: s.id as string,
62-
streamId: s.streamId as number,
63-
sender: s.sender as string,
64-
recipient: s.recipient as string,
65-
tokenSymbol: s.tokenSymbol || "USDC",
66-
ratePerSecond: Number(s.ratePerSecond) || 0,
67-
depositedAmount: (s.depositedAmount as string) || "0",
68-
withdrawnAmount: (s.withdrawnAmount as string) || "0",
69-
startTime: s.startTime as number,
70-
endTime: s.endTime as number | undefined,
71-
isActive: s.isActive as boolean,
72-
isPaused: s.isPaused as boolean,
73-
status: (s.status as string) || "unknown",
74-
}));
75-
76-
setStreams(mappedStreams);
77-
setError(null);
78-
} catch (err) {
79-
if (err instanceof Error && err.name === "AbortError") return;
80-
logger.error("Failed to fetch streams:", err);
81-
setError(err instanceof Error ? err.message : "Failed to load streams");
82-
} finally {
83-
setLoading(false);
84-
}
85-
}, [session?.publicKey]);
86-
87-
// Load streams on mount
41+
// Load streams on mount / wallet change
8842
useEffect(() => {
8943
if (!isHydrated || !session?.publicKey) return;
9044

9145
const controller = new AbortController();
92-
fetchStreams(controller.signal);
46+
47+
void (async () => {
48+
try {
49+
const response = await fetch(
50+
`${API_BASE_URL}/streams?user=${session!.publicKey}`,
51+
{ signal: controller.signal }
52+
);
53+
54+
if (!response.ok) {
55+
throw new Error("Failed to fetch streams");
56+
}
57+
58+
const data = await response.json();
59+
const streamList = Array.isArray(data) ? data : data.data ?? [];
60+
61+
// Map API response to our Stream type
62+
const mappedStreams: Stream[] = streamList.map((s: Record<string, unknown>) => ({
63+
id: s.id as string,
64+
streamId: s.streamId as number,
65+
sender: s.sender as string,
66+
recipient: s.recipient as string,
67+
tokenSymbol: s.tokenSymbol || "USDC",
68+
ratePerSecond: Number(s.ratePerSecond) || 0,
69+
depositedAmount: (s.depositedAmount as string) || "0",
70+
withdrawnAmount: (s.withdrawnAmount as string) || "0",
71+
startTime: s.startTime as number,
72+
endTime: s.endTime as number | undefined,
73+
isActive: s.isActive as boolean,
74+
isPaused: s.isPaused as boolean,
75+
status: (s.status as string) || "unknown",
76+
}));
77+
78+
setStreams(mappedStreams);
79+
setError(null);
80+
} catch (err) {
81+
if (err instanceof Error && err.name === "AbortError") return;
82+
logger.error("Failed to fetch streams:", err);
83+
setError(err instanceof Error ? err.message : "Failed to load streams");
84+
} finally {
85+
setLoading(false);
86+
}
87+
})();
9388

9489
return () => controller.abort();
95-
}, [isHydrated, session?.publicKey, fetchStreams]);
90+
}, [isHydrated, session?.publicKey]);
9691

9792
// Get unique tokens from streams
9893
const uniqueTokens = React.useMemo(() => {

package-lock.json

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)