Problem
Emptying the Trash runs inside the request. purgeTrash loops over every soft-deleted document the requester owns (apps/hocuspocus.server/src/api/services/documents.service.ts:732-733).
Each pass calls a Supabase footprint RPC (apps/hocuspocus.server/src/api/services/documentPurge.service.ts:49), then deletes the editor media (apps/hocuspocus.server/src/api/services/documentPurge.service.ts:55).
So a person with a full Trash gets a timeout instead of an answer. They cannot tell how many documents were purged before the request died, and a retry starts over.
The fix is already written down in the code, at apps/hocuspocus.server/src/api/services/documents.service.ts:710-711:
Synchronous, so a huge trash times out: move the loop to the worker, never cap it with a bare take.
What to do
Enqueue the purge and answer 202 at once. Let the worker run the loop. Today the controller returns 200 with the count (apps/hocuspocus.server/src/api/controllers/documents.controller.ts:301).
The worker already owns a batched purge loop, reapSoftDeletedDocuments (apps/hocuspocus.server/src/hocuspocus.worker.ts:101). It calls the same primitive, purgeDocumentFootprint (apps/hocuspocus.server/src/hocuspocus.worker.ts:133). Follow that shape.
Do not add a take cap on the empty-all query. The comment above rules that out, because a cap silently leaves documents in the Trash. The ids path is a separate case, and it is already capped at 500 (apps/hocuspocus.server/src/schemas/document.schema.ts:56).
Acceptance
Notes
Two comments describe the current synchronous behaviour and must change with the fix:
apps/hocuspocus.server/src/schemas/document.schema.ts:51-54
apps/hocuspocus.server/src/api/services/documents.service.ts:708-711
The OpenAPI description also names the timeout (apps/hocuspocus.server/src/modules/openapi/domain/paths/documents.ts:230), and the operation declares only a 200 response (:235).
Problem
Emptying the Trash runs inside the request.
purgeTrashloops over every soft-deleted document the requester owns (apps/hocuspocus.server/src/api/services/documents.service.ts:732-733).Each pass calls a Supabase footprint RPC (
apps/hocuspocus.server/src/api/services/documentPurge.service.ts:49), then deletes the editor media (apps/hocuspocus.server/src/api/services/documentPurge.service.ts:55).So a person with a full Trash gets a timeout instead of an answer. They cannot tell how many documents were purged before the request died, and a retry starts over.
The fix is already written down in the code, at
apps/hocuspocus.server/src/api/services/documents.service.ts:710-711:What to do
Enqueue the purge and answer
202at once. Let the worker run the loop. Today the controller returns200with the count (apps/hocuspocus.server/src/api/controllers/documents.controller.ts:301).The worker already owns a batched purge loop,
reapSoftDeletedDocuments(apps/hocuspocus.server/src/hocuspocus.worker.ts:101). It calls the same primitive,purgeDocumentFootprint(apps/hocuspocus.server/src/hocuspocus.worker.ts:133). Follow that shape.Do not add a
takecap on the empty-all query. The comment above rules that out, because a cap silently leaves documents in the Trash. Theidspath is a separate case, and it is already capped at 500 (apps/hocuspocus.server/src/schemas/document.schema.ts:56).Acceptance
202instead of timing out.takecap.Notes
Two comments describe the current synchronous behaviour and must change with the fix:
apps/hocuspocus.server/src/schemas/document.schema.ts:51-54apps/hocuspocus.server/src/api/services/documents.service.ts:708-711The OpenAPI description also names the timeout (
apps/hocuspocus.server/src/modules/openapi/domain/paths/documents.ts:230), and the operation declares only a200response (:235).