Skip to content

Document existential relationship conditions and relationship[...] groups for 5.4 - #784

Merged
kriszyp merged 6 commits into
mainfrom
docs/relationship-existential-conditions-and-groups
Nov 5, 2026
Merged

kriszyp merged 6 commits into
mainfrom
docs/relationship-existential-conditions-and-groups

Conversation

@kriszyp

@kriszyp kriszyp commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

⊙ Problem

Make each relationship condition existential, and add relationship[...] for conditions one related record must meet changes how v5.4 combines conditions on a to-many relationship. The docs do not describe the new rule. Instead, Document same-record AND matching and OR scope for relationship conditions in 5.4 documents an earlier rule that did not ship: that every AND condition on one relationship must match the same related record.

🤔 Is the requirement right?

Yes. #3927 is the rule the owner chose for v5.4. It matches how arrays already work, and adds an explicit form for "one record meets all". Users of collection DELETE need the warning most.

💡 Solution

  • Separate conditions may each be met by a different related record. products.name=Keyboard&products.name=Cable returns Acme.
  • New products[name=Cable&price=ge=30] (in code, { attribute: 'products', conditions: [...] }): one related record must meet all of them.
  • select() keeps the related records that meet any AND condition; a group counts as one condition. A condition inside an OR never narrows select().
  • Also: permissions, to-one relationships, 400 errors, and a three-level example of where brackets go.

This PR replaces #779: it keeps #779's OR rule, re-verified, and drops its same-record rule.

⚖️ Alternatives

🤔 Replaces #779 rather than editing it

#779 belongs to another task, with its own history and review record. This branch starts from main and carries the whole current rule. Close #779 once this lands; its OR text is carried here.

🤔 New examples are not in the fixture harness

The paired fixture must match harper's copy byte for byte, and #3927 does not change that copy. Follow-up: Check the relationship-condition examples against the paired core fixture. Every example was run by hand instead (see Verification).

🔧 Changes

🤔 Pre-5.4 results on reference pages

Two sentences give the v5.3.5 results, so a reader on 5.3 sees the difference. Drop them once 5.3 leaves support.

🤔 Operations API exclusion

#3927 leaves group validation in search_by_conditions as separate work. A top-level group fails there today (unknown attribute 'price'). Remove the sentence once core supports groups.

✅ Verification

  • I built harper at the #3927 head (b850946) in a scratch directory and loaded the docs Brand/Product data plus the synthetic Company/Department/Employee schema through harper's integration-test harness. I ran every documented request and new snippet, extracted verbatim from the Markdown. Each documented result matches. That includes the 400 and 403 cases (over REST and with checkPermission: true) and collection DELETE with separate conditions and with a group.
  • The same suite on harper@5.3.5 backs each "before v5.4" claim.
  • format:check, lint, typecheck, test:workflows and build pass. test:examples passes all 14 with HARPER_CORE_FIXTURE_ROOT set to the #3927 fixture. The new anchors resolve in the built HTML.
  • PR QA: skipped @ 4e21548 — docs-only change
Observed results (#3927 head / v5.3.5)
Request #3927 v5.3.5
products.name=Keyboard&products.name=Cable Acme []
products.name=Cable&products.price=ge=number:30 Acme [] (with name=Acme& first: Acme)
products[name=Cable&price=ge=30] [] 404 price is not a defined attribute
products[name=Keyboard&price=ge=30]&select(id,products{name}) Acme [Keyboard] 404
products.name=Keyboard&products.price=ge=number:30&select(id,products{name}) Acme [Keyboard, Dock] Acme [Keyboard]
(products.name=Cable|id=44)&select(id,products{name}) Acme: all 3; Studio Gear: both Acme [Cable]; Studio Gear []
products[name=Mouse|price=ge=100] Budget Basics, Studio Gear 404
Company table rows 1-4 c1,c2,c3 / c1,c2 / c2 / c2 c1,c2 / 404 / 404 / 404
name[id=42], products[] 400, 400 [42], 500
role without Product read: products[name=Cable], products.name=Cable 403, 403 [], Acme
collection DELETE, separate / group brand deleted / spared deleted / 404

Refs HarperFast/harper#3927

🤖 Generated by Claude Opus 5.5; posted via @kriszyp.

Related PRs: #779 supersedes (replaces its same-record rule; carries its OR text), #775 overlaps (qualifies its to-many sort wording), #783 overlaps (edits the same resource-api.md insertion point and search_by_conditions line; whichever merges second needs a rebase), 2 others independent
Complexity: easy

Deferred findings

Origin — the dispatch brief this PR was written from

Document existential relationship conditions and relationship[...] same-record groups

Revise the relationship-condition documentation to the rule in HarperFast/harper#3927 (Harper v5.4). #779 currently documents the earlier rule from harper#3724 (separate AND conditions on one to-many relationship must be met by one related record); that rule did not ship and is replaced.

The rule to document:

  1. Separate AND conditions on a to-many relationship are each met by some related record, possibly different ones, the same as separate conditions on an array attribute. GET /Brand/?products.name=Keyboard&products.name=Mouse returns a brand that has both a Keyboard and a Mouse product.
  2. relationship[conditions] in condition position means one related record must meet all of them (like MongoDB $elemMatch). GET /Brand/?products[name=Cable&price=ge=30] returns a brand with one product that is a Cable and costs at least 30. Inner conditions are relative to the related table, may use | and parenthesized groups, and may nest another relationship: departments[employees[tag=t&level=ge=3]]. A path works too: departments.employees[tag=t&level=ge=3]. Brackets inside select(...) keep their existing nested-selection meaning.
  3. Programmatic search(): { attribute: 'products', operator: 'and', conditions: [{ attribute: 'name', value: 'Cable' }, { attribute: 'price', comparator: 'ge', value: 30 }] } (no comparator or value on the group itself; operator defaults to and).
  4. select() of the relationship: with separate conditions it returns the related records that match any of them; with a group, the records matching the whole group. A condition inside an OR decides which rows match and never narrows the selection.
  5. A group on a to-one relationship behaves like separate conditions, since there is one related record.
  6. Reading through a group needs read permission on the related table and attributes, as a dotted path does.

Use synthetic examples only. Link the harper PR from the docs PR.

Dispatch: task docs-harper-3927 · queued by task:harper-relationship-existential-and-same-record-form · ran by claude/opus/xhigh · worker kzyp-xps-1

Ready-For-Promotion: fdac9cf urgency=normal late=folded

Review-Coverage: authored=claude; ran=gemini,cursor-composer,codex,cursor-grok; late=cursor-grok:adjudicated; adjudicated=domain; declined=muse; rounds=7; full=2 @ fdac9cf

Review-Attention: skim ~2m (decisions: unreleased-semantics-in-current-reference, land-order-with-779) @ fdac9cf

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the documentation across multiple files to detail the new to-many relationship query behavior in version 5.4.0, including the introduction of bracketed relationship groups to enforce that a single related record meets multiple conditions. The review feedback points out a style violation regarding the mid-sentence use of the component, suggesting it be replaced with plain text format (Added in: v5.4.0) instead.

Comment thread reference/resources/resource-api.md Resolved
@github-actions
github-actions Bot temporarily deployed to pr-784 November 2, 2026 21:24 Inactive
@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-784

This preview will update automatically when you push new commits.

@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-784

This preview will update automatically when you push new commits.

kriszyp and others added 5 commits November 4, 2026 09:28
…oups for 5.4

Separate AND conditions on a to-many relationship are each met by some
related record; relationship[conditions] (programmatically
{ attribute, operator, conditions }) requires one related record to meet
all of them. select() keeps the related records any AND condition matched,
and a condition inside an OR decides rows without narrowing the selection.
Documents HarperFast/harper#3927 and replaces the same-record rule
documented in #779, which did not ship.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dispatch-Task: docs-harper-3927
… rules

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dispatch-Task: docs-harper-3927
…tionship rules

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dispatch-Task: docs-harper-3927
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dispatch-Task: docs-harper-3927
…s API exclusion

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Dispatch-Task: pr-maint-165fdb441be4ca4fb47889bc26fbd2b8
@kriszyp
kriszyp force-pushed the docs/relationship-existential-conditions-and-groups branch from 4e21548 to 411f39e Compare November 4, 2026 16:38
@github-actions
github-actions Bot temporarily deployed to pr-784 November 4, 2026 16:42 Inactive
@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-784

This preview will update automatically when you push new commits.

…ed table before 5.4

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Dispatch-Task: pr-maint-165fdb441be4ca4fb47889bc26fbd2b8
@github-actions
github-actions Bot temporarily deployed to pr-784 November 4, 2026 16:52 Inactive
@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-784

This preview will update automatically when you push new commits.

@kriszyp
kriszyp marked this pull request as ready for review November 5, 2026 00:45
@kriszyp
kriszyp requested a review from a team as a code owner November 5, 2026 00:45
@kriszyp
kriszyp merged commit d287360 into main Nov 5, 2026
14 checks passed
@kriszyp
kriszyp deleted the docs/relationship-existential-conditions-and-groups branch November 5, 2026 00:45
@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown

🧹 Preview Cleanup

The preview deployment for this PR has been removed.

kriszyp added a commit to HarperFast/harper that referenced this pull request Nov 5, 2026
…oups for 5.4 (HarperFast/documentation#784)

* Document existential relationship conditions and relationship[...] groups for 5.4

Separate AND conditions on a to-many relationship are each met by some
related record; relationship[conditions] (programmatically
{ attribute, operator, conditions }) requires one related record to meet
all of them. select() keeps the related records any AND condition matched,
and a condition inside an OR decides rows without narrowing the selection.
Documents #3927 and replaces the same-record rule
documented in HarperFast/documentation#779, which did not ship.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dispatch-Task: docs-harper-3927

* Address review: link nested and DELETE references to the relationship rules

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dispatch-Task: docs-harper-3927

* Address review: link the Grouping and nested-filter notes to the relationship rules

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dispatch-Task: docs-harper-3927

* Address review: use plain-text version note mid-sentence

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dispatch-Task: docs-harper-3927

* Address review: state the full-text 400 case and reword the operations API exclusion

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Dispatch-Task: pr-maint-165fdb441be4ca4fb47889bc26fbd2b8

* Address review: warn that bracketed DELETE filters apply to the queried table before 5.4

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Dispatch-Task: pr-maint-165fdb441be4ca4fb47889bc26fbd2b8

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

This branch was previously deployed

1 inactive deployment
pr-784 — fdac9cf1 Deployed Nov 4, 2026 by github-actions[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant