Andrew commited on
Commit
69e900d
·
1 Parent(s): f5bb818

Add persona usage check so deletions archive in-use personas

Browse files
src/routes/api/personas/[personaId]/usage/+server.ts ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { collections } from "$lib/server/database";
2
+ import { authCondition } from "$lib/server/auth";
3
+ import { z } from "zod";
4
+
5
+ export async function GET({ locals, params }) {
6
+ if (!locals.user && !locals.sessionId) {
7
+ return Response.json({ message: "Unauthorized" }, { status: 401 });
8
+ }
9
+
10
+ const personaId = z.string().min(1).parse(params.personaId);
11
+ const condition = authCondition(locals);
12
+
13
+ const settings = await collections.settings.findOne(
14
+ { ...condition, "personas.id": personaId },
15
+ { projection: { _id: 1 } }
16
+ );
17
+
18
+ if (!settings) {
19
+ return Response.json({ message: "Persona not found" }, { status: 404 });
20
+ }
21
+
22
+ const personaUsed = await collections.conversations.findOne(
23
+ {
24
+ ...condition,
25
+ $or: [
26
+ { personaId },
27
+ { branchedFromPersonaId: personaId },
28
+ { lockedPersonaId: personaId },
29
+ { "messages.personaResponses.personaId": personaId },
30
+ { "messages.personaResponses.children.personaId": personaId },
31
+ ],
32
+ },
33
+ { projection: { _id: 1 } }
34
+ );
35
+
36
+ return Response.json({ used: Boolean(personaUsed) });
37
+ }
src/routes/settings/(nav)/personas/[...persona]/+page.svelte CHANGED
@@ -58,7 +58,7 @@
58
  }
59
  }
60
 
61
- function deletePersona() {
62
  if (!selectedPersona) return;
63
 
64
  // Can't delete if it's locked
@@ -84,23 +84,42 @@
84
  `Are you sure you want to remove "${selectedPersona.name}"? Past responses will continue to show their persona details, but this persona will be hidden from future use.`
85
  )
86
  ) {
87
- const remainingPersona = $settings.personas.find(
88
- (persona) => !persona.archived && persona.id !== selectedPersona.id
89
- );
 
90
 
91
- $settings.personas = $settings.personas.map((persona) =>
92
- persona.id === selectedPersona.id
93
- ? { ...persona, archived: true, updatedAt: new Date() }
94
- : persona
95
- );
96
 
97
- const filteredActive = $settings.activePersonas.filter((id) => id !== selectedPersona.id);
98
- if (filteredActive.length !== $settings.activePersonas.length) {
99
- void settings.instantSet({ activePersonas: filteredActive });
100
- }
 
 
 
 
 
 
 
 
 
 
 
101
 
102
- const targetId = remainingPersona?.id ?? $settings.personas.find((p) => !p.archived)?.id ?? "";
103
- goto(`${base}/settings/personas/${targetId}`);
 
 
 
 
 
 
 
 
104
  }
105
  }
106
 
 
58
  }
59
  }
60
 
61
+ async function deletePersona() {
62
  if (!selectedPersona) return;
63
 
64
  // Can't delete if it's locked
 
84
  `Are you sure you want to remove "${selectedPersona.name}"? Past responses will continue to show their persona details, but this persona will be hidden from future use.`
85
  )
86
  ) {
87
+ try {
88
+ const usageResponse = await fetch(
89
+ `${base}/api/personas/${selectedPersona.id}/usage`
90
+ );
91
 
92
+ if (!usageResponse.ok) {
93
+ alert("Unable to delete persona right now. Please try again later.");
94
+ return;
95
+ }
 
96
 
97
+ const { used } = (await usageResponse.json()) as { used: boolean };
98
+ const now = new Date();
99
+ const filteredActive = $settings.activePersonas.filter((id) => id !== selectedPersona.id);
100
+ const updatedPersonas = used
101
+ ? $settings.personas.map((persona) =>
102
+ persona.id === selectedPersona.id
103
+ ? { ...persona, archived: true, updatedAt: now }
104
+ : persona
105
+ )
106
+ : $settings.personas.filter((persona) => persona.id !== selectedPersona.id);
107
+
108
+ await settings.instantSet({
109
+ personas: updatedPersonas,
110
+ activePersonas: filteredActive,
111
+ });
112
 
113
+ const nextCandidate = updatedPersonas.find(
114
+ (persona) => !persona.archived && persona.id !== selectedPersona.id
115
+ );
116
+ const fallbackPersona = updatedPersonas.find((persona) => !persona.archived)?.id ?? "";
117
+ const targetId = nextCandidate?.id ?? fallbackPersona;
118
+ goto(`${base}/settings/personas/${targetId}`);
119
+ } catch (error) {
120
+ console.error("Failed to delete persona", error);
121
+ alert("Unable to delete persona right now. Please try again later.");
122
+ }
123
  }
124
  }
125