Skip to content

Commit 9dbff71

Browse files
web3jenksclaude
andauthored
fix(chat): auto-expire chat sessions older than two months (#402) (#415)
Replace indefinite localStorage retention with a two-calendar-month expiry that matches the backend's data retention policy. Sessions are pruned on load. Also removes legacy migration code for the old babylon_ai_chat_history key and fixes a missing space in the token-limit error message. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a2d5c82 commit 9dbff71

1 file changed

Lines changed: 10 additions & 28 deletions

File tree

src/components/ChatWidget.tsx

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ interface ChatSession {
3838
}
3939

4040
const STORAGE_KEY = 'babylon_ai_chat_sessions';
41-
const OLD_STORAGE_KEY = 'babylon_ai_chat_history'; // For migration
4241
const CONSENT_KEY = 'babylon_ai_chat_consent';
4342

4443
const PRIVACY_CONSENT_TEXT =
@@ -77,38 +76,23 @@ export default function ChatWidget() {
7776
return false;
7877
});
7978

80-
// State for sessions
79+
// State for sessions (with two-calendar-month expiry to match backend retention policy)
8180
const [sessions, setSessions] = useState<ChatSession[]>(() => {
8281
if (typeof window !== 'undefined') {
83-
// Try new format first
8482
const savedSessions = localStorage.getItem(STORAGE_KEY);
8583
if (savedSessions) {
8684
try {
87-
return JSON.parse(savedSessions);
85+
const parsed: ChatSession[] = JSON.parse(savedSessions);
86+
// Prune sessions older than two calendar months
87+
const cutoff = new Date();
88+
cutoff.setMonth(cutoff.getMonth() - 2);
89+
const cutoffTs = cutoff.getTime();
90+
const fresh = parsed.filter(s => s.timestamp >= cutoffTs);
91+
if (fresh.length > 0) return fresh;
8892
} catch (e) {
8993
console.error('Failed to parse sessions', e);
9094
}
9195
}
92-
93-
// Migration: Check for old format
94-
const oldHistory = localStorage.getItem(OLD_STORAGE_KEY);
95-
if (oldHistory) {
96-
try {
97-
const messages = JSON.parse(oldHistory);
98-
if (Array.isArray(messages) && messages.length > 0) {
99-
const migratedSession: ChatSession = {
100-
id: Date.now().toString(),
101-
thread_uuid: generateUUID(), // Best effort migration
102-
title: 'Previous Chat',
103-
messages: messages,
104-
timestamp: Date.now()
105-
};
106-
return [migratedSession];
107-
}
108-
} catch (e) {
109-
console.error('Failed to migrate old history', e);
110-
}
111-
}
11296
}
11397
// Default initial session
11498
return [{
@@ -265,7 +249,7 @@ export default function ChatWidget() {
265249
if (value.trim()) {
266250
const estimatedTokens = estimateTokens(value);
267251
if (estimatedTokens > maxTokens) {
268-
setInputError(`Message too long (~${estimatedTokens}/${maxTokens} tokens).Please shorten your question.`);
252+
setInputError(`Message too long (~${estimatedTokens}/${maxTokens} tokens). Please shorten your question.`);
269253
} else if (estimatedTokens > maxTokens * 0.8) {
270254
setInputError(`Approaching limit (~${estimatedTokens}/${maxTokens} tokens)`);
271255
} else {
@@ -290,12 +274,10 @@ export default function ChatWidget() {
290274
scrollToBottom();
291275
}, [messages, isOpen, isExpanded, currentSessionId]);
292276

293-
// Persist sessions
277+
// Persist sessions (expired sessions pruned on load)
294278
useEffect(() => {
295279
if (typeof window !== 'undefined') {
296280
localStorage.setItem(STORAGE_KEY, JSON.stringify(sessions));
297-
// Clean up old key if exists
298-
localStorage.removeItem(OLD_STORAGE_KEY);
299281
}
300282
}, [sessions]);
301283

0 commit comments

Comments
 (0)