Skip to content
5 changes: 5 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,8 @@ src/services/
src/types/
src/utils/virtualBackgroundUtils.ts
src/workers/
**/*.test.ts
**/*.test.tsx
**/*.spec.ts
**/*.spec.tsx
scripts/
5 changes: 3 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-unsafe-function-type": "warn",
"@typescript-eslint/no-unused-expressions": "warn",
"prettier/prettier": ["error", { "endOfLine": "auto" }]
"prettier/prettier": ["error", { "endOfLine": "auto" }],
"no-console": "error"
}
}
}
5 changes: 4 additions & 1 deletion src/app/api/auth/discord/callback/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { withRateLimit } from '@/lib/ratelimit';
import { exchangeCodeForToken, getDiscordUser, getDiscordAvatarUrl } from '@/lib/discord/oauth';
import type { AuthResponseDTO, AuthErrorDTO } from '@/types/api/auth.dto';
import { edgeLog } from '@/../infra/edge-config';
import { createLogger } from '@/lib/logging';

const logger = createLogger('api-auth-discord-callback');

export const runtime = 'edge';

Expand Down Expand Up @@ -103,7 +106,7 @@ export async function GET(
return addHeaders(response) as NextResponse;
} catch (error) {
edgeLog('error', '/api/auth/discord/callback', `Error: ${error}`);
console.error('Discord OAuth callback error:', error);
logger.error('Discord OAuth callback error', { error });

return addHeaders(
NextResponse.json({ message: 'Internal server error' }, { status: 500 }),
Expand Down
5 changes: 4 additions & 1 deletion src/app/api/auth/login/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { LoginRequestSchema } from '@/types/api/auth.dto';
import type { AuthResponseDTO, AuthErrorDTO } from '@/types/api/auth.dto';
import { edgeLog } from '@/../infra/edge-config';
import { getVerificationStatus } from '@/lib/auth/email-verification';
import { createLogger } from '@/lib/logging';

const logger = createLogger('api-auth-login');

export const runtime = 'nodejs';

Expand Down Expand Up @@ -73,7 +76,7 @@ export async function POST(

return addHeaders(NextResponse.json({ message: 'Invalid email or password' }, { status: 401 }));
} catch (error) {
console.error('Login error:', error);
logger.error('Login error', { error });

return addHeaders(NextResponse.json({ message: 'Internal server error' }, { status: 500 }));
}
Expand Down
5 changes: 4 additions & 1 deletion src/app/api/exports/history/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

import { NextRequest, NextResponse } from 'next/server';
import { getHistoryByUser } from '@/lib/export-scheduler';
import { createLogger } from '@/lib/logging';

const logger = createLogger('api-exports-history');

// Mock user ID - in production, get from auth session
const getCurrentUserId = (): string => 'user-123';
Expand All @@ -19,7 +22,7 @@ export async function GET(request: NextRequest) {

return NextResponse.json({ history });
} catch (error) {
console.error('Error fetching history:', error);
logger.error('Error fetching history', { error });
return NextResponse.json({ error: 'Failed to fetch history' }, { status: 500 });
}
}
9 changes: 6 additions & 3 deletions src/app/api/exports/schedules/[id]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import {
deleteSchedule,
UpdateScheduleInput,
} from '@/lib/export-scheduler';
import { createLogger } from '@/lib/logging';

const logger = createLogger('api-exports-schedules-id');

export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
try {
Expand All @@ -24,7 +27,7 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{

return NextResponse.json({ schedule });
} catch (error) {
console.error('Error fetching schedule:', error);
logger.error('Error fetching schedule', { error });
return NextResponse.json({ error: 'Failed to fetch schedule' }, { status: 500 });
}
}
Expand All @@ -51,7 +54,7 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise<

return NextResponse.json({ schedule });
} catch (error) {
console.error('Error updating schedule:', error);
logger.error('Error updating schedule', { error });
return NextResponse.json({ error: 'Failed to update schedule' }, { status: 500 });
}
}
Expand All @@ -66,7 +69,7 @@ export async function DELETE(

return NextResponse.json({ success: true });
} catch (error) {
console.error('Error deleting schedule:', error);
logger.error('Error deleting schedule', { error });
return NextResponse.json({ error: 'Failed to delete schedule' }, { status: 500 });
}
}
7 changes: 5 additions & 2 deletions src/app/api/exports/schedules/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import {
frequencyToCron,
validateCronExpression,
} from '@/lib/export-scheduler';
import { createLogger } from '@/lib/logging';

const logger = createLogger('api-exports-schedules');

// Mock user ID - in production, get from auth session
const getCurrentUserId = (): string => 'user-123';
Expand All @@ -24,7 +27,7 @@ export async function GET(request: NextRequest) {

return NextResponse.json({ schedules });
} catch (error) {
console.error('Error fetching schedules:', error);
logger.error('Error fetching schedules', { error });
return NextResponse.json({ error: 'Failed to fetch schedules' }, { status: 500 });
}
}
Expand Down Expand Up @@ -54,7 +57,7 @@ export async function POST(request: NextRequest) {

return NextResponse.json({ schedule }, { status: 201 });
} catch (error) {
console.error('Error creating schedule:', error);
logger.error('Error creating schedule', { error });
return NextResponse.json({ error: 'Failed to create schedule' }, { status: 500 });
}
}
9 changes: 6 additions & 3 deletions src/app/api/exports/templates/[id]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

import { NextRequest, NextResponse } from 'next/server';
import { getTemplate, updateTemplate, deleteTemplate } from '@/lib/export-scheduler';
import { createLogger } from '@/lib/logging';

const logger = createLogger('api-exports-templates-id');

export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
try {
Expand All @@ -19,7 +22,7 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{

return NextResponse.json({ template });
} catch (error) {
console.error('Error fetching template:', error);
logger.error('Error fetching template', { error });
return NextResponse.json({ error: 'Failed to fetch template' }, { status: 500 });
}
}
Expand All @@ -37,7 +40,7 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise<

return NextResponse.json({ template });
} catch (error) {
console.error('Error updating template:', error);
logger.error('Error updating template', { error });
return NextResponse.json({ error: 'Failed to update template' }, { status: 500 });
}
}
Expand All @@ -52,7 +55,7 @@ export async function DELETE(

return NextResponse.json({ success: true });
} catch (error) {
console.error('Error deleting template:', error);
logger.error('Error deleting template', { error });
return NextResponse.json({ error: 'Failed to delete template' }, { status: 500 });
}
}
7 changes: 5 additions & 2 deletions src/app/api/exports/templates/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

import { NextRequest, NextResponse } from 'next/server';
import { createTemplate, getTemplatesByUser, CreateTemplateInput } from '@/lib/export-scheduler';
import { createLogger } from '@/lib/logging';

const logger = createLogger('api-exports-templates');

// Mock user ID - in production, get from auth session
const getCurrentUserId = (): string => 'user-123';
Expand All @@ -17,7 +20,7 @@ export async function GET(request: NextRequest) {

return NextResponse.json({ templates });
} catch (error) {
console.error('Error fetching templates:', error);
logger.error('Error fetching templates', { error });
return NextResponse.json({ error: 'Failed to fetch templates' }, { status: 500 });
}
}
Expand All @@ -40,7 +43,7 @@ export async function POST(request: NextRequest) {

return NextResponse.json({ template }, { status: 201 });
} catch (error) {
console.error('Error creating template:', error);
logger.error('Error creating template', { error });
return NextResponse.json({ error: 'Failed to create template' }, { status: 500 });
}
}
5 changes: 4 additions & 1 deletion src/app/api/generate-pdf/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { NextRequest, NextResponse } from 'next/server';
import { generatePDF } from '../../../services/pdf-generation';
import { generateReportHTML, ReportData } from '../../../lib/pdf/templates';
import { createLogger } from '@/lib/logging';

const logger = createLogger('api-generate-pdf');

export async function POST(request: NextRequest) {
try {
Expand All @@ -22,7 +25,7 @@ export async function POST(request: NextRequest) {
},
});
} catch (error) {
console.error('Error generating PDF:', error);
logger.error('Error generating PDF', { error });
return NextResponse.json({ error: 'Failed to generate PDF' }, { status: 500 });
}
}
5 changes: 4 additions & 1 deletion src/app/api/notarization/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { NextRequest, NextResponse } from 'next/server';
import { saveTipNotarization } from '@/services/notarizationStore';
import { createLogger } from '@/lib/logging';

const logger = createLogger('api-notarization');

interface NotarizationPayload {
txHash: string;
Expand Down Expand Up @@ -36,7 +39,7 @@ export async function POST(request: NextRequest) {

return NextResponse.json(record, { status: 201 });
} catch (error) {
console.error('[Notarization API] Error creating notarization:', error);
logger.error('Error creating notarization', { error });
return NextResponse.json({ message: 'Failed to create notarization' }, { status: 500 });
}
}
5 changes: 4 additions & 1 deletion src/app/api/performance/db-metrics/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { NextResponse } from 'next/server';
import { dbPool } from '@/lib/db/pool';
import { createLogger } from '@/lib/logging';

const logger = createLogger('api-performance-db-metrics');

/**
* API endpoint to expose database connection pool metrics
Expand Down Expand Up @@ -35,7 +38,7 @@ export async function GET() {
],
});
} catch (error) {
console.error('Failed to fetch DB metrics:', error);
logger.error('Failed to fetch DB metrics', { error });
return NextResponse.json(
{ success: false, message: 'Failed to fetch database metrics' },
{ status: 500 },
Expand Down
13 changes: 8 additions & 5 deletions src/app/api/performance/vitals/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { NextRequest, NextResponse } from 'next/server';
import { z } from 'zod';
import { edgeLog } from '@/../infra/edge-config';
import { query } from '@/lib/db/pool';
import { createLogger } from '@/lib/logging';

const logger = createLogger('api-performance-vitals');
import { requireAuth } from '@/lib/authMiddleware';

export const runtime = 'nodejs';
Expand Down Expand Up @@ -54,7 +57,7 @@ async function checkPoorRate(name: string): Promise<void> {

const poorPct = (row.poor_count / row.total) * 100;
if (poorPct > POOR_ALERT_THRESHOLD_PCT) {
console.warn(
logger.warn(
`[PERFORMANCE ALERT] "${name}" poor-rate ${poorPct.toFixed(
1,
)}% exceeds ${POOR_ALERT_THRESHOLD_PCT}% threshold (${row.poor_count}/${
Expand Down Expand Up @@ -96,14 +99,14 @@ export async function POST(request: NextRequest) {
const insertedId = result.rows[0]?.id as string | undefined;

if (rating === 'poor') {
console.warn(
logger.warn(
`[PERFORMANCE ALERT] Critical degradation detected for ${name} on ${
url ?? '/'
}. Value: ${value}`,
);
await checkPoorRate(name);
} else if (rating === 'needs-improvement') {
console.info(
logger.info(
`[PERFORMANCE WARNING] ${name} needs improvement on ${url ?? '/'}. Value: ${value}`,
);
}
Expand All @@ -115,7 +118,7 @@ export async function POST(request: NextRequest) {
alertTriggered: rating === 'poor',
});
} catch (error) {
console.error('[Performance Analytics] Error processing metric:', error);
logger.error('[Performance Analytics] Error processing metric', { error });
return NextResponse.json({ success: false, message: 'Internal Server Error' }, { status: 500 });
}
}
Expand Down Expand Up @@ -152,7 +155,7 @@ export async function GET(request: NextRequest) {
range: range ?? '7d',
});
} catch (error) {
console.error('[Performance Analytics] Error fetching vitals:', error);
logger.error('[Performance Analytics] Error fetching vitals', { error });
return NextResponse.json(
{ success: false, message: 'Failed to fetch metrics' },
{ status: 500 },
Expand Down
11 changes: 8 additions & 3 deletions src/app/api/security/reporting/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { NextRequest, NextResponse } from 'next/server';
import { createLogger } from '@/lib/logging';

const logger = createLogger('api-security-reporting');

interface SecurityReportEnvelope {
type?: string;
Expand All @@ -18,9 +21,11 @@ export async function POST(request: NextRequest) {
const reports = normalizeReportBody(payload);

if (reports.length > 0) {
console.warn('[security-reporting] received violation reports', {
count: reports.length,
reports,
logger.warn('Received violation reports', {
context: {
count: reports.length,
reports,
},
});
}

Expand Down
5 changes: 4 additions & 1 deletion src/app/api/tipping/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { NextRequest, NextResponse } from 'next/server';
import { randomBytes } from 'crypto';
import { saveTipNotarization } from '@/services/notarizationStore';
import { createLogger } from '@/lib/logging';

const logger = createLogger('api-tipping');

interface TipRequestBody {
recipientId: string;
Expand Down Expand Up @@ -51,7 +54,7 @@ export async function POST(request: NextRequest) {

return NextResponse.json(response, { status: 201 });
} catch (error) {
console.error('[Tipping API] Failed to send tip:', error);
logger.error('Failed to send tip', { error });
return NextResponse.json({ message: 'Failed to process tipping request' }, { status: 500 });
}
}
13 changes: 12 additions & 1 deletion src/app/components/dashboard/DashboardGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
import dynamic from 'next/dynamic';
import { useDashboardWidgets } from '../../hooks/useDashboardWidgets';
import { EmptyState } from '@/components';
import { createLogger } from '@/lib/logging';

const logger = createLogger('DashboardGrid');

const ProgressSummaryWidget = dynamic(
() => import('./widgets/ProgressSummaryWidget').then((mod) => mod.ProgressSummaryWidget),
Expand Down Expand Up @@ -131,7 +134,7 @@
setWidgets(initialWidgets);
}
} catch (error) {
console.error('Error loading widget layout', error);
logger.error('Error loading widget layout', { error });
if (initialWidgets.length > 0) setWidgets(initialWidgets);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand All @@ -143,6 +146,14 @@
onWidgetChange?.(widgets);
}, [widgets, onWidgetChange]);

try {
saveWidgetLayout(widgets);
onWidgetChange?.(widgets);
} catch (error) {
logger.error('Error saving widget layout', { error });
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [widgets]); // Only depend on widgets, not the functions

Check failure on line 156 in src/app/components/dashboard/DashboardGrid.tsx

View workflow job for this annotation

GitHub Actions / Type Check, Lint & Validation

',' expected.
// Persist layout to localStorage at most once per 500ms via debounce
useEffect(() => {
if (widgets.length === 0) return;
Expand Down Expand Up @@ -564,4 +575,4 @@
</div>
</div>
);
};

Check failure on line 578 in src/app/components/dashboard/DashboardGrid.tsx

View workflow job for this annotation

GitHub Actions / Type Check, Lint & Validation

Declaration or statement expected.
Loading
Loading