import { requireSession } from '@/lib/session' import { restoreAgent } from '@/lib/oauth' import { requireListScopes } from '@/lib/scope-gate' import { getListSubscriptionRkey, unsubscribeFromList, listBlockEvents, updateBlockEvent } from '@/lib/lexicon' export async function DELETE(request: Request) { let session: { did: string } try { session = await requireSession() } catch { return Response.json({ error: 'Not authenticated' }, { status: 401 }) } let body: { listUri: string } try { body = await request.json() } catch { return Response.json({ error: 'Invalid request body' }, { status: 400 }) } const { listUri } = body if (!listUri) { return Response.json({ error: 'listUri is required' }, { status: 400 }) } // Validate this list belongs to the session user const ownerDid = listUri.split('/')[2] if (ownerDid !== session.did) { return Response.json({ error: 'You can only delete your own lists' }, { status: 403 }) } const rkey = listUri.split('/').pop() if (!rkey) { return Response.json({ error: 'Invalid list URI' }, { status: 400 }) } try { const scopeGate = await requireListScopes(session.did) if (scopeGate) return scopeGate const agent = await restoreAgent(session.did) // Unsubscribe first if subscribed (best-effort) try { const subscriptionRkey = await getListSubscriptionRkey(agent, session.did, listUri) if (subscriptionRkey) { await unsubscribeFromList(agent, session.did, subscriptionRkey) } } catch { // Non-fatal — proceed with deletion even if unsubscribe fails } // Delete the list record itself await agent.com.atproto.repo.deleteRecord({ repo: session.did, collection: 'app.bsky.graph.list', rkey, }) // Listitem records are left orphaned (harmless without the list record) // Clear listUri from any block event that references this list, so the // event detail page doesn't show a broken link after deletion. try { const events = await listBlockEvents(agent, session.did) const matches = events.filter((e) => e.record.listUri === listUri) for (const match of matches) { await updateBlockEvent(agent, session.did, match.rkey, { ...match.record, listUri: undefined, }) } } catch { // Non-fatal — list is deleted, event reference cleanup is best-effort } return Response.json({ deleted: true }) } catch (err) { console.error('[api/list/delete]', err) return Response.json({ error: 'Failed to delete list' }, { status: 500 }) } }