Skip to content

refactor: extract bounded-context modules from article.md pipeline, add typed interfaces and tests#2284

Merged
pethers merged 6 commits intomainfrom
copilot/refactor-article-md-pipeline
May 6, 2026
Merged

refactor: extract bounded-context modules from article.md pipeline, add typed interfaces and tests#2284
pethers merged 6 commits intomainfrom
copilot/refactor-article-md-pipeline

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 6, 2026

  • Create shared pipeline interfaces with discriminated union PipelineResult<T>
  • Align EnrichmentMetadata / ArticlePipelineConfig field names to snake_case matching FrontMatterFields; add missing layout
  • Wire config (generated_at/language/layout) through runArticlePipelineAggregationInputbuildFrontMatter
  • Remove redundant import { rewriteRelativeLinks } from structural.ts — the binding was only re-exported, never used locally, causing ESLint no-unused-vars error
  • All 265 tests pass; ESLint and TypeScript strict check clean

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

🏷️ Automatic Labeling Summary

This PR has been automatically labeled based on the files changed and PR metadata.

Applied Labels: size-xs

Label Categories

  • 🗳️ Content: news, dashboard, visualization, intelligence
  • 💻 Technology: html-css, javascript, workflow, security
  • 📊 Data: cia-data, riksdag-data, data-pipeline, schema
  • 🌍 I18n: i18n, translation, rtl
  • 🔒 ISMS: isms, iso-27001, nist-csf, cis-controls
  • 🏗️ Infrastructure: ci-cd, deployment, performance, monitoring
  • 🔄 Quality: testing, accessibility, documentation, refactor
  • 🤖 AI: agent, skill, agentic-workflow

For more information, see .github/labeler.yml.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

…eline interfaces and tests

- Create interfaces.ts with typed pipeline stage contracts (PipelineResult, ReadStageInput, WriteStageOutput, etc.)
- Create pipeline.ts composable orchestrator (runArticlePipeline) wrapping aggregateAnalysis
- Extract heading-demotion.ts from structural.ts (demoteHeadings)
- Extract link-rewriting.ts from structural.ts (rewriteRelativeLinks)
- Extract deduplication.ts from structural.ts (dedupeAdjacentDuplicateLines, collapseRepeatedFooterBlocks)
- structural.ts reduced from 314 → 164 lines (under 200-line target)
- Add comprehensive test file (article-pipeline.test.ts) with 36 tests covering:
  - Pipeline interface type contracts
  - Happy path (minimal folder, title/description extraction, front-matter, ordering)
  - Error cases (missing folder, missing executive-brief, empty files, malformed YAML)
  - Edge cases (README exclusion, article.md exclusion, supplementary artifacts)
  - Extracted module tests (heading-demotion, link-rewriting)
- Update Article-Generation.md with new architecture diagram
- Export new types/functions from barrel (index.ts) and render-lib/index.ts
- All 263 existing + new tests pass, TypeScript strict check clean, ESLint clean

Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/68311a88-b977-4f8d-a9fc-6083bd194104

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
@github-actions github-actions Bot added documentation Documentation updates testing Test coverage refactor Code refactoring size-xl Extra large change (> 1000 lines) labels May 6, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Copilot AI changed the title [WIP] Refactor article.md generation pipeline for improved architecture and testing refactor: extract bounded-context modules from article.md pipeline, add typed interfaces and tests May 6, 2026
Copilot finished work on behalf of pethers May 6, 2026 11:12
Copilot AI requested a review from pethers May 6, 2026 11:12
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

@pethers pethers marked this pull request as ready for review May 6, 2026 11:14
Copilot AI review requested due to automatic review settings May 6, 2026 11:14
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Comment thread scripts/render-lib/aggregator/cleaning/structural.ts Fixed
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the existing aggregateAnalysis()article.md generation flow into clearer bounded-context modules by extracting cleaning utilities, introducing a typed pipeline wrapper (runArticlePipeline), and adding comprehensive Vitest coverage plus updated documentation.

Changes:

  • Introduces typed pipeline contracts in interfaces.ts and a wrapper orchestrator in pipeline.ts (runArticlePipeline) while keeping aggregateAnalysis() as the underlying implementation.
  • Extracts structural cleaning helpers into dedicated modules (heading demotion, relative-link rewriting, deduplication) and re-exports them from structural.ts to preserve existing imports.
  • Adds a new end-to-end and unit-test suite for the article pipeline and updates Article-Generation.md to reflect the new directory structure.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/article-pipeline.test.ts Adds unit + integration tests for the pipeline wrapper and extracted cleaning modules.
scripts/render-lib/index.ts Exposes runArticlePipeline and new pipeline types via the top-level render-lib barrel.
scripts/render-lib/aggregator/pipeline.ts Adds runArticlePipeline() wrapper returning PipelineResult<WriteStageOutput>.
scripts/render-lib/aggregator/interfaces.ts Defines shared pipeline type contracts (result, stage, stage I/O types).
scripts/render-lib/aggregator/index.ts Re-exports new pipeline entry point + types from the aggregator barrel.
scripts/render-lib/aggregator/cleaning/structural.ts Switches to imported leaf cleaners and re-exports extracted functions for compatibility.
scripts/render-lib/aggregator/cleaning/link-rewriting.ts New leaf module for rewriting relative markdown links to GitHub blob URLs.
scripts/render-lib/aggregator/cleaning/heading-demotion.ts New leaf module for demoting inner headings (fence-aware).
scripts/render-lib/aggregator/cleaning/deduplication.ts New leaf module for adjacent-line + footer-block deduplication (fence-aware).
Article-Generation.md Updates responsibility table and adds bounded-context directory tree for the refactor.

Comment on lines +21 to +27
export interface PipelineResult<T> {
readonly ok: boolean;
readonly value?: T;
readonly error?: string;
readonly warnings?: readonly string[];
}

Comment on lines +124 to +136
/**
* SEO and metadata fields added during enrichment.
*/
export interface EnrichmentMetadata {
readonly title: string;
readonly description: string;
readonly date: string;
readonly subfolder: string;
readonly slug: string;
readonly sourceFolder: string;
readonly generatedAt: string;
readonly language: string;
}
Comment on lines +38 to +45
* @param input - Filesystem location and metadata for the analysis folder.
* @param config - Optional pipeline configuration overrides.
* @returns A typed result with either the generated article or an error.
*/
export function runArticlePipeline(
input: ReadStageInput,
_config?: ArticlePipelineConfig,
): PipelineResult<WriteStageOutput> {
@pethers
Copy link
Copy Markdown
Member

pethers commented May 6, 2026

@copilot apply changes based on the comments in this thread

…s, wire config through pipeline

- PipelineResult<T>: change from interface with optional fields to discriminated union type
  (ok:true branch has `value:T`, ok:false branch has `error:string`, no invalid states possible)
- EnrichmentMetadata + ArticlePipelineConfig: align field names to snake_case matching
  FrontMatterFields contract (sourceFolder→source_folder, generatedAt→generated_at, add layout)
- AggregationInput: extend with optional generated_at/language/layout fields
- aggregate.ts: use input.generated_at/language/layout overrides in buildFrontMatter call
- pipeline.ts: rename _config to config, wire all three fields through to aggregationInput
- Tests: add requireOk() helper to eliminate non-null assertions on success branch;
  replace result.value! with requireOk(result); add config-override test

Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/72e4fc96-94a0-48c5-97c0-3b18f1174e19

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 6, 2026

@copilot apply changes based on the comments in this thread

Applied all three changes in commit 839d9a0:

  1. PipelineResult<T> → discriminated union — changed from an interface with optional value?/error? fields to type PipelineResult<T> = { ok: true; value: T; ... } | { ok: false; error: string; ... }. Invalid states like { ok: true, error: '...' } are now compile-time errors. Tests use a requireOk() helper to narrow the union cleanly without ! assertions.

  2. EnrichmentMetadata + ArticlePipelineConfig field names aligned with FrontMatterFields — renamed sourceFolder → source_folder, generatedAt → generated_at, and added the missing layout field to both interfaces.

  3. config wired through pipeline — renamed _config to config, extended AggregationInput with optional generated_at, language, and layout fields, and passed them from runArticlePipeline into aggregateAnalysisbuildFrontMatter. A new test (config overrides are wired into the front-matter) validates all three fields end up in the generated YAML.

Copilot finished work on behalf of pethers May 6, 2026 11:33
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

import { stripLeadingAdminBylines } from './admin-bylines.js';
import { stripProcessMetaLines } from './process-meta.js';
import { demoteHeadings } from './heading-demotion.js';
import { rewriteRelativeLinks } from './link-rewriting.js';
@pethers
Copy link
Copy Markdown
Member

pethers commented May 6, 2026

@copilot apply changes based on the comments in this thread

…Lint no-unused-vars)

Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/d6cd90ad-eb9c-44f0-9d91-e1a24f227e64

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 6, 2026

@copilot apply changes based on the comments in this thread

Fixed in 6da758b — removed the unused import { rewriteRelativeLinks } from structural.ts (line 49). The re-export on line 105 already handles re-exposing the binding directly from the source module, so the local import was redundant and would have failed no-unused-vars.

Copilot finished work on behalf of pethers May 6, 2026 11:55
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

@pethers pethers merged commit 2e0bcbb into main May 6, 2026
18 checks passed
@pethers pethers deleted the copilot/refactor-article-md-pipeline branch May 6, 2026 12:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Documentation updates refactor Code refactoring size-xl Extra large change (> 1000 lines) size-xs Extra small change (< 10 lines) testing Test coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve architecture, code quality, and test coverage for article.md generation pipeline (aggregate-analysis → article.md)

3 participants