[EPAC-1006]: Bill page — PBO costing panel#808
Merged
riddim-developer-bot[bot] merged 1 commit intoJun 14, 2026
Merged
Conversation
Add the independent Parliamentary Budget Officer costing panel to the canonical Bill page. When the backend links a PBO note to a bill, the panel shows the verbatim 5-year cost (in millions), a methodology category badge, and the publication date, with a link out to the full PBO report PDF. Tapping the panel opens an in-app reader with the PBO summary card and an Open-PDF-in-Safari button. When no PBO link exists the panel renders nothing — no fallback prose. Implements the LoadPBOCosting use case (entity, port, backend-backed repository, SwiftUI panel + reader) and wires it into BillDetailView. Removes the old on-device PBO scraper; all PBO parsing stays in the backend and iOS decodes typed JSON only. Adds use-case + repository unit tests and snapshot tests (present, absent, multiple notes with latest-wins, no-figure, reader), and records LoadPBOCosting in the use-case catalog.
riddim-developer-bot
Bot
deleted the
symphony/epac-1006-bill-page-pbo-costing-panel
branch
June 14, 2026 11:15
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the Independent costing — Parliamentary Budget Officer panel to the canonical Bill page (
BillDetailView). When the backend has a PBO costing note linked to a bill, the panel shows the verbatim headline figure (5-year cost in millions), a methodology category badge, and the publication date, with a link out to the full PBO report PDF. Tapping the panel opens an in-app reader showing the PBO summary card and a button to open the PDF in Safari. When no PBO link exists, the panel renders nothing — no fallback prose.Implements
LoadPBOCosting(Clean Architecture Shape from EPAC-1006). iOS-only change; the backendGET /pbo/by-bill/{legisinfo_id}endpoint is a shipped prerequisite. The old on-device PBO scraper (PBOService/PBOReport) is removed — all PBO parsing lives in the backend; iOS decodes typed JSON only and never scrapes PBO pages on device.Linear: https://linear.app/riddimsoftware/issue/EPAC-1006/bill-page-pbo-costing-panel
What changed
PBOCostingentity (headlineFigureMillions,methodologyCategory,publishedAt,reportURL,sourceURL,summaryText) +PBOCostingResult(latest note + older linked notes).PBOCostingQueryPort.LoadPBOCosting: returnsnilwhen absent/empty; otherwise sorts notes by publication date (latest wins) and keeps older notes for the reader.BackendPBOCostingRepository(PBOCostingQueryPort):GET /pbo/by-bill/{legisinfo_id};204/404→nil(hide panel); decodes the typed JSON contract.PBOCostingPanel(renders nothing whenresult == nil) +PBOCostingReaderView(in-app summary card, other-notes list, open-PDF-in-Safari). Wired intoBillDetailViewvia injectedLoadPBOCosting+autoloadPBOCosting.pbo.costing.*/pbo.methodology.*/common.done. Oldpbo.*cost-analysis keys removed.LoadPBOCostinguse case,PBOCostingQueryPortport, and correctedPBOCostingentity added todocs/architecture/use-case-catalog.md.ios/epac/Util/PBOService.swiftandios/epac/Model/PBOReport.swift.Backend JSON contract (boundary)
GET /pbo/by-bill/{legisinfo_id}→200:{ "costings": [ { "id": "PBO-2026-014", "title": "Cost Estimate — Bill C-8", "headline_figure_millions": "1,240", "methodology_category": "legislative-cost", "published_at": "2026-05-20", "report_url": "https://www.pbo-dpb.ca/en/publications/RP-2627-014-S", "source_url": "https://www.pbo-dpb.ca/en/publications/RP-2627-014-S", "summary_text": "The PBO estimates the five-year cost at $1,240 million." } ] }204/404→ no PBO link; the bill page hides the panel. The decoder also accepts a bare top-level array and alternate envelope keys so a backend wrapper rename does not silently blank the bill page; the canonicalcostingskey is always tried first. Figures and summary text are rendered verbatim — no paraphrasing, no LLM summaries.Acceptance criteria
LoadPBOCostingadded to the use-case catalog (DoD)Verification
All run locally on the rebased branch (iPhone 17 Pro simulator, iOS 26.5):
xcodebuildbuild + test: app and test target compile clean; 5 snapshot tests (present, presentNoFigure, multipleNotes, absent, reader) pass with 0 failures; 13 unit tests pass (LoadPBOCostingTests7,PBOCostingRepositoryTests6). CI's iOS job is build-only (ENABLE_TESTABILITY=NO), so the tests are run locally; CI re-runs the build as thepr-buildgate.cyclomatic_complexityerror (and a latent type-inference bug) in the inherited JSON decoder — simplified it to the documented contract.scripts/localization/check_localizations.py): exit 0; en/fr PBO keys at parity (verified French translations, e.g. "Directeur parlementaire du budget").Simulator-rendered evidence
The panel below is rendered by the production SwiftUI view in the simulator via the snapshot harness. The bill page only shows the panel when staging returns a PBO link for a specific bill (data-dependent), so these deterministic renders are the visual evidence:
Release-Note: Bill pages now show the Parliamentary Budget Officer's independent costing — the 5-year cost, methodology, publication date, and a link to the full PBO report.