Everything the fill drawer needs to render a run's answers over the PDF: the decoded
value, its provenance (citations + normalized context sources), a per-field status,
and the boxes to position each answer in.
Values arrive already decoded by the repo's codec, so all three at-rest v1 shapes
(["text"], batched {coordId: "text"}, and manually-edited
{coordId: {value, fontSize}}) come back as one discriminated union rather than raw
jsonb the client has to sniff. Unrecognized shapes pass through as kind: "unknown" —
decoding never throws, so one weird legacy row cannot blank the whole drawer.
Read-only. update-answer.mutation returns EXACTLY one element of answers (same toAnswerOutput) so the client can patch this cache in place.
Everything the fill drawer needs to render a run's answers over the PDF: the decoded value, its provenance (citations + normalized context sources), a per-field status, and the boxes to position each answer in.
Values arrive already decoded by the repo's codec, so all three at-rest v1 shapes (
["text"], batched{coordId: "text"}, and manually-edited{coordId: {value, fontSize}}) come back as one discriminated union rather than raw jsonb the client has to sniff. Unrecognized shapes pass through askind: "unknown"— decoding never throws, so one weird legacy row cannot blank the whole drawer.Read-only.
update-answer.mutationreturns EXACTLY one element ofanswers(same toAnswerOutput) so the client can patch this cache in place.