feat(server): impl doc gc (#15282)

#### PR Dependency Tree


* **PR #15282** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added automated document cleanup to reconcile missing workspace docs,
delete related stored data, and recover if the doc returns.
* Added effect-based follow-up reconciliation for search indexing,
Copilot embeddings, and comment attachment cleanup with explicit
acknowledgements.
* **Bug Fixes**
* Deleted-document references now persist as dangling references rather
than disappearing.
* Improved document deletion flow to enforce permissions and ensure
authorized deletions succeed.
* **Tests**
* Expanded coverage for cleanup recovery, indexing/embedding
reconciliation, permissions, and reference semantics.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
DarkSky
2026-07-20 15:29:23 +08:00
committed by GitHub
parent 81df4751a3
commit bb55d6fd21
30 changed files with 2657 additions and 337 deletions
@@ -1,5 +1,6 @@
import { LinkExtension } from '@blocksuite/affine-inline-link';
import { textKeymap } from '@blocksuite/affine-inline-preset';
import type { AffineReference } from '@blocksuite/affine-inline-reference';
import type {
ListBlockModel,
ParagraphBlockModel,
@@ -312,6 +313,16 @@ describe('hotkey/bracket/linked-page', () => {
const richText = getRichTextByBlockId(paragraphId);
expect(richText.querySelectorAll('affine-reference').length).toBe(2);
expect(richText.inlineEditor.yTextString.length).toBe(2);
collection.removeDoc(linkedDoc.id);
await wait();
expect(collection.docs.has(linkedDoc.id)).toBe(false);
const danglingReferences =
richText.querySelectorAll<AffineReference>('affine-reference');
expect(danglingReferences.length).toBe(2);
expect([...danglingReferences].every(reference => !reference.refMeta)).toBe(
true
);
});
});