Imports the substantive work from the aristide/diagram-design fork (PR #9) as a curated set: - 12 new diagram types with reference docs: radar, bar, line, gantt, scatter, it-state, high-level, process, medallion, data-flow, dp-integration, dp-security-matrix (26 types total) - 86-icon monochrome IT/cloud primitive, build script, and gallery - /diagram-design:export command with PNG/SVG export reference - Onboarding v2: URL, skill, and folder design-token sources - Mandatory connector rules (orthogonal elbows, label gaps, fanned attach points, bridge crossings) + architecture/ER connector upgrades - Series palette tokens for multi-series chart types - THIRD_PARTY_LICENSES.md covering Tabler, Simple Icons, log-z, Devicon Not taken from the fork: plugin-manifest identity changes, the client-brand takeover of style-guide.md, and client-branded example files. The six affected type examples were regenerated in the neutral editorial skin with generic content, and their README screenshots recaptured. Reference docs for those types were rewritten to semantic tokens and typography roles. Version: 1.0.0 -> 2.0.0. Co-authored-by: Aristide <mendoo.aristide@gmail.com>
160 lines
13 KiB
HTML
160 lines
13 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>E-commerce analytics · Medallion</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 {
|
|
--paper: #f5f5f5; --paper-2: #ececec; --ink: #2d3142; --muted: #4f5d75;
|
|
--soft: #7a8399; --rule: rgba(45,49,66,0.12); --accent: #eb6c36;
|
|
--accent-tint: rgba(235,108,54,0.08); --link: #2e5aa8;
|
|
--sans: 'Geist', system-ui, sans-serif; --serif: 'Instrument Serif', serif;
|
|
--mono: 'Geist Mono', ui-monospace, monospace;
|
|
}
|
|
body { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 3rem 2rem; background: var(--paper); color: var(--ink); font-family: var(--sans); }
|
|
.frame { width: 100%; max-width: 1200px; }
|
|
.eyebrow { margin-bottom: 0.5rem; color: var(--muted); font: 500 0.66rem var(--mono); letter-spacing: 0.18em; text-transform: uppercase; }
|
|
h1 { margin-bottom: 1.5rem; color: var(--ink); font: 400 clamp(1.5rem, 2.4vw + 0.75rem, 2rem)/1.15 var(--serif); letter-spacing: -0.02em; }
|
|
svg { display: block; width: 100%; min-width: 1040px; }
|
|
.tier-title { fill: var(--ink); font: 600 13px var(--sans); text-anchor: middle; }
|
|
.bucket, .field-value, .example-value { fill: var(--muted); font: 400 9px var(--mono); }
|
|
.bucket { text-anchor: middle; }
|
|
.field-value { color: var(--muted); }
|
|
.focal-text { fill: var(--accent); }
|
|
.field-label { fill: var(--ink); font: 600 11px var(--sans); }
|
|
.example-label, .arc-label, .path-tag { font-family: var(--mono); font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; }
|
|
.example-label { fill: var(--soft); font-size: 8px; }
|
|
.arc-label { font-size: 10px; text-anchor: middle; }
|
|
.path-title { fill: var(--ink); font: 600 11px var(--sans); }
|
|
.path-sub { fill: var(--muted); font: 400 9px var(--mono); }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<main class="frame">
|
|
<p class="eyebrow">Medallion · Diagram Design</p>
|
|
<h1>Five-tier e-commerce analytics storage</h1>
|
|
|
|
<svg viewBox="0 0 1040 548" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="medallion-title medallion-desc">
|
|
<title id="medallion-title">Five-tier e-commerce analytics medallion</title>
|
|
<desc id="medallion-desc">Clickstream events and order records move from raw storage through anonymized, staging, and aggregated tiers before lifecycle archiving.</desc>
|
|
<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>
|
|
<clipPath id="clip-raw"><rect x="16" y="80" width="172" height="380" rx="6"/></clipPath>
|
|
<clipPath id="clip-anon"><rect x="204" y="80" width="172" height="380" rx="6"/></clipPath>
|
|
<clipPath id="clip-stage"><rect x="392" y="80" width="172" height="380" rx="6"/></clipPath>
|
|
<clipPath id="clip-aggregate"><rect x="580" y="80" width="172" height="380" rx="6"/></clipPath>
|
|
<clipPath id="clip-archive"><rect x="768" y="80" width="172" height="380" rx="6"/></clipPath>
|
|
</defs>
|
|
<rect width="1040" height="548" fill="#f5f5f5"/>
|
|
|
|
<!-- Promotion arcs are the medallion type's required connector grammar. -->
|
|
<path d="M102 80 C102 0 290 0 290 80" fill="none" stroke="#4f5d75" stroke-width="1.4" marker-end="url(#arrow)"/>
|
|
<path d="M290 80 C290 0 478 0 478 80" fill="none" stroke="#4f5d75" stroke-width="1.4" marker-end="url(#arrow)"/>
|
|
<path d="M478 80 C478 0 666 0 666 80" fill="none" stroke="#eb6c36" stroke-width="1.6" marker-end="url(#arrow-accent)"/>
|
|
<path d="M666 80 C666 0 854 0 854 80" fill="none" stroke="#4f5d75" stroke-width="1.4" stroke-dasharray="4,3" marker-end="url(#arrow)"/>
|
|
<text x="196" y="50" class="arc-label" fill="#4f5d75">MASK IDS</text>
|
|
<text x="384" y="50" class="arc-label" fill="#4f5d75">CLEAN + JOIN</text>
|
|
<text x="572" y="50" class="arc-label" fill="#eb6c36">AGGREGATE</text>
|
|
<text x="760" y="50" class="arc-label" fill="#4f5d75">LIFECYCLE</text>
|
|
|
|
<!-- Raw -->
|
|
<rect x="16" y="80" width="172" height="380" rx="6" fill="#fff"/>
|
|
<rect x="16" y="80" width="172" height="50" fill="rgba(79,93,117,0.10)" clip-path="url(#clip-raw)"/>
|
|
<rect x="16" y="80" width="172" height="380" rx="6" fill="none" stroke="#4f5d75"/>
|
|
<text x="102" y="106" class="tier-title">Raw</text>
|
|
<text x="102" y="144" class="bucket">raw-commerce</text>
|
|
<text x="32" y="180" class="field-label">Tool</text>
|
|
<foreignObject x="32" y="186" width="140" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="field-value" style="line-height:1.25">NiFi ingest</div></foreignObject>
|
|
<text x="32" y="220" class="field-label">Format</text>
|
|
<foreignObject x="32" y="226" width="140" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="field-value" style="line-height:1.25">JSON · Parquet</div></foreignObject>
|
|
<text x="32" y="260" class="field-label">Writer</text>
|
|
<foreignObject x="32" y="266" width="140" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="field-value" style="line-height:1.25">Data Engineer</div></foreignObject>
|
|
<text x="32" y="360" class="example-label">E-COMMERCE EXAMPLE</text>
|
|
<text x="32" y="374" class="example-value">clickstream events</text>
|
|
<text x="32" y="388" class="example-value">order records</text>
|
|
|
|
<!-- Anonymized -->
|
|
<rect x="204" y="80" width="172" height="380" rx="6" fill="#fff"/>
|
|
<rect x="204" y="80" width="172" height="50" fill="rgba(45,49,66,0.06)" clip-path="url(#clip-anon)"/>
|
|
<rect x="204" y="80" width="172" height="380" rx="6" fill="none" stroke="#2d3142"/>
|
|
<text x="290" y="106" class="tier-title">Anonymized</text>
|
|
<text x="290" y="144" class="bucket">anon-commerce</text>
|
|
<text x="220" y="180" class="field-label">Tool</text>
|
|
<foreignObject x="220" y="186" width="140" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="field-value" style="line-height:1.25">Trino SQL</div></foreignObject>
|
|
<text x="220" y="220" class="field-label">Format</text>
|
|
<foreignObject x="220" y="226" width="140" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="field-value" style="line-height:1.25">Iceberg · partitioned</div></foreignObject>
|
|
<text x="220" y="260" class="field-label">Writer</text>
|
|
<foreignObject x="220" y="266" width="140" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="field-value" style="line-height:1.25">Data Engineer</div></foreignObject>
|
|
<text x="220" y="360" class="example-label">E-COMMERCE EXAMPLE</text>
|
|
<text x="220" y="374" class="example-value">session pseudonyms</text>
|
|
<text x="220" y="388" class="example-value">masked customer IDs</text>
|
|
|
|
<!-- Staging -->
|
|
<rect x="392" y="80" width="172" height="380" rx="6" fill="#fff"/>
|
|
<rect x="392" y="80" width="172" height="50" fill="rgba(45,49,66,0.06)" clip-path="url(#clip-stage)"/>
|
|
<rect x="392" y="80" width="172" height="380" rx="6" fill="none" stroke="#2d3142"/>
|
|
<text x="478" y="106" class="tier-title">Staging</text>
|
|
<text x="478" y="144" class="bucket">staging-commerce</text>
|
|
<text x="408" y="180" class="field-label">Tool</text>
|
|
<foreignObject x="408" y="186" width="140" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="field-value" style="line-height:1.25">Trino · notebooks</div></foreignObject>
|
|
<text x="408" y="220" class="field-label">Format</text>
|
|
<foreignObject x="408" y="226" width="140" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="field-value" style="line-height:1.25">Iceberg · cleaned</div></foreignObject>
|
|
<text x="408" y="260" class="field-label">Writer</text>
|
|
<foreignObject x="408" y="266" width="140" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="field-value" style="line-height:1.25">Data Scientist</div></foreignObject>
|
|
<text x="408" y="360" class="example-label">E-COMMERCE EXAMPLE</text>
|
|
<text x="408" y="374" class="example-value">joined order facts</text>
|
|
<text x="408" y="388" class="example-value">validated event rows</text>
|
|
|
|
<!-- Aggregated focal tier -->
|
|
<rect x="580" y="80" width="172" height="380" rx="6" fill="rgba(235,108,54,0.07)"/>
|
|
<rect x="580" y="80" width="172" height="50" fill="rgba(235,108,54,0.14)" clip-path="url(#clip-aggregate)"/>
|
|
<rect x="580" y="80" width="172" height="380" rx="6" fill="none" stroke="#eb6c36" stroke-width="1.6"/>
|
|
<text x="666" y="106" class="tier-title">Aggregated</text>
|
|
<text x="666" y="144" class="bucket focal-text">analytics-marts</text>
|
|
<text x="596" y="180" class="field-label">Tool</text>
|
|
<foreignObject x="596" y="186" width="140" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="field-value" style="line-height:1.25">Trino INSERT</div></foreignObject>
|
|
<text x="596" y="220" class="field-label">Format</text>
|
|
<foreignObject x="596" y="226" width="140" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="field-value" style="line-height:1.25">Iceberg · metrics</div></foreignObject>
|
|
<text x="596" y="260" class="field-label">Writer</text>
|
|
<foreignObject x="596" y="266" width="140" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="field-value" style="line-height:1.25">Data Scientist</div></foreignObject>
|
|
<text x="596" y="360" class="example-label">E-COMMERCE EXAMPLE</text>
|
|
<text x="596" y="374" class="example-value focal-text">daily conversion rate</text>
|
|
<text x="596" y="388" class="example-value focal-text">revenue by channel</text>
|
|
|
|
<!-- Archive -->
|
|
<rect x="768" y="80" width="172" height="380" rx="6" fill="#ececec"/>
|
|
<rect x="768" y="80" width="172" height="50" fill="rgba(79,93,117,0.18)" clip-path="url(#clip-archive)"/>
|
|
<rect x="768" y="80" width="172" height="380" rx="6" fill="none" stroke="#4f5d75" stroke-dasharray="5,3"/>
|
|
<text x="854" y="106" class="tier-title">Archive</text>
|
|
<text x="854" y="144" class="bucket">archive-commerce</text>
|
|
<text x="784" y="180" class="field-label">Tool</text>
|
|
<foreignObject x="784" y="186" width="140" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="field-value" style="line-height:1.25">Object storage lifecycle</div></foreignObject>
|
|
<text x="784" y="220" class="field-label">Format</text>
|
|
<foreignObject x="784" y="226" width="140" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="field-value" style="line-height:1.25">Cold tier · immutable</div></foreignObject>
|
|
<text x="784" y="260" class="field-label">Writer</text>
|
|
<foreignObject x="784" y="266" width="140" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="field-value" style="line-height:1.25">Data Engineer</div></foreignObject>
|
|
<text x="784" y="360" class="example-label">E-COMMERCE EXAMPLE</text>
|
|
<text x="784" y="374" class="example-value">retained clickstream</text>
|
|
<text x="784" y="388" class="example-value">closed order snapshots</text>
|
|
|
|
<!-- Write-method paths -->
|
|
<rect x="16" y="476" width="460" height="56" rx="6" fill="#fff" stroke="rgba(45,49,66,0.20)"/>
|
|
<rect x="24" y="482" width="64" height="12" rx="2" fill="none" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
|
|
<text x="56" y="491" class="path-tag" fill="#2d3142" font-size="7" text-anchor="middle">SQL PATH</text>
|
|
<text x="96" y="506" class="path-title">Trino INSERT INTO … SELECT</text>
|
|
<text x="96" y="522" class="path-sub">filter · join · aggregate — repeatable transforms</text>
|
|
<rect x="492" y="476" width="460" height="56" rx="6" fill="#fff" stroke="rgba(45,49,66,0.20)"/>
|
|
<rect x="500" y="482" width="96" height="12" rx="2" fill="none" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
|
|
<text x="548" y="491" class="path-tag" fill="#2d3142" font-size="7" text-anchor="middle">NOTEBOOK PATH</text>
|
|
<text x="604" y="506" class="path-title">Python notebooks on object storage</text>
|
|
<text x="604" y="522" class="path-sub">explore · validate · model — interactive analysis</text>
|
|
</svg>
|
|
</main>
|
|
</body>
|
|
</html>
|