fix(scripts): recover group folder for already-unregistered rooms
When a room was unregistered first (room_settings row already gone), the folder was unknown, so sessions rows and the on-disk group/workspace/session/ ipc folders (and any git worktree) were silently skipped — leaving orphans. Back-trace the folder from the group_folder recorded on the chat's leftover paired_tasks/work_items/scheduled_tasks/service_handoffs/paired_projects rows so folder-scoped cleanup still runs. Targets now carry a folder list. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -60,21 +60,45 @@ const db = new Database(path.join(STORE_DIR, 'messages.db'));
|
||||
|
||||
interface Target {
|
||||
jid: string;
|
||||
folder: string | null;
|
||||
folders: string[];
|
||||
isMain: boolean;
|
||||
name: string | null;
|
||||
registered: boolean;
|
||||
}
|
||||
|
||||
// When a room was already unregistered (room_settings gone) the group folder is
|
||||
// no longer stored there, so recover it from the group_folder recorded on the
|
||||
// chat's leftover managed rows — otherwise sessions/disk/worktrees for an
|
||||
// already-unregistered room would be missed.
|
||||
function backtraceFolders(jid: string): string[] {
|
||||
const set = new Set<string>();
|
||||
for (const t of [
|
||||
'paired_tasks',
|
||||
'work_items',
|
||||
'scheduled_tasks',
|
||||
'service_handoffs',
|
||||
'paired_projects',
|
||||
]) {
|
||||
const rows = db
|
||||
.query(
|
||||
`SELECT DISTINCT group_folder FROM ${t} WHERE chat_jid=? AND group_folder IS NOT NULL`,
|
||||
)
|
||||
.all(jid) as Array<{ group_folder: string | null }>;
|
||||
for (const r of rows) if (r.group_folder) set.add(r.group_folder);
|
||||
}
|
||||
return [...set];
|
||||
}
|
||||
|
||||
const targets: Target[] = jids.map((jid) => {
|
||||
const r = db
|
||||
.query('SELECT folder, is_main, name FROM room_settings WHERE chat_jid=?')
|
||||
.get(jid) as
|
||||
| { folder: string | null; is_main: number | null; name: string | null }
|
||||
| undefined;
|
||||
const folders = r?.folder ? [r.folder] : backtraceFolders(jid);
|
||||
return {
|
||||
jid,
|
||||
folder: r?.folder ?? null,
|
||||
folders,
|
||||
isMain: r?.is_main === 1,
|
||||
name: r?.name ?? null,
|
||||
registered: Boolean(r),
|
||||
@@ -102,15 +126,16 @@ function folderShared(folder: string): boolean {
|
||||
const safeFolders = new Set<string>();
|
||||
const sharedFolders = new Set<string>();
|
||||
for (const t of targets) {
|
||||
if (!t.folder) continue;
|
||||
if (folderShared(t.folder)) sharedFolders.add(t.folder);
|
||||
else safeFolders.add(t.folder);
|
||||
for (const folder of t.folders) {
|
||||
if (folderShared(folder)) sharedFolders.add(folder);
|
||||
else safeFolders.add(folder);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('=== targets ===');
|
||||
for (const t of targets) {
|
||||
console.log(
|
||||
` ${t.jid} | name=${t.name ?? '(unregistered)'} | folder=${t.folder ?? '-'} | registered=${t.registered}${t.isMain ? ' | MAIN' : ''}`,
|
||||
` ${t.jid} | name=${t.name ?? '(unregistered)'} | folder=${t.folders.length ? t.folders.join(',') : '-'} | registered=${t.registered}${t.isMain ? ' | MAIN' : ''}`,
|
||||
);
|
||||
}
|
||||
if (sharedFolders.size) {
|
||||
|
||||
Reference in New Issue
Block a user