The diagram path now follows a documented standard procedure (lookup the closest Oracle Architecture Center reference → confirm components → author absolute_layout → spec validator → render → visually verify) and ships persistent guardrails so layout regressions can't recur. Persistent procedure changes (apply to all users, all sessions): - tools/diagram_spec_validator.py — geometry checks (CONTAINER_TOO_THIN, CONTAINER_PADDING_VIOLATION, LABEL_OVERFLOW_PARENT) run BEFORE either renderer (drawio + PPTX). Catches the subnet-collapse / label-overflow bugs that the post-render drawio validator missed. - tools/oci_diagram_gen.py + tools/oci_pptx_diagram_gen.py — call the spec validator before emitting any output. Adds mysql / mysql_heatwave type aliases. - tools/archcenter_pattern_lookup.py — scores against cached page descriptions (not just the 1-line summary), supports --queries for multi-fragment composition, and applies synonym expansion via kb/architecture-center/synonyms.yaml so "LB HA cross AD" matches "load balancer high availability availability domain". - kb/architecture-center/synonyms.yaml — canonical synonym table (load balancer, autonomous database, data guard, …) used by the lookup scorer. KB enrichment: - tools/archcenter_description_fetcher.py + 121 cached _description.md under kb/diagram/assets/archcenter-refs/<slug>/. Removes the runtime dependency on docs.oracle.com when authoring specs and feeds the pattern-lookup scorer. - 110+ cached .drawio / .svg / .png references for offline reuse, plus the OCI Toolkit v24.2 import (kb/diagram/assets/oci-toolkit-drawio). Documentation: - docs/skill/output-formats.md — new "Standard diagram-generation procedure (MANDATORY)" + geometry rules + the new validator entry. - SKILL.md option 2 — references the mandatory procedure. - README.md — describes the spec validator, archcenter_pattern_lookup and description fetcher, and updates the KB-health table. Tooling that backs the procedure (cumulative across recent sessions): tools/archcenter_case_runner.py, archcenter_batch_driver.py, archcenter_zip_downloader.py, drawio_visual_validator.py, drawio_fidelity_eval.py, harvest_drawio_icon.py, import_oci_library.py, oci_pptx_diagram_gen.py, oci_pptx_render.py, refresh_pptx_icon_index.py. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
124 lines
3.6 KiB
Python
124 lines
3.6 KiB
Python
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
|
|
|
|
|
|
def test_from_spec_enriches_sparse_nested_spec_with_safe_fallback_sections():
|
|
spec = {
|
|
"metadata": {
|
|
"customer": "Acme Corp",
|
|
"project": "Pilot",
|
|
},
|
|
"summary": {
|
|
"why": "Modernize core platform",
|
|
"current_state": ["Legacy Oracle DB on-prem"],
|
|
"target_state": "Target OCI platform with improved DR posture",
|
|
"timeline": "12 weeks",
|
|
},
|
|
}
|
|
|
|
gen = OCIDeckGenerator.from_spec(spec)
|
|
text = _collect_slide_text(gen)
|
|
|
|
assert "Architecture Overview" in text
|
|
assert "Migration Approach" in text
|
|
assert "Operational Responsibilities" in text
|
|
assert "Risk Register" in text
|
|
assert "Next Steps" in text
|
|
assert "12 weeks" in text
|