Skip to content

composeStatusQueryConstraint

composeStatusQueryConstraint(props): object

Defined in: packages/core/src/versions/statusQueryConstraint.ts:210

Folds the framework’s published/draft status composition onto whatever resolveQueryIndex / pickConvexQueryIndex / resolveQueryConstraint already resolved for the caller’s RBAC rule, honoring Convex’s one-withIndex-per-query limit AND, when the winning index declares a draftStatus (Step 13’s per-index config), the one-physical-field-order limit a vex_status-prefixed index imposes.

Never a permission rule. The published-only half runs whenever requiresPublishedOnly says so, including when the caller bypassed RBAC entirely (props.resolvedIndex/props.accessFilter may both be undefined in that case) — hiding non-published rows on a versioned collection is data integrity (design-review.md §3.1), not authorization, so it has no dependency on access.bypass at all. MUST run AFTER pickConvexQueryIndex — every branch reads props.resolvedIndex.name to look up THAT index’s own draftStatus, never the collection’s in the abstract.

Four cases, crossing “does this read want published-only or everything” with “does the winning index declare a draftStatus” — see the Why above for the full worked reasoning per case:

  1. Published-only, no draftStatus on the winning index (or none chosen) — unchanged original design: claim the free by_status slot, or fold vex_status === "published" into .filter(). Warns once when an index WAS chosen but declares no draftStatus.
  2. Published-only, winning index HAS a draftStatus — rides the SAME (prefixed) physical index for free via composeConvexQueryRanges. No .filter().
  3. drafts: true, winning index has draftStatus: "both" — the unprefixed physical index already exists untouched; no-op.
  4. drafts: true, winning index has draftStatus: true — no unprefixed physical form exists; drop the range and re-apply it as a .filter() ANDed with accessFilter. Warns once, suggesting "both".

Input props.

ConvexQueryFilterFn | undefined

The RBAC filter resolveQueryConstraint already resolved for resolvedIndex as arbitrated (the SAME indexAlreadyApplied the caller already used).

string

The collection slug being queried.

VexConfig

The resolved VexConfig.

boolean

The caller’s drafts arg.

ConvexQueryIndex | undefined

pickConvexQueryIndex({ accessIndex, callerIndex })’s output, computed BEFORE this function runs.

object

The index to apply and the filter to apply.

accessFilter: ConvexQueryFilterFn | undefined

resolvedIndex: ConvexQueryIndex | undefined