b22e5baa5c
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.
69 lines
2.1 KiB
TypeScript
69 lines
2.1 KiB
TypeScript
import { startCleanupScheduler } from "./lib/cleanup.server";
|
|
import { initializeDatabase } from "./lib/db-init.server";
|
|
import { logStartupError, logError } from "./lib/error-logger.server";
|
|
import { PassThrough } from "node:stream";
|
|
import type { AppLoadContext, EntryContext } from "react-router";
|
|
import { createReadableStreamFromReadable } from "@react-router/node";
|
|
import { ServerRouter } from "react-router";
|
|
import { isbot } from "isbot";
|
|
import { renderToPipeableStream } from "react-dom/server";
|
|
|
|
startCleanupScheduler();
|
|
|
|
// Initialize database: run migrations on startup
|
|
initializeDatabase().catch((error) => {
|
|
logStartupError(error);
|
|
process.exit(1);
|
|
});
|
|
|
|
const ABORT_DELAY = 5_000;
|
|
|
|
export default function handleRequest(
|
|
request: Request,
|
|
responseStatusCode: number,
|
|
responseHeaders: Headers,
|
|
routerContext: EntryContext,
|
|
_loadContext: AppLoadContext
|
|
) {
|
|
return new Promise((resolve, reject) => {
|
|
let shellRendered = false;
|
|
const userAgent = request.headers.get("user-agent");
|
|
const readyCallback = isbot(userAgent ?? "") ? "onAllReady" : "onShellReady";
|
|
|
|
const { pipe, abort } = renderToPipeableStream(
|
|
<ServerRouter context={routerContext} url={request.url} abortDelay={ABORT_DELAY} />,
|
|
{
|
|
[readyCallback]() {
|
|
shellRendered = true;
|
|
const body = new PassThrough();
|
|
responseHeaders.set("Content-Type", "text/html");
|
|
resolve(
|
|
new Response(createReadableStreamFromReadable(body), {
|
|
headers: responseHeaders,
|
|
status: responseStatusCode,
|
|
})
|
|
);
|
|
pipe(body);
|
|
},
|
|
onShellError(error: unknown) {
|
|
logError("SHELL_ERROR", error, {
|
|
request,
|
|
route: new URL(request.url).pathname,
|
|
});
|
|
reject(error);
|
|
},
|
|
onError(error: unknown) {
|
|
responseStatusCode = 500;
|
|
if (shellRendered) {
|
|
logError("RENDER_ERROR", error, {
|
|
request,
|
|
route: new URL(request.url).pathname,
|
|
});
|
|
}
|
|
},
|
|
}
|
|
);
|
|
setTimeout(abort, ABORT_DELAY);
|
|
});
|
|
}
|