feat: add repository pattern, service layer architecture, and scheduler management

- Implement repository pattern for data access layer
- Add comprehensive service layer for business logic
- Create scheduler management system with health monitoring
- Add bounded buffer utility for memory management
- Enhance security audit logging with retention policies
This commit is contained in:
2025-07-12 07:00:37 +02:00
parent e1abedb148
commit 041a1cc3ef
54 changed files with 5755 additions and 878 deletions

View File

@ -32,19 +32,14 @@ function createDynamicComponent<T = object>(
options?: {
loading?: ComponentType;
ssr?: boolean;
suspense?: boolean;
}
) {
const {
loading: LoadingComponent = LoadingSpinner,
ssr = true,
suspense = false,
} = options || {};
const { loading: LoadingComponent = LoadingSpinner, ssr = true } =
options || {};
return dynamic(importFunc, {
loading: () => <LoadingComponent />,
ssr,
suspense,
});
}
@ -70,30 +65,33 @@ export const DynamicAreaChart = createDynamicComponent(
);
// D3 components for data visualization (also heavy)
export const DynamicWordCloud = createDynamicComponent(
() =>
import("../components/charts/WordCloud").then((mod) => ({
default: mod.WordCloud,
})),
{ loading: LoadingSkeleton, ssr: false }
);
// TODO: Create WordCloud component
// export const DynamicWordCloud = createDynamicComponent(
// () =>
// import("../components/charts/WordCloud").then((mod) => ({
// default: mod.WordCloud,
// })),
// { loading: LoadingSkeleton, ssr: false }
// );
export const DynamicTreeMap = createDynamicComponent(
() =>
import("../components/charts/TreeMap").then((mod) => ({
default: mod.TreeMap,
})),
{ loading: LoadingSkeleton, ssr: false }
);
// TODO: Create TreeMap component
// export const DynamicTreeMap = createDynamicComponent(
// () =>
// import("../components/charts/TreeMap").then((mod) => ({
// default: mod.TreeMap,
// })),
// { loading: LoadingSkeleton, ssr: false }
// );
// Map components (Leaflet is heavy)
export const DynamicLeafletMap = createDynamicComponent(
() =>
import("../components/maps/LeafletMap").then((mod) => ({
default: mod.LeafletMap,
})),
{ loading: LoadingSkeleton, ssr: false }
);
// TODO: Create LeafletMap component
// export const DynamicLeafletMap = createDynamicComponent(
// () =>
// import("../components/maps/LeafletMap").then((mod) => ({
// default: mod.LeafletMap,
// })),
// { loading: LoadingSkeleton, ssr: false }
// );
// Admin panels (only loaded for admin users)
export const DynamicAuditLogsPanel = createDynamicComponent(
@ -104,95 +102,107 @@ export const DynamicAuditLogsPanel = createDynamicComponent(
{ loading: LoadingSkeleton }
);
export const DynamicSecurityMonitoring = createDynamicComponent(
() =>
import("../components/admin/SecurityMonitoring").then((mod) => ({
default: mod.SecurityMonitoring,
})),
{ loading: LoadingSkeleton }
);
// TODO: Create SecurityMonitoring component
// export const DynamicSecurityMonitoring = createDynamicComponent(
// () =>
// import("../components/admin/SecurityMonitoring").then((mod) => ({
// default: mod.SecurityMonitoring,
// })),
// { loading: LoadingSkeleton }
// );
// CSV processing components (only loaded when needed)
export const DynamicCSVUploader = createDynamicComponent(
() =>
import("../components/csv/CSVUploader").then((mod) => ({
default: mod.CSVUploader,
})),
{ loading: LoadingSpinner }
);
// TODO: Create CSVUploader component
// export const DynamicCSVUploader = createDynamicComponent(
// () =>
// import("../components/csv/CSVUploader").then((mod) => ({
// default: mod.CSVUploader,
// })),
// { loading: LoadingSpinner }
// );
export const DynamicCSVProcessor = createDynamicComponent(
() =>
import("../components/csv/CSVProcessor").then((mod) => ({
default: mod.CSVProcessor,
})),
{ loading: LoadingSpinner }
);
// TODO: Create CSVProcessor component
// export const DynamicCSVProcessor = createDynamicComponent(
// () =>
// import("../components/csv/CSVProcessor").then((mod) => ({
// default: mod.CSVProcessor,
// })),
// { loading: LoadingSpinner }
// );
// Data table components (heavy when dealing with large datasets)
export const DynamicDataTable = createDynamicComponent(
() =>
import("../components/tables/DataTable").then((mod) => ({
default: mod.DataTable,
})),
{ loading: LoadingSkeleton }
);
// TODO: Create DataTable component
// export const DynamicDataTable = createDynamicComponent(
// () =>
// import("../components/tables/DataTable").then((mod) => ({
// default: mod.DataTable,
// })),
// { loading: LoadingSkeleton }
// );
// Modal components (can be heavy with complex forms)
export const DynamicUserInviteModal = createDynamicComponent(
() =>
import("../components/modals/UserInviteModal").then((mod) => ({
default: mod.UserInviteModal,
})),
{ loading: LoadingSpinner }
);
// TODO: Create UserInviteModal component
// export const DynamicUserInviteModal = createDynamicComponent(
// () =>
// import("../components/modals/UserInviteModal").then((mod) => ({
// default: mod.UserInviteModal,
// })),
// { loading: LoadingSpinner }
// );
export const DynamicCompanySettingsModal = createDynamicComponent(
() =>
import("../components/modals/CompanySettingsModal").then((mod) => ({
default: mod.CompanySettingsModal,
})),
{ loading: LoadingSpinner }
);
// TODO: Create CompanySettingsModal component
// export const DynamicCompanySettingsModal = createDynamicComponent(
// () =>
// import("../components/modals/CompanySettingsModal").then((mod) => ({
// default: mod.CompanySettingsModal,
// })),
// { loading: LoadingSpinner }
// );
// Text editor components (rich text editors are typically heavy)
export const DynamicRichTextEditor = createDynamicComponent(
() =>
import("../components/editor/RichTextEditor").then((mod) => ({
default: mod.RichTextEditor,
})),
{ loading: LoadingSpinner, ssr: false }
);
// TODO: Create RichTextEditor component
// export const DynamicRichTextEditor = createDynamicComponent(
// () =>
// import("../components/editor/RichTextEditor").then((mod) => ({
// default: mod.RichTextEditor,
// })),
// { loading: LoadingSpinner, ssr: false }
// );
// PDF viewers and generators (heavy libraries)
export const DynamicPDFViewer = createDynamicComponent(
() =>
import("../components/pdf/PDFViewer").then((mod) => ({
default: mod.PDFViewer,
})),
{ loading: LoadingSpinner, ssr: false }
);
// TODO: Create PDFViewer component
// export const DynamicPDFViewer = createDynamicComponent(
// () =>
// import("../components/pdf/PDFViewer").then((mod) => ({
// default: mod.PDFViewer,
// })),
// { loading: LoadingSpinner, ssr: false }
// );
// Animation libraries (Framer Motion, Lottie, etc.)
export const DynamicAnimatedComponent = createDynamicComponent(
() =>
import("../components/animations/AnimatedComponent").then((mod) => ({
default: mod.AnimatedComponent,
})),
{ loading: LoadingSpinner, ssr: false }
);
// TODO: Create AnimatedComponent
// export const DynamicAnimatedComponent = createDynamicComponent(
// () =>
// import("../components/animations/AnimatedComponent").then((mod) => ({
// default: mod.AnimatedComponent,
// })),
// { loading: LoadingSpinner, ssr: false }
// );
// React wrapper for React.lazy with Suspense
export function createLazyComponent<T = object>(
export function createLazyComponent<
T extends Record<string, any> = Record<string, any>,
>(
importFunc: () => Promise<{ default: ComponentType<T> }>,
_fallback: ComponentType = LoadingSpinner
fallback: ComponentType = LoadingSpinner
) {
const LazyComponent = lazy(importFunc);
const FallbackComponent = fallback;
return function WrappedComponent(props: T) {
return (
<Suspense fallback={<fallback />}>
<LazyComponent {...props} />
<Suspense fallback={<FallbackComponent />}>
<LazyComponent {...(props as T)} />
</Suspense>
);
};