MemberJunction / MemberJunction/MJ

Lists: write ListDetail.RecordID as the compact CompositeKey segment, and sweep remaining hardcoded-ID key construction (follow-up to #4184)

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

Description

## Summary

#4184 establishes the contract that a record id carried in `SearchResult.RecordID`, `MJ: List Details.RecordID` and `MJ: User Record Logs` is a **compact `CompositeKey` segment** — the bare value for a single-column key (whatever the column is called), `F1|v1||F2|v2` for a composite key — and moves the search navigation sites, the recents lookups and the list form's `openRecord` onto `CompositeKey.FromURLSegment(entityInfo, recordId)` / `FromEntityRecord(entityInfo, row)`.

Two things remain, both called out in that PR's description as follow-ups.

## 1. List Details are still *written* with a hardcoded `ID`

The read side now resolves any key, but the write side still assumes the column is `ID`, so adding a record from an entity whose key is `individual_id` (or composite) to a list stores an empty or wrong `RecordID`:

| site | writes |
|---|---|
| `packages/Angular/Explorer/core-entity-forms/src/lib/custom/Lists/list-form.component.ts:748` | `listDetail.RecordID = record.ID` |
| `packages/Angular/Explorer/core-entity-forms/src/lib/custom/Lists/list-form.component.ts:885` | `listDetail.RecordID = recordID` (caller-supplied) |
| `packages/Angular/Explorer/explorer-core/src/lib/single-list-detail/single-list-detail.component.ts:961` | `newDetail.RecordID = recordId` |
| `packages/Actions/CoreActions/src/custom/lists/add-records-to-list.action.ts:109` | `listDetail.RecordID = recordId` |
| `packages/Actions/CoreActions/src/custom/lists/create-list.action.ts:103` | `listDetail.RecordID = recordId` |
| `packages/AI/Providers/Recommendations-Rex/src/provider.ts:308` | `listDetail.RecordID = recordID` |

Fix: build the value with `CompositeKey.FromEntityRecord(entityInfo, row).ToCompactURLSegment()` where a row is in hand, and document on the action inputs that a caller-supplied id must be the compact segment. With #4184's read side in place each of these is a one-liner.

## 2. Repo-wide sweep of the same anti-pattern, plus a guard

`CompositeKey.FromID(...)` and `{ FieldName: 'ID', Value: ... }` on a **variable** entity (as opposed to a literal MJ core entity that really is keyed by `ID`) still appear at roughly 146 sites under `packages/Angular` alone. #4184 proposes a `PrimaryKeyCompliance` guard test in MJCore modelled on `MultiProviderCompliance` so new occurrences are caught in CI. The sweep should distinguish the two cases rather than rewrite everything: a literal core entity (`'MJ: Lists'`, `'MJ: Users'`, …) with `FromID` is fine; an entity name that comes from data is not.

## Why it matters

Silent data loss, not an error: a `RecordID` of `''` is dropped by fusion/dedup on the read path, so the record simply never shows up in the list it was added to. Reported originally in #4179 for search navigation; the write side is the same defect one layer down.

## Related

- #4184 — the contract and the read-side fix (approved)
- #4179 — the original report

Contributor guide

Open the contributing guide

Research direction

Start with the six listed ListDetail.RecordID assignments in the list form, single-list detail, actions, and Recommendations-Rex provider, then review #4184's compact CompositeKey contract. Verify row-based writes use the entity record and caller-supplied ids are compact segments. Next search packages/Angular for variable-entity CompositeKey.FromID and { FieldName: 'ID' } uses, distinguishing literal MJ core entities, and add the proposed PrimaryKeyCompliance guard modeled on MultiProviderCompliance.

Written by the indexing model from the issue text.

Assessment

Tech stack
angular, typescript
Domain
full-stack
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.