feat: add client-side validation utilities and debugging tools
Build and Push Docker Image / build (push) Successful in 1m23s
Build and Push Docker Image / build (push) Successful in 1m23s
- 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.
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
Reference in New Issue
Block a user