Skip to content

Commit 2ddbc56

Browse files
committed
Fix TypeScript build errors for strict type checking
- Add explicit types to reduce/map/filter callback parameters across multiple files to resolve implicit 'any' type errors - Export NotificationResult interface from notification-dispatcher.ts - Add type cast for CorrelationState status field to match union type - Replace 'any' types in field-correlation-engine.ts with proper Prisma-inferred types - Add local interfaces (RecentLog, etc.) for component type safety Files modified: - src/lib/correlation-engine.ts - src/lib/field-correlation-engine.ts - src/lib/notification-dispatcher.ts - src/app/(dashboard)/dashboard/page.tsx - src/app/(dashboard)/dashboard/channels/page.tsx - src/app/(dashboard)/dashboard/logs/page.tsx - src/app/(dashboard)/dashboard/webhooks/[id]/page.tsx - src/app/api/webhook/[uniqueUrl]/route.ts - src/components/rules/unified-rule-builder.tsx - src/components/rules/rule-builder.tsx
1 parent 5395517 commit 2ddbc56

File tree

11 files changed

+73
-30
lines changed

11 files changed

+73
-30
lines changed

src/app/(dashboard)/dashboard/channels/page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ export default function ChannelsPage() {
220220

221221
if (response.ok) {
222222
setChannels(
223-
channels.map((c) => (c.id === id ? { ...c, enabled } : c))
223+
channels.map((c: Channel) => (c.id === id ? { ...c, enabled } : c))
224224
);
225225
toast.success(`Channel ${enabled ? "enabled" : "disabled"}`);
226226
}
@@ -236,7 +236,7 @@ export default function ChannelsPage() {
236236
});
237237

238238
if (response.ok) {
239-
setChannels(channels.filter((c) => c.id !== id));
239+
setChannels(channels.filter((c: Channel) => c.id !== id));
240240
toast.success("Channel deleted successfully");
241241
}
242242
} catch {

src/app/(dashboard)/dashboard/logs/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ export default function LogsPage() {
234234
</TableRow>
235235
</TableHeader>
236236
<TableBody>
237-
{logs.map((log) => (
237+
{logs.map((log: WebhookLog) => (
238238
<TableRow key={log.id}>
239239
<TableCell className="font-mono text-sm">
240240
{new Date(log.timestamp).toLocaleString()}

src/app/(dashboard)/dashboard/page.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
44
import { Badge } from "@/components/ui/badge";
55
import { Webhook, Bell, ScrollText, CheckCircle, XCircle, AlertCircle } from "lucide-react";
66

7+
interface RecentLog {
8+
id: string;
9+
timestamp: Date;
10+
status: string;
11+
notificationSent: boolean;
12+
webhook: {
13+
name: string;
14+
};
15+
}
16+
717
async function getDashboardStats(userId: string) {
818
const [webhooks, channels, logsToday, recentLogs] = await Promise.all([
919
prisma.webhook.count({ where: { userId } }),
@@ -119,7 +129,7 @@ export default async function DashboardPage() {
119129
</p>
120130
) : (
121131
<div className="space-y-4">
122-
{stats.recentLogs.map((log) => (
132+
{stats.recentLogs.map((log: RecentLog) => (
123133
<div
124134
key={log.id}
125135
className="flex items-center justify-between border-b pb-4 last:border-0 last:pb-0"

src/app/(dashboard)/dashboard/webhooks/[id]/page.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ export default function WebhookDetailPage({
237237
prev
238238
? {
239239
...prev,
240-
rules: prev.rules.map((r) =>
240+
rules: prev.rules.map((r: Rule) =>
241241
r.id === ruleId ? { ...r, enabled } : r
242242
),
243243
}
@@ -259,7 +259,7 @@ export default function WebhookDetailPage({
259259
if (response.ok) {
260260
setWebhook((prev) =>
261261
prev
262-
? { ...prev, rules: prev.rules.filter((r) => r.id !== ruleId) }
262+
? { ...prev, rules: prev.rules.filter((r: Rule) => r.id !== ruleId) }
263263
: null
264264
);
265265
toast.success("Rule deleted successfully");
@@ -276,7 +276,7 @@ export default function WebhookDetailPage({
276276
});
277277

278278
if (response.ok) {
279-
setCorrelationRules((prev) => prev.filter((r) => r.id !== ruleId));
279+
setCorrelationRules((prev) => prev.filter((r: CorrelationRule) => r.id !== ruleId));
280280
toast.success("Correlation rule deleted successfully");
281281
}
282282
} catch {

src/app/api/webhook/[uniqueUrl]/route.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { NextRequest, NextResponse } from "next/server";
22
import { prisma } from "@/lib/prisma";
33
import { evaluateRule, isRuleDebounced, updateRuleLastTriggered, updateServerState } from "@/lib/rule-engine";
4-
import { dispatchNotifications } from "@/lib/notification-dispatcher";
4+
import { dispatchNotifications, NotificationResult } from "@/lib/notification-dispatcher";
55
import { processCorrelations } from "@/lib/correlation-engine";
66
import { processFieldCorrelations } from "@/lib/field-correlation-engine";
77
import { ConditionGroup, RuleAction } from "@/lib/validations/webhook";
@@ -119,7 +119,7 @@ export async function POST(request: NextRequest, { params }: RouteParams) {
119119
triggeredRules.push(rule.id);
120120

121121
// Check results
122-
const successfulNotifications = results.filter((r) => r.success);
122+
const successfulNotifications = results.filter((r: NotificationResult) => r.success);
123123
const ruleNotificationSent = successfulNotifications.length > 0;
124124

125125
if (ruleNotificationSent) {
@@ -129,7 +129,7 @@ export async function POST(request: NextRequest, { params }: RouteParams) {
129129
}
130130
} else {
131131
status = "failed";
132-
const ruleErrors = results.map((r) => r.error).filter(Boolean).join("; ");
132+
const ruleErrors = results.map((r: NotificationResult) => r.error).filter(Boolean).join("; ");
133133
errorMessage = errorMessage ? `${errorMessage}; ${ruleErrors}` : ruleErrors;
134134
}
135135

src/components/rules/rule-builder.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ export function RuleBuilder({
120120
setLogic(parsedConditions.logic);
121121
setConditions(
122122
parsedConditions.conditions.filter(
123-
(c): c is Condition => "field" in c
123+
(c: Condition | ConditionGroup): c is Condition => "field" in c
124124
)
125125
);
126126

@@ -170,7 +170,7 @@ export function RuleBuilder({
170170
return;
171171
}
172172

173-
const validConditions = conditions.filter((c) => c.field.trim());
173+
const validConditions = conditions.filter((c: Condition) => c.field.trim());
174174
if (validConditions.length === 0) {
175175
toast.error("At least one condition is required");
176176
return;

src/components/rules/unified-rule-builder.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ export function UnifiedRuleBuilder({
166166
setLogic(parsedConditions.logic);
167167
setConditions(
168168
parsedConditions.conditions.filter(
169-
(c): c is Condition => "field" in c
169+
(c: Condition | ConditionGroup): c is Condition => "field" in c
170170
)
171171
);
172172

@@ -187,7 +187,7 @@ export function UnifiedRuleBuilder({
187187
setLogic(parsedMatchConditions.logic);
188188
setConditions(
189189
parsedMatchConditions.conditions.filter(
190-
(c): c is Condition => "field" in c
190+
(c: Condition | ConditionGroup): c is Condition => "field" in c
191191
)
192192
);
193193

@@ -270,7 +270,7 @@ export function UnifiedRuleBuilder({
270270
return;
271271
}
272272

273-
const validConditions = conditions.filter((c) => c.field.trim());
273+
const validConditions = conditions.filter((c: Condition) => c.field.trim());
274274

275275
if (selectedChannels.length === 0) {
276276
toast.error("At least one notification channel is required");
@@ -711,15 +711,15 @@ export function UnifiedRuleBuilder({
711711
<CardContent className="space-y-4">
712712
<div className="space-y-2">
713713
<Label>Notification Channels</Label>
714-
{channels.filter((c) => c.enabled).length === 0 ? (
714+
{channels.filter((c: Channel) => c.enabled).length === 0 ? (
715715
<p className="text-sm text-muted-foreground">
716716
No channels configured. Add a channel first.
717717
</p>
718718
) : (
719719
<div className="flex flex-wrap gap-2">
720720
{channels
721-
.filter((c) => c.enabled)
722-
.map((channel) => (
721+
.filter((c: Channel) => c.enabled)
722+
.map((channel: Channel) => (
723723
<Badge
724724
key={channel.id}
725725
variant={
@@ -812,8 +812,8 @@ export function UnifiedRuleBuilder({
812812
<Label>Notification Channels</Label>
813813
<div className="flex flex-wrap gap-2">
814814
{channels
815-
.filter((c) => c.enabled)
816-
.map((channel) => (
815+
.filter((c: Channel) => c.enabled)
816+
.map((channel: Channel) => (
817817
<Badge
818818
key={channel.id}
819819
variant={

src/lib/correlation-engine.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,14 @@ async function processAsTargetWebhook(
125125
...rule,
126126
description: rule.description ?? undefined,
127127
timeoutActions: rule.timeoutActions ?? undefined,
128+
correlationStates: rule.correlationStates.map((s: typeof rule.correlationStates[number]) => ({
129+
...s,
130+
status: s.status as "waiting" | "completed" | "timeout",
131+
targetWebhookId: s.targetWebhookId ?? undefined,
132+
targetPayload: s.targetPayload ?? undefined,
133+
targetReceivedAt: s.targetReceivedAt ?? undefined,
134+
actionResult: s.actionResult ?? undefined,
135+
})),
128136
};
129137
await completeCorrelation(state.id, webhookId, payload, ruleConfig);
130138
}
@@ -280,14 +288,14 @@ export async function getCorrelationStats(webhookId: string) {
280288

281289
return {
282290
asSource: asSource.reduce(
283-
(acc, item) => {
291+
(acc: Record<string, number>, item: { status: string; _count: number }) => {
284292
acc[item.status] = item._count;
285293
return acc;
286294
},
287295
{} as Record<string, number>
288296
),
289297
asTarget: asTarget.reduce(
290-
(acc, item) => {
298+
(acc: Record<string, number>, item: { status: string; _count: number }) => {
291299
acc[item.status] = item._count;
292300
return acc;
293301
},

src/lib/field-correlation-engine.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import { prisma } from "@/lib/prisma";
99
import { evaluateConditionGroup } from "./rule-engine";
1010
import { dispatchNotifications } from "./notification-dispatcher";
1111

12+
// Type inferred from Prisma model
13+
type FieldCorrelationRule = NonNullable<Awaited<ReturnType<typeof prisma.fieldCorrelationRule.findFirst>>>;
14+
1215
/**
1316
* Process field correlations when a webhook receives data
1417
*/
@@ -77,7 +80,7 @@ export async function processFieldCorrelations(
7780
* Process a received value for a correlation rule
7881
*/
7982
async function processCorrelationValue(
80-
rule: any,
83+
rule: FieldCorrelationRule,
8184
fieldValue: string,
8285
payload: Record<string, unknown>,
8386
expectedValues: string[]
@@ -123,7 +126,7 @@ async function processCorrelationValue(
123126
}
124127
} else {
125128
// Create new correlation state
126-
const receivedValues: Record<string, any> = {
129+
const receivedValues: Record<string, Record<string, unknown>> = {
127130
[fieldValue]: payload,
128131
};
129132
const pendingValues = expectedValues.filter((v) => v !== fieldValue);
@@ -153,8 +156,8 @@ async function processCorrelationValue(
153156
*/
154157
async function completeCorrelation(
155158
stateId: string,
156-
rule: any,
157-
receivedValues: Record<string, any>
159+
rule: FieldCorrelationRule,
160+
receivedValues: Record<string, Record<string, unknown>>
158161
): Promise<void> {
159162
const state = await prisma.fieldCorrelationState.findUnique({
160163
where: { id: stateId },
@@ -287,15 +290,15 @@ async function cleanupExpiredStates(): Promise<void> {
287290
/**
288291
* Get nested value from object using dot notation
289292
*/
290-
function getNestedValue(obj: any, path: string): any {
293+
function getNestedValue(obj: Record<string, unknown>, path: string): unknown {
291294
const keys = path.split(".");
292-
let current = obj;
295+
let current: unknown = obj;
293296

294297
for (const key of keys) {
295298
if (current === null || current === undefined) {
296299
return undefined;
297300
}
298-
current = current[key];
301+
current = (current as Record<string, unknown>)[key];
299302
}
300303

301304
return current;

src/lib/notification-dispatcher.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { promisify } from "util";
66

77
const execAsync = promisify(exec);
88

9-
interface NotificationResult {
9+
export interface NotificationResult {
1010
channelId: string;
1111
channelName: string;
1212
success: boolean;

0 commit comments

Comments
 (0)