Render newsletter points as bullets and stop duplicating section titles - #1071
Merged
Merged
Conversation
… titles
The Results table showed "Deals & Movements - Deals & Movements" for every
section, because collectNewsletterSections writes the canonical label into
`heading` and the builder joined label and heading unconditionally.
It also showed each entry as one paragraph. The email renders an article's
points as a real list, but the persister flattened them with points.join(" ")
before they reached the dashboard, so the structure was gone by the time the
table saw it. Carry `points` through instead, replacing the joined `summary`
column, and render one row per point behind a `bulletField` marker so the
glyph stays in the renderer rather than the data.
The migration backfills points from summary before dropping it, so entries
written earlier keep their text as a single point.
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
The Content Generation Results table repeated every section name (
Deals & Movements - Deals & Movements) and showed each entry as one paragraph. Both come from the same place: the step that flattens the newsletter document for persistence writes the canonical label intoheading, and joins each article'spointsinto a single string. The email has been rendering those points as a real list all along, so this makes the dashboard match it.Related issues
Closes #1070
Important changes
pointsreplacessummaryonNewsletterSectionItem. The agent stops callingpoints.join(" "), the contract takes an array, and the Results table renders one row per point beneath the entry's headline. This is a breaking contract change:newsletterSectionItemSchemanow requirespointsand rejectssummary, so agent-data-api and content-generation need to deploy together.UPDATE ... SET points = ARRAY[summary]for rows that have none, thenDROP COLUMN summary. Entries written earlier become a single point rather than N, which is honest, since the original points were destroyed at write time and cannot be reconstructed.composeSectionHeaderLabelonly appends the agent's heading when it adds information, comparing case-insensitively and collapsing repeated whitespace. The join is still worth keeping for older rows whose headings differed.bulletFieldon the sub-table column contract, a path to a boolean on the row. When truthy the renderer indents the cell under a bullet marker. The marker lives in the renderer, not in stored text, which is also whatsummarize-article.tsinstructs the model to do.Other changes
entryPointstrims and drops blank points.Key files to review
packages/mediapulse/database/prisma/migrations/20260729040000_newsletter_section_item_points/migration.sql- hand-written, since no local Postgres was reachable. It is more involved than a plain drop because of theUPDATEbackfill, and the ordering matters: add, backfill, drop. Worth a careful read.apps/mediapulse/agents/content-generation/src/llm-generate-newsletter.ts-collectNewsletterSections, where the join was.packages/shared/agent-data-api-contract/src/newsletter-section.ts- the breaking shape change.apps/hermes/dashboard/components/detail-blocks/detail-block-sub-table.tsx-bulletFieldhandling.How to test
pnpm code-qualityfrom the repo root. 108/108 tasks pass.Deals & Movements, notDeals & Movements - Deals & Movements.pointspopulated and nosummarycolumn in play.Note on the email
No changes there. It already renders
article.pointsas a<ul>and takes its section heading fromSECTION_COPY, not from the persistedheading, so it never had either bug.