| 71 | } |
| 72 | |
| 73 | async list(q: { |
| 74 | userKey: string; |
| 75 | limit?: number; |
| 76 | platforms?: string[]; |
| 77 | threadId?: string; |
| 78 | roles?: ("user" | "assistant")[]; |
| 79 | }): Promise<TranscriptEntry[]> { |
| 80 | let items = await this.state.list.range<TranscriptEntry>(keyFor(q.userKey)); |
| 81 | if (this.retentionMs !== undefined) { |
| 82 | const cutoff = Date.now() - this.retentionMs; |
| 83 | items = items.filter((e) => e.ts >= cutoff); |
| 84 | } |
| 85 | if (q.platforms) |
| 86 | items = items.filter((e) => q.platforms!.includes(e.platform)); |
| 87 | if (q.threadId) items = items.filter((e) => e.threadId === q.threadId); |
| 88 | if (q.roles) items = items.filter((e) => q.roles!.includes(e.role)); |
| 89 | if (q.limit !== undefined) items = items.slice(-q.limit); |
| 90 | return items; // oldest-first |
| 91 | } |
| 92 | |
| 93 | async delete(q: { userKey: string }): Promise<{ deleted: number }> { |
| 94 | const n = (await this.state.list.range(keyFor(q.userKey))).length; |