Add deletedAt timestamps to delete operations for better audit tracking
- Updated delete methods across hooks and components to include `deletedAt: System.timeStampInSeconds()`. - Refactored synchronized delete logic to pass `deletedAt` for both offline and online states. - Improved synchronization workflows to include `deletedAt` in server and IPC requests. - Enhanced destructuring patterns for cleaner and more consistent request data.
This commit is contained in:
78
app/page.tsx
78
app/page.tsx
@@ -1,5 +1,5 @@
|
||||
'use client';
|
||||
import {useContext, useEffect, useState} from 'react';
|
||||
import {useCallback, useContext, useEffect, useRef, useState} from 'react';
|
||||
import {BookContext} from "@/context/BookContext";
|
||||
import {ChapterProps} from "@/lib/models/Chapter";
|
||||
import {ChapterContext} from '@/context/ChapterContext';
|
||||
@@ -67,59 +67,57 @@ const messagesMap = {
|
||||
|
||||
function AutoSyncOnReconnect() {
|
||||
const {offlineMode} = useContext(OfflineContext);
|
||||
const {syncAllToServer: syncAllBooksToServer, refreshBooks, booksToSyncToServer} = useSyncBooks();
|
||||
const {syncAllToServer: syncAllSeriesToServer, refreshSeries, seriesToSyncToServer} = useSyncSeries();
|
||||
const [pendingSync, setPendingSync] = useState<boolean>(false);
|
||||
const [isRefreshing, setIsRefreshing] = useState<boolean>(false);
|
||||
const {session} = useContext(SessionContext);
|
||||
const {syncAllToServer: syncAllBooksToServer, syncAllFromServer: syncAllBooksFromServer, refreshBooks, booksToSyncToServer, booksToSyncFromServer} = useSyncBooks();
|
||||
const {syncAllToServer: syncAllSeriesToServer, syncAllFromServer: syncAllSeriesFromServer, refreshSeries, seriesToSyncToServer, seriesToSyncFromServer} = useSyncSeries();
|
||||
const isSyncingRef = useRef<boolean>(false);
|
||||
const hasRefreshedRef = useRef<boolean>(false);
|
||||
|
||||
const saveLastOnlineTimestamp = (): void => {
|
||||
const saveLastOnlineTimestamp = useCallback((): void => {
|
||||
const timestamp: number = Math.floor(Date.now() / 1000);
|
||||
localStorage.setItem('lastOnlineTimestamp', timestamp.toString());
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Refresh sync data when online + authenticated + DB ready
|
||||
useEffect((): void => {
|
||||
if (!offlineMode.isOffline) {
|
||||
setPendingSync(true);
|
||||
setIsRefreshing(true);
|
||||
Promise.all([refreshBooks(), refreshSeries()]).then(() => {
|
||||
setIsRefreshing(false);
|
||||
if (!offlineMode.isOffline && session.isConnected && offlineMode.isDatabaseInitialized) {
|
||||
hasRefreshedRef.current = true;
|
||||
Promise.all([refreshBooks(), refreshSeries()]);
|
||||
}
|
||||
}, [offlineMode.isOffline, session.isConnected, offlineMode.isDatabaseInitialized]);
|
||||
|
||||
// Auto-sync when diffs become available (reactive, no flags)
|
||||
useEffect((): void => {
|
||||
if (offlineMode.isOffline || !session.isConnected || isSyncingRef.current || !hasRefreshedRef.current) return;
|
||||
|
||||
const syncPromises: Promise<void>[] = [];
|
||||
|
||||
if (booksToSyncToServer.length > 0) syncPromises.push(syncAllBooksToServer());
|
||||
if (booksToSyncFromServer.length > 0) syncPromises.push(syncAllBooksFromServer());
|
||||
if (seriesToSyncToServer.length > 0) syncPromises.push(syncAllSeriesToServer());
|
||||
if (seriesToSyncFromServer.length > 0) syncPromises.push(syncAllSeriesFromServer());
|
||||
|
||||
if (syncPromises.length > 0) {
|
||||
isSyncingRef.current = true;
|
||||
Promise.all(syncPromises).then((): void => {
|
||||
saveLastOnlineTimestamp();
|
||||
isSyncingRef.current = false;
|
||||
}).catch((): void => {
|
||||
isSyncingRef.current = false;
|
||||
});
|
||||
}
|
||||
}, [offlineMode.isOffline]);
|
||||
|
||||
useEffect((): void => {
|
||||
if (pendingSync && !isRefreshing) {
|
||||
const syncPromises: Promise<void>[] = [];
|
||||
|
||||
if (booksToSyncToServer.length > 0) {
|
||||
syncPromises.push(syncAllBooksToServer());
|
||||
}
|
||||
if (seriesToSyncToServer.length > 0) {
|
||||
syncPromises.push(syncAllSeriesToServer());
|
||||
}
|
||||
|
||||
if (syncPromises.length > 0) {
|
||||
Promise.all(syncPromises).then(() => {
|
||||
saveLastOnlineTimestamp();
|
||||
});
|
||||
} else {
|
||||
saveLastOnlineTimestamp();
|
||||
}
|
||||
|
||||
setPendingSync(false);
|
||||
}
|
||||
}, [booksToSyncToServer, seriesToSyncToServer, pendingSync, isRefreshing]);
|
||||
}, [booksToSyncToServer, booksToSyncFromServer, seriesToSyncToServer, seriesToSyncFromServer]);
|
||||
|
||||
// Update lastOnlineTimestamp every 5 minutes while online
|
||||
useEffect((): (() => void) | void => {
|
||||
if (!offlineMode.isOffline) {
|
||||
if (!offlineMode.isOffline && session.isConnected) {
|
||||
const intervalId: NodeJS.Timeout = setInterval((): void => {
|
||||
saveLastOnlineTimestamp();
|
||||
}, 5 * 60 * 1000); // 5 minutes
|
||||
}, 5 * 60 * 1000);
|
||||
|
||||
return (): void => clearInterval(intervalId);
|
||||
}
|
||||
}, [offlineMode.isOffline]);
|
||||
}, [offlineMode.isOffline, session.isConnected, saveLastOnlineTimestamp]);
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -284,8 +282,6 @@ function ScribeContent() {
|
||||
|
||||
useEffect((): void => {
|
||||
if (session.isConnected) {
|
||||
refreshBooks().then()
|
||||
refreshSeries().then()
|
||||
setIsTermsAccepted(session.user?.termsAccepted ?? false);
|
||||
setHomeStepsGuide(User.guideTourDone(session.user?.guideTour ?? [], 'home-basic'));
|
||||
setIsLoading(false);
|
||||
|
||||
Reference in New Issue
Block a user