Accept flat-spec input aliases across generators

Harden bizcase, bom, deck, and diagram generators to tolerate payload
shape variants (metadata/cover/summary/line_item aliases, current_state
as string, alternate pillar keys) so MCP and CLI flat specs render
consistently. Add input-alias tests per generator.

Also loosen KB governance tests to handle multi-document service YAMLs
with optional changelogs, untrack the customer demo output under
examples/output-demo-pharma-mx/ (matches .gitignore), and ship an
ADB-S vs Aurora 500GB sample deck.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
root
2026-04-21 10:22:14 -03:00
parent bcb16795d1
commit 490072a4b7
23 changed files with 785 additions and 2134 deletions

View File

@@ -0,0 +1,98 @@
import sys
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parent.parent
TOOLS_DIR = PROJECT_ROOT / "tools"
if str(TOOLS_DIR) not in sys.path:
sys.path.insert(0, str(TOOLS_DIR))
from oci_deck_gen import OCIDeckGenerator
def _collect_slide_text(gen):
texts = []
for slide in gen.prs.slides:
for shape in slide.shapes:
if hasattr(shape, "text"):
text = shape.text.strip()
if text:
texts.append(text)
if getattr(shape, "has_table", False):
for row in shape.table.rows:
for cell in row.cells:
text = cell.text.strip()
if text:
texts.append(text)
return "\n".join(texts)
def test_from_spec_accepts_metadata_aliases_and_current_state_string():
spec = {
"metadata": {
"customer_name": "Acme Corp",
"project_name": "DB Migration",
"prepared_by": "Diego",
"title": "Target Architecture",
},
"summary": {
"why": "Modernize platform",
"current_state": "Legacy estate",
"target_state": "OCI landing zone",
"timeline": "Q3",
},
}
gen = OCIDeckGenerator.from_spec(spec)
text = _collect_slide_text(gen)
assert gen.customer == "Acme Corp"
assert gen.project == "DB Migration"
assert gen.architect == "Diego"
assert "Legacy estate" in text
assert "OCI landing zone" in text
def test_from_spec_accepts_aliases_for_cost_migration_risk_scorecard_and_next_steps():
spec = {
"metadata": {"customer": "Acme"},
"cost": {
"line_items": [
{"name": "DB Service", "monthly": "USD 100", "note": "Includes storage"}
],
"assumptions": ["1 region"],
"show_byol": False,
},
"migration": {
"phases": [
{"title": "Discover", "weeks": "2 weeks", "tasks": ["Inventory", "Assess"]}
],
"tools": ["ZDM"],
"downtime": "Near-zero",
},
"risks": [
{"title": "Cutover risk", "action": "Pilot first", "severity": "high"}
],
"scorecard": {
"pillars": [
{"pillar": "Security", "status": "PASS", "passed": 2, "total": 2}
],
"recommendations": ["Enable auditing"],
},
"next_steps": {"next_steps": ["Validate scope"]},
}
gen = OCIDeckGenerator.from_spec(spec)
text = _collect_slide_text(gen)
assert "DB Service" in text
assert "USD 100" in text
assert "Includes storage" in text
assert "Discover" in text
assert "Inventory" in text
assert "Cutover risk" in text
assert "Pilot first" in text
assert "Security" in text
assert "2/2" in text
assert "Validate scope" in text