feat: extend data retention to files, tool calls, and shared links

Add expiredAt field and TTL indexes to file, toolCall, and share schemas.
Set expiredAt on tool calls, shared links, and file uploads when
retentionMode is "all" or chat is temporary.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Aron Gates 2026-04-03 12:13:03 +01:00
parent 30109e90b0
commit 48973752d3
No known key found for this signature in database
GPG key ID: 4F5BDD01E0CFE2A0
13 changed files with 101 additions and 17 deletions

View file

@ -180,10 +180,7 @@ export function createConversationMethods(
update.isTemporary = false;
}
if (
isTemporary ||
interfaceConfig?.retentionMode === RetentionMode.ALL
) {
if (isTemporary || interfaceConfig?.retentionMode === RetentionMode.ALL) {
try {
update.expiredAt = createTempChatExpirationDate(interfaceConfig);
} catch (err) {

View file

@ -92,10 +92,7 @@ export function createMessageMethods(mongoose: typeof import('mongoose')): Messa
messageId: params.newMessageId || params.messageId,
};
if (
isTemporary ||
interfaceConfig?.retentionMode === RetentionMode.ALL
) {
if (isTemporary || interfaceConfig?.retentionMode === RetentionMode.ALL) {
try {
update.expiredAt = createTempChatExpirationDate(interfaceConfig);
} catch (err) {

View file

@ -345,6 +345,7 @@ export function createShareMethods(mongoose: typeof import('mongoose')) {
user: string,
conversationId: string,
targetMessageId?: string,
expiredAt?: Date,
): Promise<t.CreateShareResult> {
if (!user || !conversationId) {
throw new ShareServiceError('Missing required parameters', 'INVALID_PARAMS');
@ -408,6 +409,7 @@ export function createShareMethods(mongoose: typeof import('mongoose')) {
title,
user,
...(targetMessageId && { targetMessageId }),
...(expiredAt && { expiredAt }),
});
return { shareId, conversationId };
@ -460,7 +462,11 @@ export function createShareMethods(mongoose: typeof import('mongoose')) {
/**
* Update a shared link with new messages
*/
async function updateSharedLink(user: string, shareId: string): Promise<t.UpdateShareResult> {
async function updateSharedLink(
user: string,
shareId: string,
expiredAt?: Date,
): Promise<t.UpdateShareResult> {
if (!user || !shareId) {
throw new ShareServiceError('Missing required parameters', 'INVALID_PARAMS');
}
@ -485,6 +491,7 @@ export function createShareMethods(mongoose: typeof import('mongoose')) {
messages: updatedMessages,
user,
shareId: newShareId,
...(expiredAt && { expiredAt }),
};
const updatedShare = (await SharedLink.findOneAndUpdate({ shareId, user }, update, {

View file

@ -82,12 +82,16 @@ const file: Schema<IMongoFile> = new Schema(
type: String,
index: true,
},
expiredAt: {
type: Date,
},
},
{
timestamps: true,
},
);
file.index({ expiredAt: 1 }, { expireAfterSeconds: 0 });
file.index({ createdAt: 1, updatedAt: 1 });
file.index(
{ filename: 1, conversationId: 1, context: 1, tenantId: 1 },

View file

@ -8,6 +8,7 @@ export interface ISharedLink extends Document {
shareId?: string;
targetMessageId?: string;
isPublic: boolean;
expiredAt?: Date;
createdAt?: Date;
updatedAt?: Date;
tenantId?: string;
@ -45,10 +46,14 @@ const shareSchema: Schema<ISharedLink> = new Schema(
type: String,
index: true,
},
expiredAt: {
type: Date,
},
},
{ timestamps: true },
);
shareSchema.index({ expiredAt: 1 }, { expireAfterSeconds: 0 });
shareSchema.index({ conversationId: 1, user: 1, targetMessageId: 1, tenantId: 1 });
export default shareSchema;

View file

@ -10,6 +10,7 @@ export interface IToolCallData extends Document {
attachments?: TAttachment[];
blockIndex?: number;
partIndex?: number;
expiredAt?: Date;
createdAt?: Date;
updatedAt?: Date;
tenantId?: string;
@ -50,10 +51,14 @@ const toolCallSchema: Schema<IToolCallData> = new Schema(
type: String,
index: true,
},
expiredAt: {
type: Date,
},
},
{ timestamps: true },
);
toolCallSchema.index({ expiredAt: 1 }, { expireAfterSeconds: 0 });
toolCallSchema.index({ messageId: 1, user: 1, tenantId: 1 });
toolCallSchema.index({ conversationId: 1, user: 1, tenantId: 1 });

View file

@ -23,6 +23,7 @@ export interface IMongoFile extends Omit<Document, 'model'> {
fileIdentifier?: string;
};
expiresAt?: Date;
expiredAt?: Date;
createdAt?: Date;
updatedAt?: Date;
tenantId?: string;

View file

@ -10,6 +10,7 @@ export interface ISharedLink {
shareId?: string;
targetMessageId?: string;
isPublic: boolean;
expiredAt?: Date;
createdAt?: Date;
updatedAt?: Date;
}