feat: complete refactoring phase 1 with API, component, and business logic consolidation

Co-authored-by: cetinmustafa83 <30570791+cetinmustafa83@users.noreply.github.com>
This commit is contained in:
v0andcetinmustafa83 committed 2026-07-31 13:46:13 +00:00
1 parent 36a6206c3b
commit 8b33280c20
17 files changed
+3061 -1

No files matched your search

+151
View File
@@ -0,0 +1,151 @@
import { NextRequest, NextResponse } from 'next/server';
import { getSession } from '@/lib/auth';
import { logComplianceAudit } from '@/lib/audit';
import { successResponse, unauthorizedError, forbiddenError } from '@/lib/api-response';
export type RouteHandler = (
request: NextRequest,
context: any
) => Promise<NextResponse>;
export interface RouteConfig {
auth?: boolean; // Require authentication
roles?: string[]; // Required roles
audit?: boolean; // Log to audit trail
}
/**
* Middleware for authentication check
*/
export const withAuth = (handler: RouteHandler) => {
return async (request: NextRequest, context: any) => {
try {
const session = await getSession();
if (!session) {
return unauthorizedError(request.url);
}
// Attach user to request for use in handler
(request as any).user = session.user;
return handler(request, context);
} catch (error) {
console.error('[v0] Auth error:', error);
return unauthorizedError(request.url);
}
};
};
/**
* Middleware for role-based access control
*/
export const withRoles = (allowedRoles: string[]) => {
return (handler: RouteHandler) => {
return async (request: NextRequest, context: any) => {
const session = await getSession();
if (!session) {
return unauthorizedError(request.url);
}
const userRole = session.user?.role;
if (!allowedRoles.includes(userRole)) {
return forbiddenError(request.url);
}
(request as any).user = session.user;
return handler(request, context);
};
};
};
/**
* Middleware for audit logging
*/
export const withAudit = (action: string) => {
return (handler: RouteHandler) => {
return async (request: NextRequest, context: any) => {
const session = await getSession();
const user = session?.user;
const response = await handler(request, context);
// Log after handler completes
if (user) {
try {
await logComplianceAudit({
userId: user.id,
schoolId: user.schoolId,
action,
entityType: request.url.split('/').pop() || 'unknown',
metadata: {
method: request.method,
path: request.url,
timestamp: new Date().toISOString(),
},
});
} catch (error) {
console.error('[v0] Audit log error:', error);
}
}
return response;
};
};
};
/**
* Middleware for request validation
*/
export const withValidation = (schema: any) => {
return (handler: RouteHandler) => {
return async (request: NextRequest, context: any) => {
try {
if (request.method === 'GET' || request.method === 'DELETE') {
return handler(request, context);
}
const body = await request.json();
const validation = schema.safeParse(body);
if (!validation.success) {
return NextResponse.json(
{
success: false,
error: 'Validation error',
details: validation.error.errors,
},
{ status: 422 }
);
}
(request as any).validatedBody = validation.data;
return handler(request, context);
} catch (error) {
return NextResponse.json(
{ success: false, error: 'Invalid request body' },
{ status: 400 }
);
}
};
};
};
/**
* Combine multiple middleware
*/
export const withMiddleware =
(...middleware: Array<(h: RouteHandler) => RouteHandler>) =>
(handler: RouteHandler) => {
return middleware.reduceRight((fn, mw) => mw(fn), handler);
};
/**
* Example usage in a route:
*
* export const GET = withMiddleware(
* withAuth,
* withRoles(['TEACHER', 'ADMIN']),
* withAudit('GET_STUDENTS')
* )(async (request) => {
* const user = (request as any).user;
* // handler logic
* });
*/