implemented the history retention feature
### 1. __History Retention Configuration__ - __config.toml__: Added `[HISTORY]` section with `RETENTION_DAYS = 30` setting - __Backend Integration__: Updated configuration handling to support history retention - __API Endpoints__: Modified `/api/config` to read/write history retention settings ### 2. __User Interface__ - __Settings Page__: Added "History Settings" section with number input for retention days - __Real-time Updates__: Settings are saved to config.toml when changed - __Clear Documentation__: Explains that retention only applies when incognito mode is off ### 3. __Automatic History Cleanup__ - __Background Processing__: Cleanup runs automatically when new chats are created (non-incognito mode) - __Smart Logic__: Only deletes chats older than configured retention period - __Complete Cleanup__: Removes both chat records and associated messages - __Performance Optimized__: Non-blocking background execution ### 4. __Manual Cleanup API__ - __Endpoint__: `POST /api/cleanup-history` for manual cleanup triggers - __Utility Functions__: Reusable cleanup logic in dedicated utility file ### 5. __Docker Rebuild__ - __Container Rebuild__: Successfully rebuilt the Docker containers with new features - __Configuration Persistence__: config.toml changes are preserved in Docker volume - __Application Ready__: The application should now be accessible at [](http://localhost:3000)<http://localhost:3000> ## Key Features: 1. __Incognito Mode Integration__: History retention only applies when incognito mode is OFF 2. __Flexible Configuration__: 0 = keep forever, any positive number = days to retain 3. __Automatic Cleanup__: Runs in background when creating new chats 4. __Manual Control__: API endpoint for manual cleanup triggers 5. __Database Integrity__: Properly removes both chats and associated messages ## Testing the Feature: 1. __Access the Application__: Open [](http://localhost:3000)<http://localhost:3000> in your browser 2. __Configure Settings__: Go to Settings → History Settings → Set retention days 3. __Test Incognito Mode__: Toggle incognito mode on/off to see different behaviors 4. __Create Test Chats__: Create chats in both modes to verify functionality 5. __Manual Cleanup__: Use the `/api/cleanup-history` endpoint to test manual cleanup
This commit is contained in:
parent
26952ff6c8
commit
883e457009
6 changed files with 152 additions and 14 deletions
66
src/lib/utils/historyCleanup.ts
Normal file
66
src/lib/utils/historyCleanup.ts
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
import db from '@/lib/db';
|
||||
import { chats, messages } from '@/lib/db/schema';
|
||||
import { getHistoryRetentionDays } from '@/lib/config';
|
||||
import { lt, eq } from 'drizzle-orm';
|
||||
|
||||
export const cleanupOldHistory = async (): Promise<{ deletedChats: number; message: string }> => {
|
||||
try {
|
||||
const retentionDays = getHistoryRetentionDays();
|
||||
|
||||
// If retention is 0, keep forever
|
||||
if (retentionDays === 0) {
|
||||
return { deletedChats: 0, message: 'History retention disabled, keeping all chats' };
|
||||
}
|
||||
|
||||
// Calculate cutoff date
|
||||
const cutoffDate = new Date();
|
||||
cutoffDate.setDate(cutoffDate.getDate() - retentionDays);
|
||||
const cutoffDateString = cutoffDate.toISOString();
|
||||
|
||||
// Find chats older than retention period
|
||||
const oldChats = await db
|
||||
.select({ id: chats.id })
|
||||
.from(chats)
|
||||
.where(lt(chats.createdAt, cutoffDateString));
|
||||
|
||||
if (oldChats.length === 0) {
|
||||
return { deletedChats: 0, message: 'No old chats to clean up' };
|
||||
}
|
||||
|
||||
const chatIds = oldChats.map((chat: { id: string }) => chat.id);
|
||||
|
||||
// Delete messages for old chats
|
||||
for (const chatId of chatIds) {
|
||||
await db.delete(messages).where(eq(messages.chatId, chatId));
|
||||
}
|
||||
|
||||
// Delete old chats
|
||||
await db.delete(chats).where(lt(chats.createdAt, cutoffDateString));
|
||||
|
||||
return {
|
||||
deletedChats: oldChats.length,
|
||||
message: `Cleaned up ${oldChats.length} old chats and their messages`
|
||||
};
|
||||
|
||||
} catch (err) {
|
||||
console.error('An error occurred while cleaning up history:', err);
|
||||
throw new Error('Failed to cleanup history');
|
||||
}
|
||||
};
|
||||
|
||||
// Function to check if cleanup should run (run cleanup every 24 hours)
|
||||
export const shouldRunCleanup = (): boolean => {
|
||||
const lastCleanup = localStorage.getItem('lastHistoryCleanup');
|
||||
if (!lastCleanup) return true;
|
||||
|
||||
const lastCleanupTime = new Date(lastCleanup);
|
||||
const now = new Date();
|
||||
const hoursSinceLastCleanup = (now.getTime() - lastCleanupTime.getTime()) / (1000 * 60 * 60);
|
||||
|
||||
return hoursSinceLastCleanup >= 24;
|
||||
};
|
||||
|
||||
// Function to mark cleanup as completed
|
||||
export const markCleanupCompleted = (): void => {
|
||||
localStorage.setItem('lastHistoryCleanup', new Date().toISOString());
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue