@ai-matrx/records 0.47.0 → 0.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2103,6 +2103,11 @@ declare const STORE_DOORS: readonly [{
2103
2103
  readonly args: "p_organization_id uuid, p_table_id uuid, p_record_ids uuid[], p_by_id boolean DEFAULT false";
2104
2104
  readonly returns: "TABLE(id uuid, document jsonb, level permission_level)";
2105
2105
  readonly security: "definer";
2106
+ }, {
2107
+ readonly name: "read_records_matching";
2108
+ readonly args: "p_organization_id uuid, p_table_id uuid, p_filter jsonb DEFAULT '{}'::jsonb, p_by_id boolean DEFAULT false, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0";
2109
+ readonly returns: "TABLE(id uuid, document jsonb, level permission_level)";
2110
+ readonly security: "definer";
2106
2111
  }, {
2107
2112
  readonly name: "realtime_topic_admits";
2108
2113
  readonly args: "p_topic text";
@@ -5142,6 +5147,19 @@ interface PortalPrincipal {
5142
5147
  is_active: boolean;
5143
5148
  invited_at: Timestamp;
5144
5149
  revoked_at: Timestamp | null;
5150
+ /**
5151
+ * THE LINK THE OFFICE COPIES FOR THIS PERSON — `/invitations/portal/accept/<token>`, the
5152
+ * path `custom.portal_invite` handed back when they were asked, read off the same
5153
+ * `iam.invitations` row and never re-templated.
5154
+ *
5155
+ * 🚨 `null` IS AN ANSWER, NOT AN ABSENCE, and a screen must say which. It is null when they
5156
+ * have already followed the link, when the office took it back (a revoke withdraws the
5157
+ * invitation in the same statement), when it has expired, or when they were let in through
5158
+ * the server's own magic-link route, which binds without an invitation at all. In every one
5159
+ * of those cases there is genuinely no link to copy — so draw a sentence, never a dead
5160
+ * control. (TAILS-5, 2026-09-21; the gap PORTAL-BIND left named.)
5161
+ */
5162
+ accept_path: string | null;
5145
5163
  }
5146
5164
  /** Everything about ONE portal: what it shows, and who it was opened to. */
5147
5165
  interface PortalCard {
@@ -5223,6 +5241,25 @@ interface AggregateWindow {
5223
5241
  * caller should get from the compiler, not from the database.
5224
5242
  */
5225
5243
  type AggregateFilter = string | number | boolean | null | AggregateWindow;
5244
+ /**
5245
+ * 🚨 THE STORE'S ONE FILTER SHAPE, AND THE ONLY NAME FOR IT.
5246
+ *
5247
+ * An object of Field key -> value. A scalar is an equality, `null` is UNSET
5248
+ * (the third state of a tick box), an object is a half-open time window.
5249
+ *
5250
+ * It is not the aggregate's private shape and never was. `platform.saved_view`
5251
+ * has carried exactly this as `definition -> 'filters'` across five live
5252
+ * surface keys since DOOR-18; `custom.view_declare` writes it;
5253
+ * `custom.agg_view_admits` reads it to decide whether a change belongs to a
5254
+ * saved view; `custom.record_aggregate` takes it as `p_filter` to COMPUTE a
5255
+ * dashboard number; and `custom.read_records_matching` takes it to OPEN the
5256
+ * rows behind that number. One `custom.record_filter_sql` in the database turns
5257
+ * it into SQL for the last two, so the number and the rows cannot disagree.
5258
+ *
5259
+ * Invent a second one and a chart can compute a total whose drill-through
5260
+ * lands somewhere else, which is the only way a drill-through can lie.
5261
+ */
5262
+ type RecordFilter = Record<string, AggregateFilter>;
5226
5263
  /** One measure. `count` counts rows and needs no Field; the rest read one. */
5227
5264
  interface AggregateMeasure {
5228
5265
  op: AggregateOperation;
@@ -5241,6 +5278,19 @@ interface AggregateRow {
5241
5278
  }
5242
5279
  /** The measure key the store answers with, so a chart can find its own series. */
5243
5280
  declare function measureKey(measure: AggregateMeasure): string;
5281
+ /**
5282
+ * THE QUESTION, AS A STABLE STRING — key-sorted JSON of a `RecordFilter`.
5283
+ *
5284
+ * A React parent that rebuilds `{ status: "Cancelled" }` on every render hands
5285
+ * a NEW object every time, and a hook that depends on the object re-reads the
5286
+ * whole page on every render forever. Depending on this instead means the page
5287
+ * is re-read exactly when the QUESTION changed, which is what a person means.
5288
+ *
5289
+ * Nested window objects are sorted too, so `{from, to}` and `{to, from}` are
5290
+ * one question. `undefined` and an empty filter are both `"{}"` — the caller
5291
+ * asked nothing, and there is only one way to ask nothing.
5292
+ */
5293
+ declare function stableFilterKey(filter: RecordFilter | null | undefined): string;
5244
5294
 
5245
5295
  /** The seven shapes a block can take, exactly as `custom.dashboard_kinds()` answers. */
5246
5296
  type DashboardBlockKind = "number" | "bar" | "column" | "line" | "donut" | "table" | "stuck";
@@ -6070,13 +6120,13 @@ interface SavedViewRow {
6070
6120
  view_id: Uuid;
6071
6121
  name: string;
6072
6122
  table_id: Uuid | null;
6073
- filters: Record<string, unknown>;
6123
+ filters: RecordFilter;
6074
6124
  created_at: string;
6075
6125
  }
6076
6126
  /** What `custom.view_declare` is asked for. `view_id` re-states rather than doubling. */
6077
6127
  interface SavedViewSpecIn {
6078
6128
  name: string;
6079
- filters?: Record<string, unknown> | null;
6129
+ filters?: RecordFilter | null;
6080
6130
  definition?: Record<string, unknown> | null;
6081
6131
  view_id?: Uuid | null;
6082
6132
  }
@@ -7085,6 +7135,17 @@ interface RecordsClient {
7085
7135
  */
7086
7136
  list(args: {
7087
7137
  table_id: Uuid;
7138
+ /**
7139
+ * THE STORE'S ONE FILTER SHAPE (`RecordFilter`). Left out, this is the
7140
+ * whole page. Supplied, the store narrows INSIDE its own query — never the
7141
+ * browser, which can only ever filter the rows it was already allowed to
7142
+ * see and would silently drop the rest of the answer.
7143
+ *
7144
+ * It is the same object a saved view stores as `filters` and the same one
7145
+ * `recordAggregate` counts with, so the rows a drill-through opens are the
7146
+ * rows the number on the dashboard counted.
7147
+ */
7148
+ filter?: RecordFilter;
7088
7149
  limit?: number;
7089
7150
  offset?: number;
7090
7151
  }): Promise<RecordsResult<{
@@ -7562,14 +7623,14 @@ interface RecordsClient {
7562
7623
  */
7563
7624
  dashboardRun(args: {
7564
7625
  dashboard_id: Uuid;
7565
- filter?: Record<string, AggregateFilter>;
7626
+ filter?: RecordFilter;
7566
7627
  }): Promise<RecordsResult<DashboardRunResult>>;
7567
7628
  /** The seventh block kind on its own: records that have sat on the same value too long. */
7568
7629
  dashboardStuck(args: {
7569
7630
  table_id: Uuid;
7570
7631
  state_key: string;
7571
7632
  days?: number;
7572
- filter?: Record<string, AggregateFilter>;
7633
+ filter?: RecordFilter;
7573
7634
  limit?: number;
7574
7635
  }): Promise<RecordsResult<StuckRow[]>>;
7575
7636
  /**
@@ -7688,7 +7749,7 @@ interface RecordsClient {
7688
7749
  * A scalar is an equality and an object is a half-open moment window, and
7689
7750
  * either way it lands in the SAME WHERE as visibility.
7690
7751
  */
7691
- filter?: Record<string, AggregateFilter>;
7752
+ filter?: RecordFilter;
7692
7753
  limit?: number;
7693
7754
  }): Promise<RecordsResult<AggregateRow[]>>;
7694
7755
  /** The measures the store itself offers. Asked, never hardcoded in a picker. */
@@ -8430,6 +8491,16 @@ declare function useFields(tableId: Uuid | null, recordType?: string): Async<Fie
8430
8491
  interface UseRecordsOptions {
8431
8492
  pageSize?: number;
8432
8493
  page?: number;
8494
+ /**
8495
+ * THE STORE'S ONE FILTER SHAPE. Left out, this is the whole page. Supplied,
8496
+ * the store narrows in its own query and the hook re-reads when the question
8497
+ * changes — it is never filtered in the browser, which could only ever filter
8498
+ * the rows it had already been handed and would silently drop the rest.
8499
+ *
8500
+ * This is what makes a dashboard number walkable: the same object that
8501
+ * counted it opens it.
8502
+ */
8503
+ filter?: RecordFilter;
8433
8504
  }
8434
8505
  interface UseRecordsState extends Async<{
8435
8506
  rows: ReadRow[];
@@ -8564,4 +8635,4 @@ declare function useFieldMutation(): UseFieldMutation;
8564
8635
  */
8565
8636
  declare function useMergeField(key: string | null, state?: Record<string, unknown>): MergeFieldResolution | null;
8566
8637
 
8567
- export { ABSENCE_REASONS, ACTOR_VOCABULARY, type AbsenceReason, type Actor, type AggregateBucket, type AggregateFilter, type AggregateMeasure, type AggregateOperation, type AggregateRow, type AggregateWindow, type AnonTokenBinding, type BookingAvailability, type BookingDeclared, type BookingSummary, type BookingWindow, COMPUTE_ON, CONTEXT_POLICIES, type CaptureField, type CaptureFileRef, type CaptureOutcome, type CaptureQuestion, type CaptureQueue, type CaptureQueueCounts, type CaptureQueueOptions, type CaptureQueuePorts, type CaptureQueueStore, type CaptureSheetFace, type CaptureSheetSummary, type CaptureSyncReport, type ChecklistDeclared, type ChecklistRequirement, type ChecklistRequirementKind, type ChecklistRoleSpec, type ChecklistRunStarted, type ChecklistRunStep, type ChecklistRunSummary, type ChecklistSpec, type ChecklistStepCompleted, type ChecklistStepSpec, type ChecklistTemplateShape, type ChecklistTemplateSummary, type ChecklistTrigger, type ChecklistTriggerKind, type ChoiceOption, type ChoiceOptions, type CoerceOptions, type Coerced, type CoercedAnswers, type CoercibleField, type CommentThreadRead, type CommentWritten, type ComputeOn, type ContextPolicy, type ConversationScope, type ConversationScopeContext, type CustomFieldTableType, DELIVERIES, type DashboardBlock, type DashboardBlockKind, type DashboardBlockResult, type DashboardRunResult, type DashboardSummary, type Delivery, type DigestPreview, type DocRenderRow, type DocSignatureCheck, type DocSignatureRow, type DocTemplateRow, type DocToken, type DocUnresolvedToken, ENTITY_TOKENS, type EnrichAlternate, type EnrichCell, type EnrichDeclared, type EnrichDueRow, type EnrichRun, type EnrichSource, type Enrichment, type EnrichmentSummary, type EntityFieldRights, type EntityFieldValue, type EntityRecordMatch, type EntityRecordRead, type EntityRecordsFound, type EntityTableFacts, type EntityToken, type ExternalPrincipalCard, FIELD_KINDS, FIELD_SENSITIVITIES, FIELD_SOURCES, FRESHNESS, type Field, type FieldBehavior, type FieldHistoryEntry, type FieldKind, type FieldPatch, type FieldProposal, type FieldRule, type FieldSensitivity, type FieldSource, type FieldTypeWord, type ForbiddenEnvelopeWord, type FormSummary, type Freshness, type HiddenFieldNotice, type HistoryActor, type HistoryActorKind, type HistoryChange, type Home, type ImportBatchResult, type ImportColumnPlan, type ImportFinished, type ImportOpened, type ImportOutcome, type ImportPlan, type ImportPolicy, type ImportProposal, type ImportReport, type ImportRun, type InboundAddress, type InboundDeclared, KERNEL_TABLES, type KernelTableName, type KernelTargets, MERGE_FIELD_MODIFIERS, MERGE_FIELD_SEMANTIC_TYPES, MERGE_FIELD_SOURCES, type MergeField, type MergeFieldModifier, type MergeFieldProvenance, type MergeFieldResolution, type MergeFieldSemanticType, type MergeFieldSource, type MergeFieldTransform, type MissingBehavior, type MyLevel, type MySubscription, type NewEntityFieldDeclaration, type NewFieldDeclaration, ON_DELETE, OVERRIDE_POLICIES, type OnDelete, type OverridePolicy, PARITY_FIELD_TYPES, PERMISSION_LEVELS, PER_VALUE_ACCESS_WORDS, PIPELINE_RULE_KINDS, type ParityFieldType, type ParityFieldTypeDescriptor, type PerValueAccessWord, type PermissionLevel, type PgError, type Pipeline, type PipelineColumn, type PipelineDeclared, type PipelineGate, type PipelineGatePreview, type PipelineMissingField, type PipelineMoveResult, type PipelineRule, type PipelineRuleKind, type PipelineSpec, type PipelineStage, type PipelineVerdict, type PortalCard, type PortalInvitation, type PortalPreviewRow, type PortalPrincipal, type PortalRevocation, type PortalSummary, type PortalTableExposure, type PortalTableRef, type PredictedRefusal, type ProvenancePointer, type PublishBinding, type QueuedCapture, type QueuedCaptureFile, type QueuedCaptureState, type QuietHours, REFUSALS_WORTH_REPEATING, RELATION_BINDINGS, RELATION_CARDINALITIES, RELATION_FLAVORS, RETIRED_ACTOR_WORDS, RULE_NODE_KINDS, RULE_USES, type ReadRow, type ReadValue, type RecordComment, type RecordDocument, type RecordHistoryEntry, type RecordRead, type RecordRevision, type RecordScopeComment, type RecordScopeContext, type RecordScopeField, type RecordScopeHistoryEntry, type RecordScopeRelation, type RecordScopeWithheld, type RecordsActor, type RecordsChangeSink, type RecordsConfig, type RecordsDataSource, type RecordsError, type RecordsErrorCode, type RecordsErrorSink, type RecordsFilter, RecordsProvider, type RecordsProviderProps, type RecordsRealtimePort, type RecordsResolverPort, type RecordsResponse, type RecordsResult, type RecordsTableQuery, type RegisteredTable, type Relation, type RelationBinding, type RelationCardinality, type RelationCarries, type RelationCoordinate, type RelationDisplay, type RelationFlavor, type RelationProperties, type RelationTarget, type ResolutionTriple, type ResolvedPublishBinding, type RestorePreview, type RestoreResult, type RetiredActorWord, type Rule, type RuleAnswer, type RuleExpression, type RuleNodeKind, type RuleUse, STAGE_RULE_ENFORCEMENT, STAGE_RULE_ON_FAIL, STORAGE_MODES, STORE_DOORS, STORE_KNOBS, STORE_REFUSAL_CODES, type SavedViewRow, type SavedViewSpecIn, type StagePending, type StagePendingOnBoard, type StageRuleEnforcement, type StageRuleOnFail, type StageRuleWarning, type StaleWriteDetail, type StorageMode, type StoreDoorName, type StoreRefusalCode, type StoredRecord, type StuckRow, type Subscription, type SubscriptionBlock, type SubscriptionCadence, type SubscriptionSpec, TABLE_DISPLAYS, TABLE_ORIGINS, TABLE_TYPES, type Table, type TableCapacity, type TableDisplay, type TableOrigin, type TableProposal, type TableType, type Timestamp, type UseEntityFieldMutation, type UseFieldMutation, type UseRecordMutation, type UseRecordsOptions, type UseRecordsState, type Uuid, VALUE_ALTERNATE_KEYS, VALUE_ENVELOPE_KEYS, type ValueAlternate, type ValueAlternateKey, type ValueEnvelope, type ValueEnvelopeKey, type ValueSource, type WorkApprovalDecision, type WorkApprovalFiled, type WorkApprover, type WorkAssignment, type WorkAssignmentField, type WorkChange, type WorkDueState, type WorkGraph, type WorkInboxItem, type WorkInboxKind, type WorkInstantiation, type WorkListFlavour, type WorkListItem, type WorkOrigin, type WorkRecordState, type WorkSlotHold, type WorkState, type WorkTemplateNode, type WorkTemplateRelation, type WorkTurn, type WriteConflict, asPermissionLevel, atLeast, bookingPath, choiceSlug, choiceValuesOf, choicesOf, coerceTypedAnswer, coerceTypedAnswers, coercionLabel, err, fieldKindFor, forgetAllOps, highestLevel, holdsARetiredChoice, indexedDbStore, isDecided, isOwnOp, isRecordsErr, isTheChosen, looksLikeAnId, mayDrag, measureKey, memoryStore, mintClientKey, mintOpId, ok, openCaptureQueue, optionKey, optionLabel, portalPath, publicFormPath, rememberedOpCount, scopeChip, tableShapeChanged, useEntityFieldMutation, useEntityFieldRights, useEntityFields, useEntityRecord, useEntityTable, useFieldMutation, useFields, useMergeField, useMyLevel, useMyLevels, useOptionalRecordsClient, useRecord, useRecordMutation, useRecords, useRecordsActor, useRecordsClient, useTable, useTables };
8638
+ export { ABSENCE_REASONS, ACTOR_VOCABULARY, type AbsenceReason, type Actor, type AggregateBucket, type AggregateFilter, type AggregateMeasure, type AggregateOperation, type AggregateRow, type AggregateWindow, type AnonTokenBinding, type BookingAvailability, type BookingDeclared, type BookingSummary, type BookingWindow, COMPUTE_ON, CONTEXT_POLICIES, type CaptureField, type CaptureFileRef, type CaptureOutcome, type CaptureQuestion, type CaptureQueue, type CaptureQueueCounts, type CaptureQueueOptions, type CaptureQueuePorts, type CaptureQueueStore, type CaptureSheetFace, type CaptureSheetSummary, type CaptureSyncReport, type ChecklistDeclared, type ChecklistRequirement, type ChecklistRequirementKind, type ChecklistRoleSpec, type ChecklistRunStarted, type ChecklistRunStep, type ChecklistRunSummary, type ChecklistSpec, type ChecklistStepCompleted, type ChecklistStepSpec, type ChecklistTemplateShape, type ChecklistTemplateSummary, type ChecklistTrigger, type ChecklistTriggerKind, type ChoiceOption, type ChoiceOptions, type CoerceOptions, type Coerced, type CoercedAnswers, type CoercibleField, type CommentThreadRead, type CommentWritten, type ComputeOn, type ContextPolicy, type ConversationScope, type ConversationScopeContext, type CustomFieldTableType, DELIVERIES, type DashboardBlock, type DashboardBlockKind, type DashboardBlockResult, type DashboardRunResult, type DashboardSummary, type Delivery, type DigestPreview, type DocRenderRow, type DocSignatureCheck, type DocSignatureRow, type DocTemplateRow, type DocToken, type DocUnresolvedToken, ENTITY_TOKENS, type EnrichAlternate, type EnrichCell, type EnrichDeclared, type EnrichDueRow, type EnrichRun, type EnrichSource, type Enrichment, type EnrichmentSummary, type EntityFieldRights, type EntityFieldValue, type EntityRecordMatch, type EntityRecordRead, type EntityRecordsFound, type EntityTableFacts, type EntityToken, type ExternalPrincipalCard, FIELD_KINDS, FIELD_SENSITIVITIES, FIELD_SOURCES, FRESHNESS, type Field, type FieldBehavior, type FieldHistoryEntry, type FieldKind, type FieldPatch, type FieldProposal, type FieldRule, type FieldSensitivity, type FieldSource, type FieldTypeWord, type ForbiddenEnvelopeWord, type FormSummary, type Freshness, type HiddenFieldNotice, type HistoryActor, type HistoryActorKind, type HistoryChange, type Home, type ImportBatchResult, type ImportColumnPlan, type ImportFinished, type ImportOpened, type ImportOutcome, type ImportPlan, type ImportPolicy, type ImportProposal, type ImportReport, type ImportRun, type InboundAddress, type InboundDeclared, KERNEL_TABLES, type KernelTableName, type KernelTargets, MERGE_FIELD_MODIFIERS, MERGE_FIELD_SEMANTIC_TYPES, MERGE_FIELD_SOURCES, type MergeField, type MergeFieldModifier, type MergeFieldProvenance, type MergeFieldResolution, type MergeFieldSemanticType, type MergeFieldSource, type MergeFieldTransform, type MissingBehavior, type MyLevel, type MySubscription, type NewEntityFieldDeclaration, type NewFieldDeclaration, ON_DELETE, OVERRIDE_POLICIES, type OnDelete, type OverridePolicy, PARITY_FIELD_TYPES, PERMISSION_LEVELS, PER_VALUE_ACCESS_WORDS, PIPELINE_RULE_KINDS, type ParityFieldType, type ParityFieldTypeDescriptor, type PerValueAccessWord, type PermissionLevel, type PgError, type Pipeline, type PipelineColumn, type PipelineDeclared, type PipelineGate, type PipelineGatePreview, type PipelineMissingField, type PipelineMoveResult, type PipelineRule, type PipelineRuleKind, type PipelineSpec, type PipelineStage, type PipelineVerdict, type PortalCard, type PortalInvitation, type PortalPreviewRow, type PortalPrincipal, type PortalRevocation, type PortalSummary, type PortalTableExposure, type PortalTableRef, type PredictedRefusal, type ProvenancePointer, type PublishBinding, type QueuedCapture, type QueuedCaptureFile, type QueuedCaptureState, type QuietHours, REFUSALS_WORTH_REPEATING, RELATION_BINDINGS, RELATION_CARDINALITIES, RELATION_FLAVORS, RETIRED_ACTOR_WORDS, RULE_NODE_KINDS, RULE_USES, type ReadRow, type ReadValue, type RecordComment, type RecordDocument, type RecordFilter, type RecordHistoryEntry, type RecordRead, type RecordRevision, type RecordScopeComment, type RecordScopeContext, type RecordScopeField, type RecordScopeHistoryEntry, type RecordScopeRelation, type RecordScopeWithheld, type RecordsActor, type RecordsChangeSink, type RecordsConfig, type RecordsDataSource, type RecordsError, type RecordsErrorCode, type RecordsErrorSink, type RecordsFilter, RecordsProvider, type RecordsProviderProps, type RecordsRealtimePort, type RecordsResolverPort, type RecordsResponse, type RecordsResult, type RecordsTableQuery, type RegisteredTable, type Relation, type RelationBinding, type RelationCardinality, type RelationCarries, type RelationCoordinate, type RelationDisplay, type RelationFlavor, type RelationProperties, type RelationTarget, type ResolutionTriple, type ResolvedPublishBinding, type RestorePreview, type RestoreResult, type RetiredActorWord, type Rule, type RuleAnswer, type RuleExpression, type RuleNodeKind, type RuleUse, STAGE_RULE_ENFORCEMENT, STAGE_RULE_ON_FAIL, STORAGE_MODES, STORE_DOORS, STORE_KNOBS, STORE_REFUSAL_CODES, type SavedViewRow, type SavedViewSpecIn, type StagePending, type StagePendingOnBoard, type StageRuleEnforcement, type StageRuleOnFail, type StageRuleWarning, type StaleWriteDetail, type StorageMode, type StoreDoorName, type StoreRefusalCode, type StoredRecord, type StuckRow, type Subscription, type SubscriptionBlock, type SubscriptionCadence, type SubscriptionSpec, TABLE_DISPLAYS, TABLE_ORIGINS, TABLE_TYPES, type Table, type TableCapacity, type TableDisplay, type TableOrigin, type TableProposal, type TableType, type Timestamp, type UseEntityFieldMutation, type UseFieldMutation, type UseRecordMutation, type UseRecordsOptions, type UseRecordsState, type Uuid, VALUE_ALTERNATE_KEYS, VALUE_ENVELOPE_KEYS, type ValueAlternate, type ValueAlternateKey, type ValueEnvelope, type ValueEnvelopeKey, type ValueSource, type WorkApprovalDecision, type WorkApprovalFiled, type WorkApprover, type WorkAssignment, type WorkAssignmentField, type WorkChange, type WorkDueState, type WorkGraph, type WorkInboxItem, type WorkInboxKind, type WorkInstantiation, type WorkListFlavour, type WorkListItem, type WorkOrigin, type WorkRecordState, type WorkSlotHold, type WorkState, type WorkTemplateNode, type WorkTemplateRelation, type WorkTurn, type WriteConflict, asPermissionLevel, atLeast, bookingPath, choiceSlug, choiceValuesOf, choicesOf, coerceTypedAnswer, coerceTypedAnswers, coercionLabel, err, fieldKindFor, forgetAllOps, highestLevel, holdsARetiredChoice, indexedDbStore, isDecided, isOwnOp, isRecordsErr, isTheChosen, looksLikeAnId, mayDrag, measureKey, memoryStore, mintClientKey, mintOpId, ok, openCaptureQueue, optionKey, optionLabel, portalPath, publicFormPath, rememberedOpCount, scopeChip, stableFilterKey, tableShapeChanged, useEntityFieldMutation, useEntityFieldRights, useEntityFields, useEntityRecord, useEntityTable, useFieldMutation, useFields, useMergeField, useMyLevel, useMyLevels, useOptionalRecordsClient, useRecord, useRecordMutation, useRecords, useRecordsActor, useRecordsClient, useTable, useTables };
@@ -2103,6 +2103,11 @@ declare const STORE_DOORS: readonly [{
2103
2103
  readonly args: "p_organization_id uuid, p_table_id uuid, p_record_ids uuid[], p_by_id boolean DEFAULT false";
2104
2104
  readonly returns: "TABLE(id uuid, document jsonb, level permission_level)";
2105
2105
  readonly security: "definer";
2106
+ }, {
2107
+ readonly name: "read_records_matching";
2108
+ readonly args: "p_organization_id uuid, p_table_id uuid, p_filter jsonb DEFAULT '{}'::jsonb, p_by_id boolean DEFAULT false, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0";
2109
+ readonly returns: "TABLE(id uuid, document jsonb, level permission_level)";
2110
+ readonly security: "definer";
2106
2111
  }, {
2107
2112
  readonly name: "realtime_topic_admits";
2108
2113
  readonly args: "p_topic text";
@@ -5142,6 +5147,19 @@ interface PortalPrincipal {
5142
5147
  is_active: boolean;
5143
5148
  invited_at: Timestamp;
5144
5149
  revoked_at: Timestamp | null;
5150
+ /**
5151
+ * THE LINK THE OFFICE COPIES FOR THIS PERSON — `/invitations/portal/accept/<token>`, the
5152
+ * path `custom.portal_invite` handed back when they were asked, read off the same
5153
+ * `iam.invitations` row and never re-templated.
5154
+ *
5155
+ * 🚨 `null` IS AN ANSWER, NOT AN ABSENCE, and a screen must say which. It is null when they
5156
+ * have already followed the link, when the office took it back (a revoke withdraws the
5157
+ * invitation in the same statement), when it has expired, or when they were let in through
5158
+ * the server's own magic-link route, which binds without an invitation at all. In every one
5159
+ * of those cases there is genuinely no link to copy — so draw a sentence, never a dead
5160
+ * control. (TAILS-5, 2026-09-21; the gap PORTAL-BIND left named.)
5161
+ */
5162
+ accept_path: string | null;
5145
5163
  }
5146
5164
  /** Everything about ONE portal: what it shows, and who it was opened to. */
5147
5165
  interface PortalCard {
@@ -5223,6 +5241,25 @@ interface AggregateWindow {
5223
5241
  * caller should get from the compiler, not from the database.
5224
5242
  */
5225
5243
  type AggregateFilter = string | number | boolean | null | AggregateWindow;
5244
+ /**
5245
+ * 🚨 THE STORE'S ONE FILTER SHAPE, AND THE ONLY NAME FOR IT.
5246
+ *
5247
+ * An object of Field key -> value. A scalar is an equality, `null` is UNSET
5248
+ * (the third state of a tick box), an object is a half-open time window.
5249
+ *
5250
+ * It is not the aggregate's private shape and never was. `platform.saved_view`
5251
+ * has carried exactly this as `definition -> 'filters'` across five live
5252
+ * surface keys since DOOR-18; `custom.view_declare` writes it;
5253
+ * `custom.agg_view_admits` reads it to decide whether a change belongs to a
5254
+ * saved view; `custom.record_aggregate` takes it as `p_filter` to COMPUTE a
5255
+ * dashboard number; and `custom.read_records_matching` takes it to OPEN the
5256
+ * rows behind that number. One `custom.record_filter_sql` in the database turns
5257
+ * it into SQL for the last two, so the number and the rows cannot disagree.
5258
+ *
5259
+ * Invent a second one and a chart can compute a total whose drill-through
5260
+ * lands somewhere else, which is the only way a drill-through can lie.
5261
+ */
5262
+ type RecordFilter = Record<string, AggregateFilter>;
5226
5263
  /** One measure. `count` counts rows and needs no Field; the rest read one. */
5227
5264
  interface AggregateMeasure {
5228
5265
  op: AggregateOperation;
@@ -5241,6 +5278,19 @@ interface AggregateRow {
5241
5278
  }
5242
5279
  /** The measure key the store answers with, so a chart can find its own series. */
5243
5280
  declare function measureKey(measure: AggregateMeasure): string;
5281
+ /**
5282
+ * THE QUESTION, AS A STABLE STRING — key-sorted JSON of a `RecordFilter`.
5283
+ *
5284
+ * A React parent that rebuilds `{ status: "Cancelled" }` on every render hands
5285
+ * a NEW object every time, and a hook that depends on the object re-reads the
5286
+ * whole page on every render forever. Depending on this instead means the page
5287
+ * is re-read exactly when the QUESTION changed, which is what a person means.
5288
+ *
5289
+ * Nested window objects are sorted too, so `{from, to}` and `{to, from}` are
5290
+ * one question. `undefined` and an empty filter are both `"{}"` — the caller
5291
+ * asked nothing, and there is only one way to ask nothing.
5292
+ */
5293
+ declare function stableFilterKey(filter: RecordFilter | null | undefined): string;
5244
5294
 
5245
5295
  /** The seven shapes a block can take, exactly as `custom.dashboard_kinds()` answers. */
5246
5296
  type DashboardBlockKind = "number" | "bar" | "column" | "line" | "donut" | "table" | "stuck";
@@ -6070,13 +6120,13 @@ interface SavedViewRow {
6070
6120
  view_id: Uuid;
6071
6121
  name: string;
6072
6122
  table_id: Uuid | null;
6073
- filters: Record<string, unknown>;
6123
+ filters: RecordFilter;
6074
6124
  created_at: string;
6075
6125
  }
6076
6126
  /** What `custom.view_declare` is asked for. `view_id` re-states rather than doubling. */
6077
6127
  interface SavedViewSpecIn {
6078
6128
  name: string;
6079
- filters?: Record<string, unknown> | null;
6129
+ filters?: RecordFilter | null;
6080
6130
  definition?: Record<string, unknown> | null;
6081
6131
  view_id?: Uuid | null;
6082
6132
  }
@@ -7085,6 +7135,17 @@ interface RecordsClient {
7085
7135
  */
7086
7136
  list(args: {
7087
7137
  table_id: Uuid;
7138
+ /**
7139
+ * THE STORE'S ONE FILTER SHAPE (`RecordFilter`). Left out, this is the
7140
+ * whole page. Supplied, the store narrows INSIDE its own query — never the
7141
+ * browser, which can only ever filter the rows it was already allowed to
7142
+ * see and would silently drop the rest of the answer.
7143
+ *
7144
+ * It is the same object a saved view stores as `filters` and the same one
7145
+ * `recordAggregate` counts with, so the rows a drill-through opens are the
7146
+ * rows the number on the dashboard counted.
7147
+ */
7148
+ filter?: RecordFilter;
7088
7149
  limit?: number;
7089
7150
  offset?: number;
7090
7151
  }): Promise<RecordsResult<{
@@ -7562,14 +7623,14 @@ interface RecordsClient {
7562
7623
  */
7563
7624
  dashboardRun(args: {
7564
7625
  dashboard_id: Uuid;
7565
- filter?: Record<string, AggregateFilter>;
7626
+ filter?: RecordFilter;
7566
7627
  }): Promise<RecordsResult<DashboardRunResult>>;
7567
7628
  /** The seventh block kind on its own: records that have sat on the same value too long. */
7568
7629
  dashboardStuck(args: {
7569
7630
  table_id: Uuid;
7570
7631
  state_key: string;
7571
7632
  days?: number;
7572
- filter?: Record<string, AggregateFilter>;
7633
+ filter?: RecordFilter;
7573
7634
  limit?: number;
7574
7635
  }): Promise<RecordsResult<StuckRow[]>>;
7575
7636
  /**
@@ -7688,7 +7749,7 @@ interface RecordsClient {
7688
7749
  * A scalar is an equality and an object is a half-open moment window, and
7689
7750
  * either way it lands in the SAME WHERE as visibility.
7690
7751
  */
7691
- filter?: Record<string, AggregateFilter>;
7752
+ filter?: RecordFilter;
7692
7753
  limit?: number;
7693
7754
  }): Promise<RecordsResult<AggregateRow[]>>;
7694
7755
  /** The measures the store itself offers. Asked, never hardcoded in a picker. */
@@ -8430,6 +8491,16 @@ declare function useFields(tableId: Uuid | null, recordType?: string): Async<Fie
8430
8491
  interface UseRecordsOptions {
8431
8492
  pageSize?: number;
8432
8493
  page?: number;
8494
+ /**
8495
+ * THE STORE'S ONE FILTER SHAPE. Left out, this is the whole page. Supplied,
8496
+ * the store narrows in its own query and the hook re-reads when the question
8497
+ * changes — it is never filtered in the browser, which could only ever filter
8498
+ * the rows it had already been handed and would silently drop the rest.
8499
+ *
8500
+ * This is what makes a dashboard number walkable: the same object that
8501
+ * counted it opens it.
8502
+ */
8503
+ filter?: RecordFilter;
8433
8504
  }
8434
8505
  interface UseRecordsState extends Async<{
8435
8506
  rows: ReadRow[];
@@ -8564,4 +8635,4 @@ declare function useFieldMutation(): UseFieldMutation;
8564
8635
  */
8565
8636
  declare function useMergeField(key: string | null, state?: Record<string, unknown>): MergeFieldResolution | null;
8566
8637
 
8567
- export { ABSENCE_REASONS, ACTOR_VOCABULARY, type AbsenceReason, type Actor, type AggregateBucket, type AggregateFilter, type AggregateMeasure, type AggregateOperation, type AggregateRow, type AggregateWindow, type AnonTokenBinding, type BookingAvailability, type BookingDeclared, type BookingSummary, type BookingWindow, COMPUTE_ON, CONTEXT_POLICIES, type CaptureField, type CaptureFileRef, type CaptureOutcome, type CaptureQuestion, type CaptureQueue, type CaptureQueueCounts, type CaptureQueueOptions, type CaptureQueuePorts, type CaptureQueueStore, type CaptureSheetFace, type CaptureSheetSummary, type CaptureSyncReport, type ChecklistDeclared, type ChecklistRequirement, type ChecklistRequirementKind, type ChecklistRoleSpec, type ChecklistRunStarted, type ChecklistRunStep, type ChecklistRunSummary, type ChecklistSpec, type ChecklistStepCompleted, type ChecklistStepSpec, type ChecklistTemplateShape, type ChecklistTemplateSummary, type ChecklistTrigger, type ChecklistTriggerKind, type ChoiceOption, type ChoiceOptions, type CoerceOptions, type Coerced, type CoercedAnswers, type CoercibleField, type CommentThreadRead, type CommentWritten, type ComputeOn, type ContextPolicy, type ConversationScope, type ConversationScopeContext, type CustomFieldTableType, DELIVERIES, type DashboardBlock, type DashboardBlockKind, type DashboardBlockResult, type DashboardRunResult, type DashboardSummary, type Delivery, type DigestPreview, type DocRenderRow, type DocSignatureCheck, type DocSignatureRow, type DocTemplateRow, type DocToken, type DocUnresolvedToken, ENTITY_TOKENS, type EnrichAlternate, type EnrichCell, type EnrichDeclared, type EnrichDueRow, type EnrichRun, type EnrichSource, type Enrichment, type EnrichmentSummary, type EntityFieldRights, type EntityFieldValue, type EntityRecordMatch, type EntityRecordRead, type EntityRecordsFound, type EntityTableFacts, type EntityToken, type ExternalPrincipalCard, FIELD_KINDS, FIELD_SENSITIVITIES, FIELD_SOURCES, FRESHNESS, type Field, type FieldBehavior, type FieldHistoryEntry, type FieldKind, type FieldPatch, type FieldProposal, type FieldRule, type FieldSensitivity, type FieldSource, type FieldTypeWord, type ForbiddenEnvelopeWord, type FormSummary, type Freshness, type HiddenFieldNotice, type HistoryActor, type HistoryActorKind, type HistoryChange, type Home, type ImportBatchResult, type ImportColumnPlan, type ImportFinished, type ImportOpened, type ImportOutcome, type ImportPlan, type ImportPolicy, type ImportProposal, type ImportReport, type ImportRun, type InboundAddress, type InboundDeclared, KERNEL_TABLES, type KernelTableName, type KernelTargets, MERGE_FIELD_MODIFIERS, MERGE_FIELD_SEMANTIC_TYPES, MERGE_FIELD_SOURCES, type MergeField, type MergeFieldModifier, type MergeFieldProvenance, type MergeFieldResolution, type MergeFieldSemanticType, type MergeFieldSource, type MergeFieldTransform, type MissingBehavior, type MyLevel, type MySubscription, type NewEntityFieldDeclaration, type NewFieldDeclaration, ON_DELETE, OVERRIDE_POLICIES, type OnDelete, type OverridePolicy, PARITY_FIELD_TYPES, PERMISSION_LEVELS, PER_VALUE_ACCESS_WORDS, PIPELINE_RULE_KINDS, type ParityFieldType, type ParityFieldTypeDescriptor, type PerValueAccessWord, type PermissionLevel, type PgError, type Pipeline, type PipelineColumn, type PipelineDeclared, type PipelineGate, type PipelineGatePreview, type PipelineMissingField, type PipelineMoveResult, type PipelineRule, type PipelineRuleKind, type PipelineSpec, type PipelineStage, type PipelineVerdict, type PortalCard, type PortalInvitation, type PortalPreviewRow, type PortalPrincipal, type PortalRevocation, type PortalSummary, type PortalTableExposure, type PortalTableRef, type PredictedRefusal, type ProvenancePointer, type PublishBinding, type QueuedCapture, type QueuedCaptureFile, type QueuedCaptureState, type QuietHours, REFUSALS_WORTH_REPEATING, RELATION_BINDINGS, RELATION_CARDINALITIES, RELATION_FLAVORS, RETIRED_ACTOR_WORDS, RULE_NODE_KINDS, RULE_USES, type ReadRow, type ReadValue, type RecordComment, type RecordDocument, type RecordHistoryEntry, type RecordRead, type RecordRevision, type RecordScopeComment, type RecordScopeContext, type RecordScopeField, type RecordScopeHistoryEntry, type RecordScopeRelation, type RecordScopeWithheld, type RecordsActor, type RecordsChangeSink, type RecordsConfig, type RecordsDataSource, type RecordsError, type RecordsErrorCode, type RecordsErrorSink, type RecordsFilter, RecordsProvider, type RecordsProviderProps, type RecordsRealtimePort, type RecordsResolverPort, type RecordsResponse, type RecordsResult, type RecordsTableQuery, type RegisteredTable, type Relation, type RelationBinding, type RelationCardinality, type RelationCarries, type RelationCoordinate, type RelationDisplay, type RelationFlavor, type RelationProperties, type RelationTarget, type ResolutionTriple, type ResolvedPublishBinding, type RestorePreview, type RestoreResult, type RetiredActorWord, type Rule, type RuleAnswer, type RuleExpression, type RuleNodeKind, type RuleUse, STAGE_RULE_ENFORCEMENT, STAGE_RULE_ON_FAIL, STORAGE_MODES, STORE_DOORS, STORE_KNOBS, STORE_REFUSAL_CODES, type SavedViewRow, type SavedViewSpecIn, type StagePending, type StagePendingOnBoard, type StageRuleEnforcement, type StageRuleOnFail, type StageRuleWarning, type StaleWriteDetail, type StorageMode, type StoreDoorName, type StoreRefusalCode, type StoredRecord, type StuckRow, type Subscription, type SubscriptionBlock, type SubscriptionCadence, type SubscriptionSpec, TABLE_DISPLAYS, TABLE_ORIGINS, TABLE_TYPES, type Table, type TableCapacity, type TableDisplay, type TableOrigin, type TableProposal, type TableType, type Timestamp, type UseEntityFieldMutation, type UseFieldMutation, type UseRecordMutation, type UseRecordsOptions, type UseRecordsState, type Uuid, VALUE_ALTERNATE_KEYS, VALUE_ENVELOPE_KEYS, type ValueAlternate, type ValueAlternateKey, type ValueEnvelope, type ValueEnvelopeKey, type ValueSource, type WorkApprovalDecision, type WorkApprovalFiled, type WorkApprover, type WorkAssignment, type WorkAssignmentField, type WorkChange, type WorkDueState, type WorkGraph, type WorkInboxItem, type WorkInboxKind, type WorkInstantiation, type WorkListFlavour, type WorkListItem, type WorkOrigin, type WorkRecordState, type WorkSlotHold, type WorkState, type WorkTemplateNode, type WorkTemplateRelation, type WorkTurn, type WriteConflict, asPermissionLevel, atLeast, bookingPath, choiceSlug, choiceValuesOf, choicesOf, coerceTypedAnswer, coerceTypedAnswers, coercionLabel, err, fieldKindFor, forgetAllOps, highestLevel, holdsARetiredChoice, indexedDbStore, isDecided, isOwnOp, isRecordsErr, isTheChosen, looksLikeAnId, mayDrag, measureKey, memoryStore, mintClientKey, mintOpId, ok, openCaptureQueue, optionKey, optionLabel, portalPath, publicFormPath, rememberedOpCount, scopeChip, tableShapeChanged, useEntityFieldMutation, useEntityFieldRights, useEntityFields, useEntityRecord, useEntityTable, useFieldMutation, useFields, useMergeField, useMyLevel, useMyLevels, useOptionalRecordsClient, useRecord, useRecordMutation, useRecords, useRecordsActor, useRecordsClient, useTable, useTables };
8638
+ export { ABSENCE_REASONS, ACTOR_VOCABULARY, type AbsenceReason, type Actor, type AggregateBucket, type AggregateFilter, type AggregateMeasure, type AggregateOperation, type AggregateRow, type AggregateWindow, type AnonTokenBinding, type BookingAvailability, type BookingDeclared, type BookingSummary, type BookingWindow, COMPUTE_ON, CONTEXT_POLICIES, type CaptureField, type CaptureFileRef, type CaptureOutcome, type CaptureQuestion, type CaptureQueue, type CaptureQueueCounts, type CaptureQueueOptions, type CaptureQueuePorts, type CaptureQueueStore, type CaptureSheetFace, type CaptureSheetSummary, type CaptureSyncReport, type ChecklistDeclared, type ChecklistRequirement, type ChecklistRequirementKind, type ChecklistRoleSpec, type ChecklistRunStarted, type ChecklistRunStep, type ChecklistRunSummary, type ChecklistSpec, type ChecklistStepCompleted, type ChecklistStepSpec, type ChecklistTemplateShape, type ChecklistTemplateSummary, type ChecklistTrigger, type ChecklistTriggerKind, type ChoiceOption, type ChoiceOptions, type CoerceOptions, type Coerced, type CoercedAnswers, type CoercibleField, type CommentThreadRead, type CommentWritten, type ComputeOn, type ContextPolicy, type ConversationScope, type ConversationScopeContext, type CustomFieldTableType, DELIVERIES, type DashboardBlock, type DashboardBlockKind, type DashboardBlockResult, type DashboardRunResult, type DashboardSummary, type Delivery, type DigestPreview, type DocRenderRow, type DocSignatureCheck, type DocSignatureRow, type DocTemplateRow, type DocToken, type DocUnresolvedToken, ENTITY_TOKENS, type EnrichAlternate, type EnrichCell, type EnrichDeclared, type EnrichDueRow, type EnrichRun, type EnrichSource, type Enrichment, type EnrichmentSummary, type EntityFieldRights, type EntityFieldValue, type EntityRecordMatch, type EntityRecordRead, type EntityRecordsFound, type EntityTableFacts, type EntityToken, type ExternalPrincipalCard, FIELD_KINDS, FIELD_SENSITIVITIES, FIELD_SOURCES, FRESHNESS, type Field, type FieldBehavior, type FieldHistoryEntry, type FieldKind, type FieldPatch, type FieldProposal, type FieldRule, type FieldSensitivity, type FieldSource, type FieldTypeWord, type ForbiddenEnvelopeWord, type FormSummary, type Freshness, type HiddenFieldNotice, type HistoryActor, type HistoryActorKind, type HistoryChange, type Home, type ImportBatchResult, type ImportColumnPlan, type ImportFinished, type ImportOpened, type ImportOutcome, type ImportPlan, type ImportPolicy, type ImportProposal, type ImportReport, type ImportRun, type InboundAddress, type InboundDeclared, KERNEL_TABLES, type KernelTableName, type KernelTargets, MERGE_FIELD_MODIFIERS, MERGE_FIELD_SEMANTIC_TYPES, MERGE_FIELD_SOURCES, type MergeField, type MergeFieldModifier, type MergeFieldProvenance, type MergeFieldResolution, type MergeFieldSemanticType, type MergeFieldSource, type MergeFieldTransform, type MissingBehavior, type MyLevel, type MySubscription, type NewEntityFieldDeclaration, type NewFieldDeclaration, ON_DELETE, OVERRIDE_POLICIES, type OnDelete, type OverridePolicy, PARITY_FIELD_TYPES, PERMISSION_LEVELS, PER_VALUE_ACCESS_WORDS, PIPELINE_RULE_KINDS, type ParityFieldType, type ParityFieldTypeDescriptor, type PerValueAccessWord, type PermissionLevel, type PgError, type Pipeline, type PipelineColumn, type PipelineDeclared, type PipelineGate, type PipelineGatePreview, type PipelineMissingField, type PipelineMoveResult, type PipelineRule, type PipelineRuleKind, type PipelineSpec, type PipelineStage, type PipelineVerdict, type PortalCard, type PortalInvitation, type PortalPreviewRow, type PortalPrincipal, type PortalRevocation, type PortalSummary, type PortalTableExposure, type PortalTableRef, type PredictedRefusal, type ProvenancePointer, type PublishBinding, type QueuedCapture, type QueuedCaptureFile, type QueuedCaptureState, type QuietHours, REFUSALS_WORTH_REPEATING, RELATION_BINDINGS, RELATION_CARDINALITIES, RELATION_FLAVORS, RETIRED_ACTOR_WORDS, RULE_NODE_KINDS, RULE_USES, type ReadRow, type ReadValue, type RecordComment, type RecordDocument, type RecordFilter, type RecordHistoryEntry, type RecordRead, type RecordRevision, type RecordScopeComment, type RecordScopeContext, type RecordScopeField, type RecordScopeHistoryEntry, type RecordScopeRelation, type RecordScopeWithheld, type RecordsActor, type RecordsChangeSink, type RecordsConfig, type RecordsDataSource, type RecordsError, type RecordsErrorCode, type RecordsErrorSink, type RecordsFilter, RecordsProvider, type RecordsProviderProps, type RecordsRealtimePort, type RecordsResolverPort, type RecordsResponse, type RecordsResult, type RecordsTableQuery, type RegisteredTable, type Relation, type RelationBinding, type RelationCardinality, type RelationCarries, type RelationCoordinate, type RelationDisplay, type RelationFlavor, type RelationProperties, type RelationTarget, type ResolutionTriple, type ResolvedPublishBinding, type RestorePreview, type RestoreResult, type RetiredActorWord, type Rule, type RuleAnswer, type RuleExpression, type RuleNodeKind, type RuleUse, STAGE_RULE_ENFORCEMENT, STAGE_RULE_ON_FAIL, STORAGE_MODES, STORE_DOORS, STORE_KNOBS, STORE_REFUSAL_CODES, type SavedViewRow, type SavedViewSpecIn, type StagePending, type StagePendingOnBoard, type StageRuleEnforcement, type StageRuleOnFail, type StageRuleWarning, type StaleWriteDetail, type StorageMode, type StoreDoorName, type StoreRefusalCode, type StoredRecord, type StuckRow, type Subscription, type SubscriptionBlock, type SubscriptionCadence, type SubscriptionSpec, TABLE_DISPLAYS, TABLE_ORIGINS, TABLE_TYPES, type Table, type TableCapacity, type TableDisplay, type TableOrigin, type TableProposal, type TableType, type Timestamp, type UseEntityFieldMutation, type UseFieldMutation, type UseRecordMutation, type UseRecordsOptions, type UseRecordsState, type Uuid, VALUE_ALTERNATE_KEYS, VALUE_ENVELOPE_KEYS, type ValueAlternate, type ValueAlternateKey, type ValueEnvelope, type ValueEnvelopeKey, type ValueSource, type WorkApprovalDecision, type WorkApprovalFiled, type WorkApprover, type WorkAssignment, type WorkAssignmentField, type WorkChange, type WorkDueState, type WorkGraph, type WorkInboxItem, type WorkInboxKind, type WorkInstantiation, type WorkListFlavour, type WorkListItem, type WorkOrigin, type WorkRecordState, type WorkSlotHold, type WorkState, type WorkTemplateNode, type WorkTemplateRelation, type WorkTurn, type WriteConflict, asPermissionLevel, atLeast, bookingPath, choiceSlug, choiceValuesOf, choicesOf, coerceTypedAnswer, coerceTypedAnswers, coercionLabel, err, fieldKindFor, forgetAllOps, highestLevel, holdsARetiredChoice, indexedDbStore, isDecided, isOwnOp, isRecordsErr, isTheChosen, looksLikeAnId, mayDrag, measureKey, memoryStore, mintClientKey, mintOpId, ok, openCaptureQueue, optionKey, optionLabel, portalPath, publicFormPath, rememberedOpCount, scopeChip, stableFilterKey, tableShapeChanged, useEntityFieldMutation, useEntityFieldRights, useEntityFields, useEntityRecord, useEntityTable, useFieldMutation, useFields, useMergeField, useMyLevel, useMyLevels, useOptionalRecordsClient, useRecord, useRecordMutation, useRecords, useRecordsActor, useRecordsClient, useTable, useTables };
@@ -530,6 +530,7 @@ var STORE_DOORS = [
530
530
  { name: "read_record", args: "p_organization_id uuid, p_record_id uuid, p_by_id boolean DEFAULT false", returns: "jsonb", security: "definer" },
531
531
  { name: "read_records", args: "p_organization_id uuid, p_table_id uuid, p_by_id boolean DEFAULT false, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0", returns: "TABLE(id uuid, document jsonb, level permission_level)", security: "definer" },
532
532
  { name: "read_records_by_ids", args: "p_organization_id uuid, p_table_id uuid, p_record_ids uuid[], p_by_id boolean DEFAULT false", returns: "TABLE(id uuid, document jsonb, level permission_level)", security: "definer" },
533
+ { name: "read_records_matching", args: "p_organization_id uuid, p_table_id uuid, p_filter jsonb DEFAULT '{}'::jsonb, p_by_id boolean DEFAULT false, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0", returns: "TABLE(id uuid, document jsonb, level permission_level)", security: "definer" },
533
534
  { name: "realtime_topic_admits", args: "p_topic text", returns: "boolean", security: "definer" },
534
535
  { name: "record_aggregate", args: "p_organization_id uuid, p_table_id uuid, p_group_by jsonb DEFAULT '[]'::jsonb, p_measures jsonb DEFAULT '[]'::jsonb, p_bucket jsonb DEFAULT NULL::jsonb, p_filter jsonb DEFAULT '{}'::jsonb, p_limit integer DEFAULT 200, p_required text DEFAULT 'viewer'::text", returns: "TABLE(groups jsonb, measures jsonb, row_count bigint)", security: "definer" },
535
536
  { name: "record_applicability", args: "p_organization_id uuid, p_record_id uuid", returns: "TABLE(rule_id uuid, rule_name text, rule_version integer, applies boolean, answer jsonb)", security: "invoker" },
@@ -1859,6 +1860,15 @@ var DOORS = {
1859
1860
  // live Postgres function makes every existing call ambiguous — `is not unique`. Same
1860
1861
  // ladder, same level, same masking, same page ceiling.
1861
1862
  readRecordsByIds: "read_records_by_ids",
1863
+ // THE SAME READ DOOR, ADDRESSED BY A QUESTION. `custom.read_records_matching`
1864
+ // takes the store's one filter shape (`RecordFilter` — the object
1865
+ // `platform.saved_view` carries as `filters` and `custom.record_aggregate`
1866
+ // takes as `p_filter`) and narrows the page INSIDE its own query, in the same
1867
+ // WHERE as Visibility. A separate NAME for the same reason as above. It is
1868
+ // what makes a number on a dashboard walkable: the filter is evaluated by
1869
+ // `custom.record_filter_sql`, the one body `custom.agg_sql` also calls, so the
1870
+ // rows it opens are the rows the number counted.
1871
+ readRecordsMatching: "read_records_matching",
1862
1872
  // DOOR-8, the two clocks. `p_recorded_at` is what the store SAID then;
1863
1873
  // `p_world_on` is what was TRUE of the world on that date, read out of dated
1864
1874
  // values. A client that answered either one itself would be guessing.
@@ -2550,12 +2560,13 @@ function createRecordsClient(config) {
2550
2560
  })
2551
2561
  );
2552
2562
  },
2553
- async list({ table_id, limit = 50, offset = 0 }) {
2563
+ async list({ table_id, filter, limit = 50, offset = 0 }) {
2554
2564
  const door = await callDoor(
2555
- DOORS.readRecords,
2565
+ DOORS.readRecordsMatching,
2556
2566
  {
2557
2567
  p_organization_id: org,
2558
2568
  p_table_id: table_id,
2569
+ p_filter: filter ?? {},
2559
2570
  p_limit: limit,
2560
2571
  p_offset: offset
2561
2572
  },
@@ -4264,6 +4275,27 @@ function useRecordsActor() {
4264
4275
 
4265
4276
  // src/react/hooks.ts
4266
4277
  import { useCallback, useEffect, useMemo as useMemo2, useRef, useState, useSyncExternalStore } from "react";
4278
+
4279
+ // src/aggregate.ts
4280
+ function measureKey(measure) {
4281
+ return measure.op === "count" ? "count" : `${measure.op}_${measure.key ?? ""}`;
4282
+ }
4283
+ function stableFilterKey(filter) {
4284
+ if (!filter) return "{}";
4285
+ const keys = Object.keys(filter).sort();
4286
+ if (keys.length === 0) return "{}";
4287
+ const parts = keys.map((key) => {
4288
+ const value = filter[key];
4289
+ if (value !== null && typeof value === "object") {
4290
+ const window2 = value;
4291
+ return `${JSON.stringify(key)}:{"from":${JSON.stringify(window2.from ?? null)},"to":${JSON.stringify(window2.to ?? null)}}`;
4292
+ }
4293
+ return `${JSON.stringify(key)}:${JSON.stringify(value ?? null)}`;
4294
+ });
4295
+ return `{${parts.join(",")}}`;
4296
+ }
4297
+
4298
+ // src/react/hooks.ts
4267
4299
  function useAsync(run, deps) {
4268
4300
  const client = useRecordsClient();
4269
4301
  const [state, setState] = useState(
@@ -4372,16 +4404,21 @@ function useRecords(tableId, options = {}) {
4372
4404
  const client = useRecordsClient();
4373
4405
  const pageSize = options.pageSize ?? 50;
4374
4406
  const page = options.page ?? 0;
4407
+ const filterKey = stableFilterKey(options.filter);
4375
4408
  const base = useAsync(
4376
4409
  async (c) => {
4377
4410
  if (!tableId) return { ok: true, data: { rows: [], total: null } };
4378
4411
  return c.list({
4379
4412
  table_id: tableId,
4413
+ ...filterKey === "{}" ? {} : { filter: options.filter },
4380
4414
  limit: pageSize,
4381
4415
  offset: page * pageSize
4382
4416
  });
4383
4417
  },
4384
- [tableId, pageSize, page]
4418
+ // The QUESTION, not the object: a parent that rebuilds `{status: "Cancelled"}`
4419
+ // on every render must not re-read the page on every render, and a parent
4420
+ // that changes the question must re-read on the first one.
4421
+ [tableId, pageSize, page, filterKey]
4385
4422
  );
4386
4423
  const realtime = client.config.realtime;
4387
4424
  const { reload, setData } = base;
@@ -4971,11 +5008,6 @@ function portalPath(slug) {
4971
5008
  return `/portal/c/${slug}`;
4972
5009
  }
4973
5010
 
4974
- // src/aggregate.ts
4975
- function measureKey(measure) {
4976
- return measure.op === "count" ? "count" : `${measure.op}_${measure.key ?? ""}`;
4977
- }
4978
-
4979
5011
  // src/capture-queue.ts
4980
5012
  var DB_NAME = "matrx-capture";
4981
5013
  var DB_VERSION = 1;
@@ -5332,6 +5364,7 @@ export {
5332
5364
  publicFormPath,
5333
5365
  rememberedOpCount,
5334
5366
  scopeChip,
5367
+ stableFilterKey,
5335
5368
  tableShapeChanged,
5336
5369
  useEntityFieldMutation,
5337
5370
  useEntityFieldRights,