type TenantEntitySection {
  id: ID!
  sectionSlug: String!
  heading: String!
  bodyMd: String!
  position: Int!
  facetType: String
  status: String!
  lastSourceAt: AWSDateTime
  updatedAt: AWSDateTime!
}

type TenantEntityPage {
  id: ID!
  tenantId: ID!
  type: String!
  entitySubtype: String!
  slug: String!
  title: String!
  summary: String
  bodyMd: String
  status: String!
  updatedAt: AWSDateTime!
  sections: [TenantEntitySection!]!
}

type TenantEntityFacetEdge {
  node: TenantEntitySection!
  cursor: String!
}

type TenantEntityFacetConnection {
  edges: [TenantEntityFacetEdge!]!
  pageInfo: PageInfo!
}

enum BrainEnrichmentSourceFamily {
  BRAIN
  WEB
  KNOWLEDGE_BASE
}

type BrainEnrichmentCitation {
  label: String
  uri: String
  sourceId: String
  metadata: AWSJSON
}

type BrainEnrichmentCandidate {
  id: ID!
  title: String!
  summary: String!
  sourceFamily: BrainEnrichmentSourceFamily!
  providerId: String!
  score: Float
  citation: BrainEnrichmentCitation
}

type BrainEnrichmentProviderStatus {
  providerId: String!
  family: String!
  sourceFamily: String
  displayName: String!
  state: String!
  reason: String
  error: String
  hitCount: Int
  durationMs: Int
}

type BrainEnrichmentSourceAvailability {
  family: BrainEnrichmentSourceFamily!
  label: String!
  available: Boolean!
  selectedByDefault: Boolean!
  reason: String
}

type BrainEnrichmentProposal {
  id: ID!
  tenantId: ID!
  targetPageTable: String!
  targetPageId: ID!
  # threadId/reviewRunId/reviewObjectKey are populated only when the
  # enrichment ran through the legacy synchronous path. As of U6 of plan
  # 2026-05-01-002, Brain-page enrichments queue an async draft-compile
  # job and return immediately; the thread + workspace_run are created
  # by the writeback (U5) when the compile finishes, so these are NULL
  # in the queued response. Mobile reads `status === 'QUEUED'` to detect
  # the new flow and disengage the synchronous review surface.
  threadId: ID
  reviewRunId: ID
  reviewObjectKey: String
  # 'AWAITING_REVIEW' (legacy synchronous path) or 'QUEUED' (U6 async draft).
  status: String!
  title: String!
  candidates: [BrainEnrichmentCandidate!]!
  providerStatuses: [BrainEnrichmentProviderStatus!]!
  createdAt: AWSDateTime!
  updatedAt: AWSDateTime!
}

# ---------------------------------------------------------------------------
# Draft-page review (origin plan: 2026-05-01-002 — replaces synchronous
# candidate-card review for Brain pages with an async, thread-delivered
# draft of the recompiled page).
# ---------------------------------------------------------------------------

"""
Source family aggregation for a single proposed-body region. MIXED is set when
multiple candidates from different families contributed to the same section.
"""
enum BrainEnrichmentDraftRegionFamily {
  BRAIN
  KNOWLEDGE_BASE
  WEB
  MIXED
}

"""
One section-grain change region in a draft-page review. The mobile review
surface tap-targets the section in the in-place render, and the "show changes"
toggle uses beforeMd/afterMd to render a stacked diff.
"""
type BrainEnrichmentDraftRegion {
  id: ID!
  sectionSlug: String!
  sectionHeading: String!
  sourceFamily: BrainEnrichmentDraftRegionFamily!
  citation: BrainEnrichmentCitation
  beforeMd: String!
  afterMd: String!
  contributingCandidateIds: [ID!]!
}

"""
The structured payload behind a `brain_enrichment_draft_review` workspace
review. `proposedBodyMd` renders as the in-place review surface; `snapshotMd`
is the pinned current body at draft-creation time so per-region rejection
reverts deterministically.
"""
type BrainEnrichmentDraftPage {
  proposedBodyMd: String!
  snapshotMd: String!
  regions: [BrainEnrichmentDraftRegion!]!
  pageTitle: String!
  targetPageTable: String!
  targetPageId: ID!
}

input RunBrainPageEnrichmentInput {
  tenantId: ID!
  pageTable: String!
  pageId: ID!
  query: String
  sourceFamilies: [BrainEnrichmentSourceFamily!]
  limit: Int = 12
}

extend type Query {
  tenantEntityPage(tenantId: ID!, pageId: ID!): TenantEntityPage
  tenantEntityFacets(
    pageId: ID!
    limit: Int = 20
    cursor: String
  ): TenantEntityFacetConnection!
  brainEnrichmentSources(
    tenantId: ID!
    pageTable: String!
    pageId: ID!
  ): [BrainEnrichmentSourceAvailability!]!
}

extend type Mutation {
  editTenantEntityFact(factId: ID!, content: String!): TenantEntitySection!
  rejectTenantEntityFact(factId: ID!, reason: String): TenantEntitySection!
  runBrainPageEnrichment(
    input: RunBrainPageEnrichmentInput!
  ): BrainEnrichmentProposal!
}
