fix: clean up link, pixel, board rows on user/team deletion

deleteUser and deleteTeam left link/pixel/board rows (and their share rows)
in the database after the owner was removed. /q/<slug> and /p/<slug>
also kept serving deleted entries because the routes did not filter
deletedAt and Redis cached lookups for 24h.

- deleteUser: clean up link/pixel/board + shares for the deleted user.
  Cloud mode: soft-delete link/pixel, hard-delete board, only userId-owned.
  Non-cloud: hard-delete everything matching userId or owned teamIds.
- deleteTeam: same cleanup, scoped to teamId.
- /q and /p route handlers: filter deletedAt: null at the call sites
  (not in findLink/findPixel helpers, which would null-deref the
  permission checks at src/permissions/link.ts and pixel.ts).
- Post-transaction Redis invalidation mirrors deleteWebsite.
This commit is contained in:
Stanislaw committed 2026-05-07 03:37:22 +02:00
1 parent b5c4dbfa56
commit a57abbe039
4 files changed
+81 -4

No files matched your search

+2
View File
@@ -21,6 +21,7 @@ export async function GET(request: Request, { params }: { params: Promise<{ slug
return findPixel({
where: {
slug,
deletedAt: null,
},
});
},
@@ -34,6 +35,7 @@ export async function GET(request: Request, { params }: { params: Promise<{ slug
pixel = await findPixel({
where: {
slug,
deletedAt: null,
},
});
+2
View File
@@ -19,6 +19,7 @@ export async function GET(request: Request, { params }: { params: Promise<{ slug
return findLink({
where: {
slug,
deletedAt: null,
},
});
},
@@ -32,6 +33,7 @@ export async function GET(request: Request, { params }: { params: Promise<{ slug
link = await findLink({
where: {
slug,
deletedAt: null,
},
});