Adds a draw.io import path to the skill. Points at a .drawio file and produces an editorial diagram fitted to where it's going — not a format conversion. - scripts/drawio_extract.py: decodes all four containers draw.io writes (raw XML, deflate+base64 payloads, PNG tEXt chunks, SVG content attrs), flattens mxGraphModel into absolute-positioned nodes/edges, and reports structural signals: hubs, containers, depth, cycles, collapsible leaf groups, budget flags. Deterministic half — makes no design decisions. - references/output-spec.md: the three dials. Nine size presets with per-size-class type ramps and safe areas; faithful/balanced/simplified detail levels with a fixed degrade ladder; engineer/mixed/executive audience wording; fidelity ledger; CJK font fallback. - references/import-drawio.md: the redraw procedure — extract, set dials, pick type, build the semantic model, redraw on the grid. Includes the draw.io palette/shape → semantic role mappings, multi-page handling, edge cases, and anti-patterns. - commands/import-drawio.md: /diagram-design:import slash command. - SKILL.md: new §11 (import + output dials), taste-gate entries, §12 output. - export.md: sizing section — scale factors and exact-pixel targets. - assets/example-import-drawio.html: worked import of the checked-in fixture at balanced/doc-inline, lint-clean. - scripts/verify-drawio-import.py: drives the real extractor against the fixture in all four containers and checks the references stay in sync. faithful is the one documented exemption from the §7 complexity budget, and it's conditional: zoned above 9 nodes, split above 24. The §6 connector rules never relax for imported content. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M5f1aK1zNcgnQUnXZgG2LU
184 lines
12 KiB
HTML
184 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Imported from draw.io — Order platform</title>
|
|
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
|
<style>
|
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
:root {
|
|
--color-paper: #f5f5f5; /* white-smoke */
|
|
--color-ink: #2d3142; /* jet-black */
|
|
--color-muted: #4f5d75; /* blue-slate */
|
|
--color-accent: #eb6c36; /* atomic-tangerine */
|
|
--font-sans: 'Geist', system-ui, sans-serif;
|
|
--font-serif: 'Instrument Serif', serif;
|
|
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
|
}
|
|
|
|
body {
|
|
font-family: var(--font-sans);
|
|
background: var(--color-paper);
|
|
color: var(--color-ink);
|
|
min-height: 100vh;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 3rem 2rem;
|
|
}
|
|
|
|
.frame { max-width: 1200px; width: 100%; }
|
|
|
|
.eyebrow {
|
|
font-family: var(--font-mono);
|
|
font-size: 0.66rem;
|
|
font-weight: 500;
|
|
letter-spacing: 0.18em;
|
|
text-transform: uppercase;
|
|
color: var(--color-muted);
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
h1 {
|
|
font-family: var(--font-serif);
|
|
font-size: clamp(1.5rem, 2.4vw + 0.75rem, 2rem);
|
|
font-weight: 400;
|
|
letter-spacing: -0.02em;
|
|
line-height: 1.15;
|
|
color: var(--color-ink);
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
|
|
svg { width: 100%; min-width: 900px; display: block; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="frame">
|
|
<p class="eyebrow">Architecture · Imported from draw.io · doc-inline · balanced</p>
|
|
<h1>Order platform — request path</h1>
|
|
|
|
<svg viewBox="0 0 960 600" xmlns="http://www.w3.org/2000/svg">
|
|
<defs>
|
|
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
|
|
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#eb6c36"/></marker>
|
|
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#2e5aa8"/></marker>
|
|
</defs>
|
|
|
|
<rect width="100%" height="100%" fill="#f5f5f5"/>
|
|
|
|
<!-- Zones -->
|
|
<rect x="40" y="96" width="200" height="224" rx="8" fill="none" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
|
<text x="56" y="120" fill="#7a8399" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">EDGE</text>
|
|
|
|
<rect x="320" y="96" width="560" height="224" rx="8" fill="none" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
|
<text x="336" y="120" fill="#7a8399" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">CORE SERVICES</text>
|
|
|
|
<rect x="320" y="368" width="560" height="112" rx="8" fill="none" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
|
|
<text x="336" y="392" fill="#7a8399" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">DATA</text>
|
|
|
|
<!-- Connectors (drawn before boxes) -->
|
|
<!-- Web App -> API Gateway -->
|
|
<path d="M220,164 H272 A8,8 0 0 1 280,172 V192 A8,8 0 0 0 288,200 H360" fill="none" stroke="#2e5aa8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
|
<!-- Mobile App -> API Gateway -->
|
|
<path d="M220,252 H296 A8,8 0 0 0 304,244 V232 A8,8 0 0 1 312,224 H360" fill="none" stroke="#2e5aa8" stroke-width="1.2" marker-end="url(#arrow-link)"/>
|
|
<!-- API Gateway -> Auth Service -->
|
|
<path d="M560,192 H592 A8,8 0 0 0 600,184 V164 A8,8 0 0 1 608,156 H640" fill="none" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
|
<!-- API Gateway -> Orders Service -->
|
|
<path d="M560,224 H592 A8,8 0 0 0 600,232 V252 A8,8 0 0 1 608,260 H640" fill="none" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
|
<!-- Orders Service -> Postgres -->
|
|
<path d="M680,288 V320 A8,8 0 0 1 672,328 H432 A8,8 0 0 0 424,336 V392" fill="none" stroke="#4f5d75" stroke-width="1.2" marker-end="url(#arrow)"/>
|
|
<!-- Orders Service -> Object Store (async) -->
|
|
<path d="M760,288 V344 A8,8 0 0 1 752,352 H616 A8,8 0 0 0 608,360 V392" fill="none" stroke="#4f5d75" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
|
<!-- Auth Service -> Redis (async) -->
|
|
<path d="M840,156 H848 A8,8 0 0 1 856,164 V392" fill="none" stroke="#4f5d75" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrow)"/>
|
|
|
|
<!-- Arrow labels -->
|
|
<rect x="228" y="144" width="44" height="12" rx="2" fill="#f5f5f5"/>
|
|
<text x="250" y="153" fill="#7a8399" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">HTTPS</text>
|
|
|
|
<rect x="228" y="232" width="44" height="12" rx="2" fill="#f5f5f5"/>
|
|
<text x="250" y="241" fill="#7a8399" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">HTTPS</text>
|
|
|
|
<rect x="568" y="172" width="44" height="12" rx="2" fill="#f5f5f5"/>
|
|
<text x="590" y="181" fill="#7a8399" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">VERIFY</text>
|
|
|
|
<rect x="568" y="204" width="44" height="12" rx="2" fill="#f5f5f5"/>
|
|
<text x="590" y="213" fill="#7a8399" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">ROUTE</text>
|
|
|
|
<rect x="536" y="308" width="32" height="12" rx="2" fill="#f5f5f5"/>
|
|
<text x="552" y="317" fill="#7a8399" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">SQL</text>
|
|
|
|
<rect x="768" y="326" width="56" height="12" rx="2" fill="#f5f5f5"/>
|
|
<text x="796" y="335" fill="#7a8399" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">ARCHIVE</text>
|
|
|
|
<rect x="792" y="196" width="56" height="12" rx="2" fill="#f5f5f5"/>
|
|
<text x="820" y="205" fill="#7a8399" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">CACHE</text>
|
|
|
|
<!-- Nodes: Edge -->
|
|
<rect x="60" y="136" width="160" height="56" rx="6" fill="#f5f5f5"/>
|
|
<rect x="60" y="136" width="160" height="56" rx="6" fill="rgba(79,93,117,0.10)" stroke="#7a8399" stroke-width="1"/>
|
|
<text x="140" y="169" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Web App</text>
|
|
|
|
<rect x="60" y="224" width="160" height="56" rx="6" fill="#f5f5f5"/>
|
|
<rect x="60" y="224" width="160" height="56" rx="6" fill="rgba(79,93,117,0.10)" stroke="#7a8399" stroke-width="1"/>
|
|
<text x="140" y="257" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Mobile App</text>
|
|
|
|
<!-- Nodes: Core -->
|
|
<rect x="360" y="176" width="200" height="64" rx="6" fill="#f5f5f5"/>
|
|
<rect x="360" y="176" width="200" height="64" rx="6" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
|
<text x="460" y="204" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">API Gateway</text>
|
|
<text x="460" y="220" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">single entry point</text>
|
|
|
|
<rect x="640" y="128" width="200" height="56" rx="6" fill="#f5f5f5"/>
|
|
<rect x="640" y="128" width="200" height="56" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
|
<text x="740" y="153" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Auth Service</text>
|
|
<text x="740" y="169" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">token check</text>
|
|
|
|
<rect x="640" y="232" width="200" height="56" rx="6" fill="#f5f5f5"/>
|
|
<rect x="640" y="232" width="200" height="56" rx="6" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
|
<text x="740" y="257" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Orders Service</text>
|
|
<text x="740" y="273" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">order write</text>
|
|
|
|
<!-- Nodes: Data -->
|
|
<rect x="344" y="392" width="160" height="64" rx="6" fill="#f5f5f5"/>
|
|
<rect x="344" y="392" width="160" height="64" rx="6" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="1"/>
|
|
<text x="424" y="420" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Postgres</text>
|
|
<text x="424" y="436" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">orders</text>
|
|
|
|
<rect x="528" y="392" width="160" height="64" rx="6" fill="#f5f5f5"/>
|
|
<rect x="528" y="392" width="160" height="64" rx="6" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="1"/>
|
|
<text x="608" y="420" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Object Store</text>
|
|
<text x="608" y="436" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">archive</text>
|
|
|
|
<rect x="712" y="392" width="160" height="64" rx="6" fill="#f5f5f5"/>
|
|
<rect x="712" y="392" width="160" height="64" rx="6" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="1"/>
|
|
<text x="792" y="420" fill="#2d3142" font-size="12" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Redis</text>
|
|
<text x="792" y="436" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">sessions</text>
|
|
|
|
<!-- Legend -->
|
|
<line x1="40" y1="512" x2="920" y2="512" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
|
|
<text x="40" y="532" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">LEGEND</text>
|
|
|
|
<rect x="120" y="524" width="16" height="10" rx="2" fill="rgba(235,108,54,0.08)" stroke="#eb6c36" stroke-width="1"/>
|
|
<text x="144" y="532" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.06em">FOCAL</text>
|
|
|
|
<rect x="240" y="524" width="16" height="10" rx="2" fill="#ffffff" stroke="#2d3142" stroke-width="1"/>
|
|
<text x="264" y="532" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.06em">SERVICE</text>
|
|
|
|
<rect x="376" y="524" width="16" height="10" rx="2" fill="rgba(45,49,66,0.05)" stroke="#4f5d75" stroke-width="1"/>
|
|
<text x="400" y="532" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.06em">STORE</text>
|
|
|
|
<rect x="496" y="524" width="16" height="10" rx="2" fill="rgba(79,93,117,0.10)" stroke="#7a8399" stroke-width="1"/>
|
|
<text x="520" y="532" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.06em">CLIENT</text>
|
|
|
|
<line x1="616" y1="529" x2="648" y2="529" stroke="#2e5aa8" stroke-width="1.2"/>
|
|
<text x="656" y="532" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.06em">HTTP CALL</text>
|
|
|
|
<line x1="772" y1="529" x2="804" y2="529" stroke="#4f5d75" stroke-width="1.2" stroke-dasharray="5,4"/>
|
|
<text x="812" y="532" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.06em">ASYNC</text>
|
|
</svg>
|
|
</div>
|
|
</body>
|
|
</html>
|