- Implemented client-side validation functions for tax ID, VAT ID, IBAN, BIC, and website URL. - Added debug logging functionality to assist in development. - Created a comprehensive validation function for company form data. feat: initialize database with Prisma migrations - Added a server-side script to run Prisma migrations and check database health. - Ensured safe initialization of the database to prevent concurrent migrations. feat: comprehensive server-side error logging - Developed an error logging system that captures detailed error context, including request details and stack traces. - Implemented logging functions for different error types (route, action, database, API, startup). fix: validate user ID existence in audit logs - Updated the logging function to validate that the user ID exists in the database before logging actions. fix: update schemas for optional fields and validation - Modified schemas to allow for nullable fields and refined validation logic for tax ID, VAT ID, IBAN, and BIC. feat: enhance error boundary for better debugging - Improved error boundary to log detailed error information in development mode. - Added a debug panel to the main application layout for real-time error tracking. feat: implement company deletion functionality in admin routes - Added a new API route for deleting companies with appropriate logging. - Integrated delete confirmation in the admin interface for better user experience. fix: handle API errors gracefully - Wrapped API actions in try-catch blocks to log errors and return appropriate responses. feat: generate and save invoice PDFs - Implemented functionality to generate and save invoice PDFs upon status updates. - Added a new column in the database for storing the URL of the generated PDF. chore: update Docker image reference - Changed the Docker image reference to point to the new Git repository. chore: update package dependencies - Added @radix-ui/react-tooltip for enhanced UI components. - Updated package-lock.json to reflect new dependencies.
3.3 KiB
/**
- INTEGRATION EXAMPLE: How to use error logging in your existing routes
- This shows the new error-logger.server in real-world usage */
// Before (old code - minimal logging): /* export async function action({ request }: { request: Request }) { const user = await getApiUser(request); if (!user) return Response.json({ error: "Unauthorized" }, { status: 401 });
const body = await request.json(); const parsed = customerSchema.safeParse(body); if (!parsed.success) return Response.json({ error: parsed.error.issues }, { status: 400 });
try { const customer = await prisma.customer.create({ data: parsed.data }); await log({ userId: user.id, action: "CREATE_CUSTOMER", entity: "Customer", entityId: customer.id, request }); return Response.json(customer, { status: 201 }); } catch (error) { console.error(error); // ❌ Not helpful for debugging return Response.json({ error: "Internal server error" }, { status: 500 }); } } */
// After (with comprehensive error logging): import { getApiUser } from "@/session.server"; import prisma from "@/lib/prisma.server"; import { log } from "@/lib/logger.server"; import { logApiError } from "@/lib/error-logger.server"; import { customerSchema } from "@/lib/schemas";
export async function action({ request }: { request: Request }) { const user = await getApiUser(request); if (!user) return Response.json({ error: "Unauthorized" }, { status: 401 });
try { const body = await request.json(); const parsed = customerSchema.safeParse(body); if (!parsed.success) { return Response.json({ error: parsed.error.issues }, { status: 400 }); }
const customer = await prisma.customer.create({ data: parsed.data });
await log({
userId: user.id,
action: "CREATE_CUSTOMER",
entity: "Customer",
entityId: customer.id,
request,
});
return Response.json(customer, { status: 201 });
} catch (error) { // ✅ Now with full context: stack trace, request details, metadata logApiError(error, { request, endpoint: "/api/customers", userId: user.id, statusCode: 500, metadata: { method: request.method, }, }); return Response.json({ error: "Internal server error" }, { status: 500 }); } }
// ============================================================================ // WHAT YOU'LL SEE IN THE SERVER LOGS NOW: // ============================================================================
/*
[API_ERROR] | 2026-05-02T22:15:45.789Z | duplicate entry for unique field 'email' POST /api/customers | user: user-abc123 | ip: 192.168.1.100 | endpoint: /api/customers | statusCode: 500 Error: Customer with email 'john@example.com' already exists at Object.create (file:///app/lib/customer.server.ts:25:13) at action (file:///app/routes/api.customers.ts:30:7) at processRequest (file:///app/routes/_middleware.ts:12:3)
Metadata: { "method": "POST", "endpoint": "/api/customers" }
✓ You can now see:
- Exact error message with context
- HTTP method & endpoint
- User ID & IP address
- Stack trace for debugging
- Custom metadata
- Timestamp */