---
id: CAP-PFM-QRY-012
title: Combine saved questions in a dashboard
feature: FEAT-PFM-QRY-04
product_area: platform
module: queries
revision: 1
status: draft
product_intent: confirmed
implementation_evidence: observed
supersedes:
  - CAP-RPT-DSH-001
  - CAP-RPT-DSH-002
  - CAP-RPT-DSH-003
  - CAP-RPT-DSH-004
  - CAP-RPT-DSH-005
  - CAP-RPT-DSH-006
  - CAP-RPT-DSH-007
  - CAP-RPT-DSH-008
  - CAP-RPT-DSH-009
  - CAP-RPT-DSH-010
  - CAP-RPT-DSH-011
  - CAP-RPT-DSH-012
  - CAP-RPT-DSH-013
  - CAP-RPT-DSH-014
  - CAP-RPT-DSH-015
  - CAP-RPT-DSH-016
  - CAP-RPT-DSH-017
  - CAP-RPT-DSH-018
  - CAP-RPT-DSH-019
  - CAP-RPT-DSH-020
  - CAP-RPT-DSH-021
  - CAP-RPT-DSH-022
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-platform:docs/queries/reports.md#6. Dashboards (Andrew, 2026-10-18)'
  - 'services-platform:docs/milestones/plans/RPT-M1-plan.md#D3'
purpose: Present several saved questions together while keeping their source dependencies and viewer access visible.
outcomes:
  - Several questions contribute to one presentation.
  - Sharing respects all source audiences.
  - Unavailable widget data can fail independently.
concepts:
  - CON-PFM-QRY-003
actors:
  - ACT-PFM-013
  - ACT-PFM-007
surfaces:
  - console
  - api
preconditions: []
postconditions: []
permissions:
  - key: platform.reports.use
    where_checked: api
    scope: tenant
  - key: platform.reports.share
    where_checked: service
    scope: record
  - key: platform.reports.manage
    where_checked: service
    scope: record
rules:
  - id: BR-CAP-PFM-QRY-012-01
    proved_by: [ATS-PFM-QRY-012-01, TST-PFM-QRY-233]
    statement: >-
      Dashboards are reports without a single direct saved-query source, reject that direct source field, and
      differ from other report kinds that require it.
    kind: validation
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/reports.e2e.spec.js#refuses a dashboard naming a
      saved_query_id of its own as 400
    origin: 'services-platform:docs/queries/reports.md#6. Dashboards (Andrew, 2026-10-18)'
  - id: BR-CAP-PFM-QRY-012-02
    proved_by: [ATS-PFM-QRY-012-02, TST-PFM-QRY-233]
    statement: >-
      Dashboard saves record up to fifty distinct widget sources in first-widget order and reject larger
      source sets without writing.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/reports.e2e.spec.js#answers its sources once each, in widget
      order, with their names and applications
    origin: 'services-platform:docs/queries/reports.md#6. Dashboards (Andrew, 2026-10-18)'
  - id: BR-CAP-PFM-QRY-012-03
    proved_by: [ATS-PFM-QRY-012-03, TST-PFM-QRY-096, TST-PFM-QRY-233, TST-PFM-QRY-335]
    statement: >-
      Every widget source must be visible to the author, and an inaccessible source produces a refusal
      locating its widget.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/reports.e2e.spec.js#refuses a widget over a saved query the
      caller may not see as 400 naming the widget at definition
    origin: 'services-platform:docs/queries/reports.md#6. Dashboards (Andrew, 2026-10-18)'
  - id: BR-CAP-PFM-QRY-012-04
    proved_by: [ATS-PFM-QRY-011-15, ATS-PFM-QRY-012-04, ATS-PFM-QRY-012-11, TST-PFM-QRY-054, TST-PFM-QRY-095, TST-PFM-QRY-233]
    statement: >-
      Dashboard audiences cannot exceed any source audience, with the first narrower source in widget order
      identified.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/reports.e2e.spec.js#refuses a dashboard shared wider than
      one of its sources as 409, naming that source
    origin: 'services-platform:docs/queries/reports.md#6. Dashboards (Andrew, 2026-10-18)'
  - id: BR-CAP-PFM-QRY-012-05
    proved_by: [ATS-PFM-QRY-012-05, TST-PFM-QRY-233]
    statement: A query used by a dashboard source cannot be deleted while that dependency remains.
    kind: policy
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/reports.e2e.spec.js#refuses to delete a saved query one of
      its widgets draws on as 409 saved_query_reported
    origin: 'services-platform:docs/queries/reports.md#6. Dashboards (Andrew, 2026-10-18)'
  - id: BR-CAP-PFM-QRY-012-06
    proved_by: [ATS-PFM-QRY-012-06, TST-PFM-QRY-233]
    statement: Dashboard change warnings reflect source-definition changes rather than source renames alone.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/reports.e2e.spec.js#does not answer saved_query_changed
      after a source is only renamed, because its data did not change (DEF-RPT-0640)
    origin: none
  - id: BR-CAP-PFM-QRY-012-07
    proved_by: [ATS-PFM-QRY-012-07, TST-PFM-QRY-335]
    statement: >-
      For a source the reader cannot see, dashboard source metadata returns only identity and change state,
      withholding its name.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/reports/report-library.integration.spec.js#answers
      a reader only the id and the change of a source narrowed since the dashboard was shared
    origin: 'services-platform:docs/queries/reports.md#6. Dashboards (Andrew, 2026-10-18)'
  - id: BR-CAP-PFM-QRY-012-08
    proved_by: [ATS-PFM-QRY-012-08]
    statement: >-
      A dashboard with sources passes catalog filtering when at least one visible source has an accessible
      base dataset; a dashboard without sources also passes.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/queries/services/reports/report-library.ts:readableReports'
    origin: 'services-platform:docs/milestones/plans/RPT-M1-plan.md#D3'
  - id: BR-CAP-PFM-QRY-012-09
    proved_by: [ATS-PFM-QRY-012-09, ATS-PFM-QRY-012-12, ATS-PFM-QRY-013-13, TST-PFM-QRY-097]
    statement: >-
      Widgets run their own saved queries as the viewer, apply narrowing dashboard filters and fail
      independently when a source is unavailable.
    kind: policy
    enforced_at:
      - service
      - console
    must_prove: true
    provenance: documented
    source: 'services-platform:docs/queries/reports.md#6. Dashboards'
    origin: 'services-platform:docs/queries/reports.md#6. Dashboards (Andrew, 2026-10-18)'
  - id: BR-CAP-PFM-QRY-012-10
    proved_by: [ATS-PFM-QRY-012-10, TST-PFM-QRY-233]
    statement: Platform preserves dashboard layout content exactly and interprets only widget source-query identities.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/reports.e2e.spec.js#answers the definition exactly as it was
      sent, widgets, filters and layouts untouched
    origin: 'services-platform:docs/queries/reports.md#6. Dashboards (Andrew, 2026-10-18)'
scenarios:
  - id: SC-CAP-PFM-QRY-012-01
    given: A dashboard includes a source visible only to selected finance users.
    when: Its author attempts organization sharing.
    then: The refusal identifies the source with the narrower audience.
    provenance: test
    source: >-
      react-console:acceptance/reporting/playwright/journeys/catalog-and-sharing/RPT-ACC-0009.spec.ts#RPT-ACC-0009
edge_cases: []
constraints: []
depends_on:
  - CAP-PFM-QRY-011
  - CAP-PFM-QRY-007
related:
  - CAP-PFM-QRY-011
  - CAP-PFM-QRY-013
journeys: []
open_questions: []
operations:
  - createReport
  - updateReport
  - getReport
tables:
  - report-sources.table.ts
evidence:
  - >-
    Pinned reference:
    react-console:acceptance/reporting/playwright/journeys/catalog-and-sharing/RPT-ACC-0009.spec.ts
  - 'Pinned reference: services-platform:docs/milestones/plans/RPT-M1-plan.md'
  - 'Pinned reference: services-platform:docs/queries/reports.md'
  - 'Pinned reference: services-platform:modules/queries/services/reports/report-library.ts'
  - 'Pinned reference: services-platform:modules/queries/tests/e2e/reports.e2e.spec.js'
  - >-
    Pinned reference:
    services-platform:modules/queries/tests/integration/services/reports/report-library.integration.spec.js
controls: [TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-DAT-004, TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-LOG-004, TC-LOG-005, TC-PI-001, TC-PI-003, TC-PI-005, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-VEN-001, TC-VEN-002, TC-VEN-003]
exercised_by: [FAS-PFM-QRY-04-01, FAS-PFM-QRY-04-03, FAS-PFM-QRY-04-04, FAS-PFM-QRY-04-05]
suites: [TST-PFM-QRY-054, TST-PFM-QRY-095, TST-PFM-QRY-096, TST-PFM-QRY-097, TST-PFM-QRY-233, TST-PFM-QRY-335]
---

# Combine saved questions in a dashboard

## Purpose

Present several saved questions together while keeping their source dependencies and viewer access visible.

## How It Works

An author arranges widgets in a dashboard. The saved layout identifies the questions each widget uses. Platform extracts those source dependencies while preserving the layout. Sharing is checked against every source audience. Readers run each widget with their own access. A source that becomes unavailable can fail independently of the others. Source changes flag the dashboard for review. The catalog’s source check permits an empty dashboard and does not prove every widget will execute successfully.

## Relationships

Dashboard composition specializes the report catalog and resolves several saved-question sources.
