Summary
Fixing #143 (PR #144) surfaced that the content collection can contain orphaned documents with no _type — and, in the observed cases, no _courseId or _parentId either. The _friendlyId backfill migration now skips and warns about them instead of crashing, but the documents themselves remain in the database, and there is currently no supported way to detect or remove them.
What these documents look like
Component-shaped stubs: fields such as instruction, title, displayTitle, body, _isOptional, _onScreen, _extensions, themeSettings are present, but _type, _component, _parentId and _courseId are all absent. Because nothing references them and they reference nothing, they cannot appear in any course tree or render anywhere — they are dead data.
Two things worth doing
-
Root cause — the shape suggests a non-atomic content create: a document is inserted, then a second step stamps _type/parent linkage, and if that second step fails the stub is left behind. Confirm whether the create path can leave a partially-written document, and if so make it atomic (or clean up on failure) so no new orphans are produced.
-
Detection / cleanup — provide a supported way to find and prune orphaned content documents (e.g. a maintenance command or a follow-up migration): documents with no _type, or documents that are neither course/config yet have no _courseId/_parentId. Report what would be removed before removing it.
Context
Summary
Fixing #143 (PR #144) surfaced that the
contentcollection can contain orphaned documents with no_type— and, in the observed cases, no_courseIdor_parentIdeither. The_friendlyIdbackfill migration now skips and warns about them instead of crashing, but the documents themselves remain in the database, and there is currently no supported way to detect or remove them.What these documents look like
Component-shaped stubs: fields such as
instruction,title,displayTitle,body,_isOptional,_onScreen,_extensions,themeSettingsare present, but_type,_component,_parentIdand_courseIdare all absent. Because nothing references them and they reference nothing, they cannot appear in any course tree or render anywhere — they are dead data.Two things worth doing
Root cause — the shape suggests a non-atomic content create: a document is inserted, then a second step stamps
_type/parent linkage, and if that second step fails the stub is left behind. Confirm whether the create path can leave a partially-written document, and if so make it atomic (or clean up on failure) so no new orphans are produced.Detection / cleanup — provide a supported way to find and prune orphaned content documents (e.g. a maintenance command or a follow-up migration): documents with no
_type, or documents that are neithercourse/configyet have no_courseId/_parentId. Report what would be removed before removing it.Context