openup: architecture notebook + EA diagram renders
All checks were successful
build / build-test (push) Successful in 44s

- analysis-design/architecture-notebook.md: Architecture Notebook work
  product in the keyfob docx template structure (10 sections), grounded
  in mapping / design note / supplementary specs; embeds the component
  model and all 12 realization figures
- scripts/openup/export-diagram-images.ps1: read-only EA COM renderer
  (EA-15 findings: image API on ProjectInterface, OpenDiagram before
  export or blank stub, type 0 = PNG); renders reflect manual layouts
- renders: requirements/use-case-overview.png, analysis-design/
  uc-01..12-realization.png + component-architecture.png; embedded as
  figures in use-case-model.md and uc-realization-mapping.md
- BUILD-CHECKLIST 6.4 documents the exporter
This commit is contained in:
Jan-Peter von Hunnius 2026-10-05 10:00:45 +02:00
parent c0226df62d
commit 6e5d3fb45a
19 changed files with 351 additions and 0 deletions

View file

@ -0,0 +1,90 @@
# Skara Brae — EA diagram image exporter.
# Renders the model's diagrams to PNG for embedding in the OpenUP markdown documents.
# READ-ONLY on the model (opens diagrams, renders, closes; no model mutation).
#
# EA-15 findings baked in (probe session 2026-10-05):
# - the image methods live on ProjectInterface, NOT on Repository
# (Repository.SaveImageToPath exists but always returns False);
# - PutDiagramImageToFile(id, path, type) with type 0 = PNG;
# - the diagram must be OPEN (repo.OpenDiagram) before export, else a blank
# 241x151 stub is written;
# - works with EA hidden (app.Visible = $false).
#
# Output (keyfob-station convention: requirements overview next to the UC docs,
# realization + design figures in analysis-design/):
# docs/openup/requirements/use-case-overview.png
# docs/openup/analysis-design/uc-01-realization.png .. uc-12-realization.png
# docs/openup/analysis-design/component-architecture.png
$ErrorActionPreference = 'Stop'
$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path
$modelPath = Join-Path $repoRoot 'docs\openup\model\skara-brae.eapx'
if (-not (Test-Path $modelPath)) {
Write-Output "MISSING $modelPath"
exit 1
}
$reqDir = Join-Path $repoRoot 'docs\openup\requirements'
$adDir = Join-Path $repoRoot 'docs\openup\analysis-design'
$null = New-Item -ItemType Directory -Force -Path $reqDir, $adDir
$step = 'start'
$app = $null
$eaBefore = @(Get-Process -Name EA -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Id)
function Export-Diagram([object]$project, [object]$repo, [int]$diagramId, [string]$outPath) {
if (Test-Path $outPath) { Remove-Item $outPath -Force }
$null = $repo.OpenDiagram($diagramId)
Start-Sleep -Seconds 2
$null = $project.PutDiagramImageToFile($diagramId, $outPath, 0)
try { $null = $repo.CloseDiagram($diagramId) } catch { }
if (-not (Test-Path $outPath)) { throw "no image written: $outPath" }
$bytes = (Get-Item $outPath).Length
if ($bytes -lt 5000) { throw "suspiciously small render ($bytes bytes): $outPath" }
Write-Output "exported: $outPath ($bytes bytes)"
}
try {
$app = New-Object -ComObject EA.App
$app.Visible = $false
$repo = $app.Repository
$null = $repo.OpenFile($modelPath)
$root = $repo.Models.GetAt([int]0)
$project = $repo.GetProjectInterface()
$step = 'use case overview'
$ucModel = $root.Packages.GetByName('Requirements').Packages.GetByName('Use Case Model')
$ucModel.Diagrams.Refresh()
$overview = $ucModel.Diagrams.GetByName('Skara Brae Use Case Overview')
Export-Diagram $project $repo $overview.DiagramID (Join-Path $reqDir 'use-case-overview.png')
$step = 'realization diagrams'
$analysisDesign = $root.Packages.GetByName('Analysis-Design')
$analysisDesign.Packages.Refresh()
for ($p = 0; $p -lt $analysisDesign.Packages.Count; $p++) {
$pkg = $analysisDesign.Packages.GetAt([int]$p)
if ($pkg.Name -notlike 'UC-?? Realization') { continue }
$pkg.Diagrams.Refresh()
if ($pkg.Diagrams.Count -lt 1) { throw "no diagram in $($pkg.Name)" }
$number = $pkg.Name.Substring(3, 2)
Export-Diagram $project $repo $pkg.Diagrams.GetAt([int]0).DiagramID (Join-Path $adDir ("uc-{0}-realization.png" -f $number.ToLower()))
}
$step = 'component architecture'
$design = $analysisDesign.Packages.GetByName('Design')
$design.Diagrams.Refresh()
$componentDiagram = $design.Diagrams.GetByName('Component Architecture')
Export-Diagram $project $repo $componentDiagram.DiagramID (Join-Path $adDir 'component-architecture.png')
$null = $repo.CloseFile()
Write-Output 'EXPORT OK - 14 diagrams rendered'
}
catch {
Write-Output "FAILED at [$step]: $($_.Exception.Message)"
exit 1
}
finally {
Get-Process -Name EA -ErrorAction SilentlyContinue |
Where-Object { $eaBefore -notcontains $_.Id } |
ForEach-Object { Stop-Process -Id $_.Id -Force }
}