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,136 @@
|
||||
/**
|
||||
* Error Logging Usage Examples
|
||||
*
|
||||
* Use these patterns in your routes to get better error debugging
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// PATTERN 1: In a loader (data fetching)
|
||||
// ============================================================================
|
||||
|
||||
import { json, type LoaderFunction } from "react-router";
|
||||
import { logRouteError } from "@/lib/error-logger.server";
|
||||
import prisma from "@/lib/prisma.server";
|
||||
|
||||
export const loader: LoaderFunction = async ({ request, params }) => {
|
||||
try {
|
||||
const company = await prisma.company.findUnique({
|
||||
where: { id: params.id },
|
||||
});
|
||||
|
||||
if (!company) {
|
||||
throw new Error(`Company not found: ${params.id}`);
|
||||
}
|
||||
|
||||
return json({ company });
|
||||
} catch (error) {
|
||||
logRouteError(error, {
|
||||
request,
|
||||
route: request.url,
|
||||
userId: params.userId, // if available
|
||||
metadata: {
|
||||
companyId: params.id,
|
||||
},
|
||||
});
|
||||
throw error; // Re-throw to let React Router handle it
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// PATTERN 2: In an action (mutation/form submission)
|
||||
// ============================================================================
|
||||
|
||||
import { logActionError } from "@/lib/error-logger.server";
|
||||
|
||||
export const action: LoaderFunction = async ({ request, params }) => {
|
||||
try {
|
||||
const formData = await request.formData();
|
||||
const result = await prisma.company.update({
|
||||
where: { id: params.id },
|
||||
data: { name: formData.get("name") },
|
||||
});
|
||||
return json({ success: true, result });
|
||||
} catch (error) {
|
||||
logActionError(error, {
|
||||
request,
|
||||
action: "UPDATE_COMPANY",
|
||||
metadata: {
|
||||
companyId: params.id,
|
||||
method: request.method,
|
||||
},
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// PATTERN 3: In an API route (POST/PUT/DELETE)
|
||||
// ============================================================================
|
||||
|
||||
import { logApiError } from "@/lib/error-logger.server";
|
||||
|
||||
export const action: LoaderFunction = async ({ request }) => {
|
||||
try {
|
||||
const data = await request.json();
|
||||
|
||||
// Validate
|
||||
if (!data.name) {
|
||||
return json(
|
||||
{ error: "Name is required" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Process
|
||||
const result = await prisma.company.create({ data });
|
||||
return json({ success: true, result }, { status: 201 });
|
||||
} catch (error) {
|
||||
logApiError(error, {
|
||||
request,
|
||||
endpoint: "/api/companies",
|
||||
statusCode: 500,
|
||||
metadata: {
|
||||
method: request.method,
|
||||
},
|
||||
});
|
||||
return json(
|
||||
{ error: "Internal server error" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// PATTERN 4: Database operations with error context
|
||||
// ============================================================================
|
||||
|
||||
import { logDatabaseError } from "@/lib/error-logger.server";
|
||||
|
||||
async function fetchCompanyWithUsers(companyId: string) {
|
||||
try {
|
||||
return await prisma.company.findUnique({
|
||||
where: { id: companyId },
|
||||
include: { users: true },
|
||||
});
|
||||
} catch (error) {
|
||||
logDatabaseError(error, "company.findUnique", {
|
||||
metadata: { companyId },
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// OUTPUT EXAMPLE (Server Console)
|
||||
// ============================================================================
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
[ROUTE_ERROR] | 2026-05-02T22:10:30.123Z | Company not found | route: /companies/123 | GET /companies/123 | user: user-id-456
|
||||
Stack at Object.loader (file:///app/routes/companies.$id.tsx:12:13)
|
||||
at process._tickCallback (internal/timers.ts:203:26)
|
||||
Metadata: {
|
||||
"companyId": "123"
|
||||
}
|
||||
================================================================================
|
||||
*/
|
||||
Reference in New Issue
Block a user