Repository navigation
docs(event-attendee): state the sys_user cascade rationale as a universal, not a count - #1308
Merged
Merged
Conversation
…rsal, not a count Two comments justifying `deleteBehavior: 'cascade'` on `crm_event_attendee.sys_user` each carried a hand-counted figure — "HotCRM holds 15 lookups on `sys_user`; the other 14 ... are `set_null`" — in `src/objects/event_attendee.object.ts` and `test/event-attendee-cascade.test.ts`. Nothing produced either integer and nothing checked them. They had already drifted to 16 once, when `article_feedback` gained an `owner_id`, with nothing reporting it; they read correctly today only because removing `crm_account.renewal_owner` happened to bring the real count back to 15. Both sentences now make the universal claim instead: every other `sys_user` lookup in HotCRM — every `owner_id`, plus `crm_product.product_manager` — is `set_null`. That is what the cascade argument actually rests on, it is stronger than "the other 14" because it cannot be falsified by the next field someone adds, and it needs no producer to stay true. Pinning the integers was the alternative and was rejected: it would have added a second hand-maintained number plus a guard whose only effect is to turn silent drift into red on every new `sys_user` lookup, changing nothing a user sees. Comment prose only — no code, no assertion, and no other line of either comment's argument changed. Ships nothing to users, so the changeset carries deliberately empty frontmatter. Claude-Session: https://claude.ai/code/session_01R5spVzEKtmowdQQ3r6xNRM
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
hotlong
marked this pull request as ready for review
August 26, 2026 05:54
This was referenced Aug 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Two comments justifying
deleteBehavior: 'cascade'oncrm_event_attendee.sys_usereach stated a hand-counted figure — "HotCRM holds 15 lookups onsys_user; the other 14 … areset_null" — one in the object, one in the test. Nothing produced either integer and nothing checked them.The figure is load-bearing: it is the evidence for "a deleted user's references degrade is already this app's stance", which is why this lookup uses
cascaderather thanrestrict. The reasoning is sound; the number backing it had no producer. It had already drifted to 16 once (whenarticle_feedbackgained anowner_id) with nothing reporting it, and it reads correctly today only because removingcrm_account.renewal_ownerhappened to bring the real count back to 15 — by coincidence, not because anything holds it there.Both sentences now make the universal claim instead: every other
sys_userlookup in HotCRM — everyowner_id, pluscrm_product.product_manager— isset_null. That is what the cascade argument actually rests on, it is stronger than "the other 14" because a universal cannot be falsified by the next field someone adds, and it needs no producer to stay true.Pinning the integers was the alternative and was rejected: it would add a second hand-maintained number plus a guard whose only effect is to turn silent drift into red on every new
sys_userlookup — an author editing that integer changes nothing a user sees.Type of Change
Related Issues
Closes #1188
Changes Made
src/objects/event_attendee.object.ts(~:257)test/event-attendee-cascade.test.ts(~:70)Each file keeps its own existing voice (parentheses in the object comment, em dashes in the JSDoc block) so the diff stays minimal and the line count is unchanged in both.
Nothing else changed. The whole diff is 4 changed lines across the 2 files, and every one of them is a comment line — verified mechanically:
No code, no assertion, no field, no
deleteBehavior. The surrounding argumentation — the/api/v1/auth/delete-user→dataEngine.delete(...)path chain, and theattendee_resolves/attendee_type_exclusiverule claims — is untouched.The universal claim was verified before being written
The count as of this PR's base (
cd198f10), re-measured independently:15 objects hold one
sys_userlookup each. Field names and delete behaviour:deleteBehaviorowner_idproduct_managersys_user'cascade'— this lookupAnd the default is
set_null, from the installed spec (@objectstack/spec@17.1.0,src/data/field.zod.ts:906):So "every other
sys_userlookup … isset_null" is true on the base commit, and — unlike the count — stays true as fields are added.Testing
Run at the final commit
126aa43a:pnpm testTest Files 140 passed (140)·Tests 2969 passed | 1 skipped (2970)pnpm typecheckpnpm validate✓ Validation passed (1586ms)pnpm build✓ Build complete (1711ms)pnpm lint45 warning(s), 10 suggestion(s)— pre-existing advisory, exit 0pnpm lint:i18n-gate✓ i18n lint gate: 0 i18n/missing-* issuespnpm hygiene✓ source hygiene cleanpnpm hygiene:tokens✓ source token ratchet cleantest/event-attendee-cascade.test.ts— the file whose header comment this PR edits — ran in that suite and passed. The token ratchet is unmoved by design: it strips comments before measuring.pnpm test)pnpm lint)pnpm build)Screenshots
N/A — no user-visible surface changes.
Checklist
.changeset/sys-user-lookup-count-out-of-prose.md, with deliberately empty frontmatter. Of the two lawful exemptions this PR chose the empty-frontmatter changeset over theskip-changesetlabel: it is the sanctioned "this PR releases nothing" declaration that.github/workflows/changeset-check.ymldocuments in both of its steps, and it travels in the PR itself rather than depending on a label being applied.Additional Notes
Why no guard ships with this. The card offered a second shape — derive the count from the built stack and assert the comment's number. That shape was rejected on ADR-0049 axis ③: it creates one more hand-maintained integer and merely puts a lock on it, converting "silent drift" into "red on every new
sys_userlookup" while changing nothing a user sees. Removing the number removes the drift surface outright, which is why there is no new test here — there is no longer a fact that can drift.Scope. Strictly the two sentences.
test/forecast-seeds.test.tscarries the same family and the same fix shape and is deliberately not touched here — it belongs to its own card.Generated by Claude Code