MemberJunction / MemberJunction/MJ

spDeleteEntityWithCoreDependencies covers ~18 of ~73 FK references to Entity — entity removal half-fails silently

Open
#3,546 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TSQL
Stars
29
Forks
6
Avg merge
2d 1h
Merged PRs (30d)
323

Description

## What

`spDeleteEntityWithCoreDependencies` is what CodeGen calls (via `checkAndRemoveMetadataForDeletedTables`, `packages/CodeGenLib/src/Database/manage-metadata.ts`) to prune an entity's metadata once its base table disappears. It cascades **~18** tables. The database currently has **~73** FK references to `Entity.ID`.

Anything not on the proc's list blocks the final `DELETE FROM Entity`, and the failure is caught and logged rather than raised:

```ts
catch (ex) {
logError(`Error removing metadata for entity ${(ex as any).Name}, error: ${ex}`);
}
```

## Why it matters

The entity is left **half-pruned** — the `Entity` row survives, but its `EntityField` rows are already gone. Every subsequent CodeGen run then emits:

```
SKIPPING SQL GENERATION: Entity has no primary key field in metadata.
```

...and that entity is silently excluded from generation from then on. The only signal is one grey log line in a long CodeGen run.

## How it was found

Phase 0 of the unified-workflow program (#3456) drops 11 entities. Ten pruned cleanly; `MJ: Scheduled Actions` did not, because 40 `ProcessRun` and 125 `ProcessRunDetail` rows referenced it. Neither table is in the proc — both postdate it (Record Set Processing).

The Phase 0 migration works around this by deleting the dangling rows itself for the entities it drops. That is a point fix, not the general one.

## Uncovered references (partial)

Beyond `ProcessRun` / `ProcessRunDetail`: `EntityAction` (`EntityID`, `ScopeEntityID`), `EntityFormOverride`, `EntityOrganicKey`, `EntityRecordDocument`, `QueryEntity`, `RecordProcess`, `RecordProcessWatermark`, `SearchScopeEntity`, `TaggedItem`, `TagScope`, `VersionLabel` / `VersionLabelItem`, `MLModelScoringBinding`, `MLTrainingPipeline`, `RecordLink`, `SignatureRequest`, `SystemEvent`, `ScopedPromptConfig` / `ScopedPromptPart`, and more.

## Suggested fix

1. Make the proc's cascade list exhaustive — each reference decided as delete-vs-null (nullable FKs like `ProcessRun.EntityID` could be nulled; non-nullable children must be deleted).
2. Consider generating the list from the FK graph instead of hand-maintaining it, so it cannot drift again.
3. Make the CodeGen caller **fail loudly** rather than log-and-continue, so a half-pruned entity can't slip through unnoticed.

Not attempted in #3456's Phase 0: fixing all ~55 uncovered references speculatively would be a large, under-tested change riding on an unrelated PR.

Contributor guide

Open the contributing guide

Research direction

Start with spDeleteEntityWithCoreDependencies and its CodeGen entry point, checkAndRemoveMetadataForDeletedTables in packages/CodeGenLib/src/Database/manage-metadata.ts. Map the database's Entity.ID foreign-key references and compare them with the procedure's cascade list, then review the caller's catch-and-log behavior. Done means deletion handles every reference deliberately and a failed cleanup is surfaced instead of silently leaving partial metadata.

Written by the indexing model from the issue text.

Assessment

Tech stack
sql, typescript
Domain
databases, tooling
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.