Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .changeset/sys-user-lookup-count-out-of-prose.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
---

Comment prose only — this PR releases nothing to HotCRM users, so the
frontmatter above is deliberately empty (the sanctioned "releases nothing"
declaration that `.github/workflows/changeset-check.yml` documents, on par with
the `skip-changeset` label).

Two comments justifying `deleteBehavior: 'cascade'` on
`crm_event_attendee.sys_user` each stated 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.

No code, no assertion and no other line of either comment's argument changed.
4 changes: 2 additions & 2 deletions src/objects/event_attendee.object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,8 @@ export const EventAttendee = ObjectSchema.create({
// runs the referential pass. So `set_null` here is not dormant: it broke
// account erasure for any colleague who had ever attended a meeting.
// · The app's shipped stance is already "a deleted user's references
// degrade". HotCRM holds 15 lookups on `sys_user`; the other 14 (every
// `owner_id`, plus `product_manager`) are `set_null`
// degrade". EVERY other `sys_user` lookup in HotCRM (every `owner_id`,
// plus `product_manager`) is `set_null`
// and NO validation rule reads any of them — the rule below is the only
// one in the app that reads a user reference at all, which is precisely
// why this is the only lookup where the default misbehaved. `restrict`
Expand Down
4 changes: 2 additions & 2 deletions test/event-attendee-cascade.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ import stack from '../objectstack.config';
* not dormant: it broke account erasure for any colleague who had ever sat
* in a logged meeting.
* 2. **"A deleted user's references degrade" is already this app's stance.**
* HotCRM holds 15 lookups on `sys_user`; the other 14 — every `owner_id`,
* plus `crm_product.product_manager` — are
* EVERY other `sys_user` lookup in HotCRM — every `owner_id`, plus
* `crm_product.product_manager` — is
* `set_null`, and NO validation rule reads any of them. Swept over the
* built stack (rule conditions are `{ dialect, source }`, so the source
* string is what has to be searched): this object's rules are the only ones
Expand Down
Loading