---
id: CAP-PFM-QRY-009
title: Organize reusable views of record lists
feature: FEAT-PFM-QRY-03
product_area: platform
module: queries
revision: 1
status: draft
product_intent: proposed
implementation_evidence: observed
supersedes: []
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-platform:docs/explorer.md#2. Who may see and change a view (Andrew, 2026-10-11)'
purpose: 'Let staff retain the columns, ordering and filters they use for recurring record-list work.'
outcomes:
  - Useful list arrangements can be recalled.
  - Recipe anchors preserve record grain.
  - Stale definitions remain available for repair.
concepts:
  - CON-PFM-QRY-002
actors:
  - ACT-PFM-013
  - ACT-PFM-007
surfaces:
  - console
  - api
preconditions: []
postconditions: []
permissions:
  - key: platform.explorer-views.use
    where_checked: api
    scope: tenant
  - key: platform.explorer-views.share
    where_checked: service
    scope: record
  - key: platform.explorer-views.manage
    where_checked: service
    scope: record
  - key: <application>.<dataset>.query (the owner's key)
    where_checked: service
    scope: tenant
rules:
  - id: BR-CAP-PFM-QRY-009-01
    proved_by: [ATS-PFM-QRY-009-01, TST-PFM-QRY-210]
    statement: >-
      A saved view requires a live recipe and its dataset, rejecting missing or retired recipes and a dataset
      that differs from its anchor.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/explorer/tests/e2e/explorer-views-api.e2e.spec.js#refuses a body whose dataset
      is not the recipe’s as 400
    origin: none
  - id: BR-CAP-PFM-QRY-009-02
    proved_by: [ATS-PFM-QRY-009-02, TST-PFM-QRY-211]
    statement: Explorer rejects a recipe join that repeats base records and identifies the incompatible join.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/explorer/tests/integration/services/definitions/recipe-anchors.integration.spec.js#refuses
      a recipe whose joins answer a base record once per child
    origin: none
  - id: BR-CAP-PFM-QRY-009-03
    proved_by: [ATS-PFM-QRY-009-03, TST-PFM-QRY-210]
    statement: >-
      Every view save validates its definition against the reader’s resolved recipe model and locates
      unsupported fields.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/explorer/tests/e2e/explorer-views-api.e2e.spec.js#refuses a definition naming
      a field the dataset has not got as 400
    origin: none
  - id: BR-CAP-PFM-QRY-009-04
    proved_by: [ATS-PFM-QRY-008-12, ATS-PFM-QRY-009-04, ATS-PFM-QRY-009-12, TST-PFM-QRY-211]
    statement: >-
      Reading a view returns model problems for repair rather than rejecting the definition, and an absent
      recipe produces a recipe-missing problem.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/explorer/tests/integration/services/definitions/recipe-anchors.integration.spec.js#answers
      recipe_missing for a recipe that has gone, rather than an error
    origin: none
  - id: BR-CAP-PFM-QRY-009-05
    proved_by: [ATS-PFM-QRY-009-05, TST-PFM-QRY-210]
    statement: >-
      Private views remain owner-only and appear missing to others, while workspace-shared views are readable
      to users with dataset access.
    kind: permission
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/explorer/tests/e2e/explorer-views-api.e2e.spec.js#answers 404, not 403, for
      another person’s private view
    origin: none
  - id: BR-CAP-PFM-QRY-009-06
    proved_by: [ATS-PFM-QRY-009-06, TST-PFM-QRY-210]
    statement: >-
      View sharing requires share permission, maintaining another owner’s shared view requires manage
      permission, and ownership and dataset cannot change.
    kind: permission
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/explorer/tests/e2e/explorer-views-api.e2e.spec.js#refuses sharing a view
      without the share permission as 403
    origin: 'services-platform:docs/explorer.md#2. Who may see and change a view (Andrew, 2026-10-11)'
  - id: BR-CAP-PFM-QRY-009-07
    proved_by: [ATS-PFM-QRY-009-07, ATS-PFM-QRY-009-13, ATS-PFM-QRY-010-13, TST-PFM-QRY-210]
    statement: Explorer operations require access to the base and joined datasets of the anchored recipe.
    kind: permission
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/explorer/tests/e2e/explorer-views-api.e2e.spec.js#refuses a joined recipe to a
      caller who may not query a dataset it joins to, as 403
    origin: none
  - id: BR-CAP-PFM-QRY-009-08
    proved_by: [ATS-PFM-QRY-009-08, TST-PFM-QRY-218]
    statement: >-
      Views accept names of one to 120 characters, one to fifty columns, one to five sort keys and page sizes
      of ten, twenty-five, fifty or one hundred, store no current position, and are capped at two hundred per
      dataset and workspace.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: documented
    source: 'services-platform:docs/explorer.md#1. A saved view'
    origin: none
    note: >-
      Tests cover view-count, name and team limits. The cited contract and view schema supply the column,
      ordering and page-size bounds.
  - id: BR-CAP-PFM-QRY-009-09
    proved_by: [ATS-PFM-QRY-009-09, TST-PFM-QRY-210, TST-PFM-QRY-218]
    statement: Team-based view sharing remains reserved and is rejected.
    kind: validation
    enforced_at:
      - api
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/explorer/tests/e2e/explorer-views-api.e2e.spec.js#refuses a team id, which is
      reserved, as 400
    origin: 'services-platform:docs/explorer.md#1. A saved view (Andrew, 2026-10-10)'
  - id: BR-CAP-PFM-QRY-009-10
    proved_by: [ATS-PFM-QRY-009-10, TST-PFM-QRY-210]
    statement: >-
      Replacement and patch operations require the read version, refusing missing versions or stale saves
      without changing the view.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/explorer/tests/e2e/explorer-views-api.e2e.spec.js#refuses a replacement that
      states no version as 400 MissingVersion, never as a server fault
    origin: none
  - id: BR-CAP-PFM-QRY-009-11
    proved_by: [ATS-PFM-QRY-009-11, TST-PFM-QRY-209]
    statement: >-
      Personal Explorer preferences replace up to twenty pinned views and an opening view against a read
      version, starting at zero, and retain references without checking whether those views still exist.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/explorer/tests/e2e/explorer-preferences-api.e2e.spec.js#refuses a later save
      that states no version as 409, so nothing is overwritten unread
    origin: none
scenarios:
  - id: SC-CAP-PFM-QRY-009-01
    given: A saved view includes a custom field that is subsequently archived.
    when: Its owner reads the view.
    then: The view remains available with a repair problem for the retired field.
    provenance: documented
    source: 'services-platform:docs/explorer.md#What a definition is judged against, and how a view can go stale'
edge_cases: []
constraints: []
depends_on:
  - CAP-PFM-QRY-008
  - CAP-PFM-QRY-002
related:
  - CAP-PFM-QRY-008
  - CAP-PFM-QRY-010
journeys:
  - JNY-PFM-QRY-003
open_questions: []
operations:
  - createExplorerView
  - listExplorerViews
  - getExplorerView
  - updateExplorerView
  - patchExplorerView
  - deleteExplorerView
  - getExplorerViewPreferences
  - putExplorerViewPreferences
tables:
  - explorer-views.table.ts
  - explorer-view-preferences.table.ts
evidence:
  - 'Pinned reference: services-platform:docs/explorer.md'
  - 'Pinned reference: services-platform:modules/explorer/tests/e2e/explorer-preferences-api.e2e.spec.js'
  - 'Pinned reference: services-platform:modules/explorer/tests/e2e/explorer-views-api.e2e.spec.js'
  - >-
    Pinned reference:
    services-platform:modules/explorer/tests/integration/services/definitions/recipe-anchors.integration.spec.js
controls: [TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-DAT-001, TC-DAT-003, TC-DAT-004, TC-LOG-004, TC-LOG-005, TC-PI-001, TC-PI-003, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-PRV-004, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-VEN-001, TC-VEN-002, TC-VEN-003]
exercised_by: [FAS-PFM-QRY-03-01, FAS-PFM-QRY-03-02, FAS-PFM-QRY-03-03, FAS-PFM-QRY-03-04, FAS-PFM-QRY-03-05]
suites: [TST-PFM-QRY-209, TST-PFM-QRY-210, TST-PFM-QRY-211, TST-PFM-QRY-218]
---

# Organize reusable views of record lists

## Purpose

Let staff retain the columns, ordering and filters they use for recurring record-list work.

## How It Works

A person opens a record list and chooses a view suited to their task. Saving the arrangement keeps its columns, ordering and filters with a recipe anchor. Platform checks the definition against that recipe’s resolved model. A stale view can still be opened with problems for repair. People can share their own useful arrangements with the workspace. Administrators maintain shared views when their authors move on. Personal pins and the opening view organize each person’s list experience. Navigation position is retained separately from the view.

## Relationships

Reusable views supply the list arrangement used alongside navigation and selection.
