@taloswork/ose-shared 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/skills/cozy-static-svg/SKILL.md +76 -0
- package/skills/cozy-static-svg/references/approved-preview.png +0 -0
- package/skills/cozy-static-svg/references/cross-platform.md +73 -0
- package/skills/cozy-static-svg/references/moon_keeps_watch.svg +229 -0
- package/skills/cozy-static-svg/references/style-anchor.md +271 -0
- package/skills/cozy-static-svg/scripts/artkit.py +321 -0
- package/skills/cozy-static-svg/scripts/to_png.py +333 -0
- package/skills/diagram-design/SKILL.md +568 -0
- package/skills/diagram-design/assets/example-architecture-dark.html +182 -0
- package/skills/diagram-design/assets/example-architecture-full.html +194 -0
- package/skills/diagram-design/assets/example-architecture.html +183 -0
- package/skills/diagram-design/assets/example-bar-dark.html +129 -0
- package/skills/diagram-design/assets/example-bar-full.html +105 -0
- package/skills/diagram-design/assets/example-bar.html +129 -0
- package/skills/diagram-design/assets/example-data-flow-dark.html +143 -0
- package/skills/diagram-design/assets/example-data-flow-full.html +185 -0
- package/skills/diagram-design/assets/example-data-flow.html +143 -0
- package/skills/diagram-design/assets/example-datalake-dark.html +243 -0
- package/skills/diagram-design/assets/example-datalake-full.html +248 -0
- package/skills/diagram-design/assets/example-datalake.html +269 -0
- package/skills/diagram-design/assets/example-dp-integration-dark.html +80 -0
- package/skills/diagram-design/assets/example-dp-integration-full.html +90 -0
- package/skills/diagram-design/assets/example-dp-integration.html +80 -0
- package/skills/diagram-design/assets/example-dp-security-matrix-dark.html +31 -0
- package/skills/diagram-design/assets/example-dp-security-matrix-full.html +32 -0
- package/skills/diagram-design/assets/example-dp-security-matrix.html +88 -0
- package/skills/diagram-design/assets/example-er-dark.html +202 -0
- package/skills/diagram-design/assets/example-er-full.html +205 -0
- package/skills/diagram-design/assets/example-er.html +202 -0
- package/skills/diagram-design/assets/example-flowchart-dark.html +156 -0
- package/skills/diagram-design/assets/example-flowchart-full.html +159 -0
- package/skills/diagram-design/assets/example-flowchart.html +156 -0
- package/skills/diagram-design/assets/example-gantt-dark.html +137 -0
- package/skills/diagram-design/assets/example-gantt-full.html +127 -0
- package/skills/diagram-design/assets/example-gantt.html +137 -0
- package/skills/diagram-design/assets/example-high-level-dark.html +251 -0
- package/skills/diagram-design/assets/example-high-level-full.html +247 -0
- package/skills/diagram-design/assets/example-high-level-vertical-dark.html +274 -0
- package/skills/diagram-design/assets/example-high-level-vertical-full.html +252 -0
- package/skills/diagram-design/assets/example-high-level-vertical.html +325 -0
- package/skills/diagram-design/assets/example-high-level.html +301 -0
- package/skills/diagram-design/assets/example-import-drawio.html +185 -0
- package/skills/diagram-design/assets/example-import-mermaid.html +70 -0
- package/skills/diagram-design/assets/example-it-state-dark.html +90 -0
- package/skills/diagram-design/assets/example-it-state-full.html +69 -0
- package/skills/diagram-design/assets/example-it-state.html +128 -0
- package/skills/diagram-design/assets/example-layers-dark.html +123 -0
- package/skills/diagram-design/assets/example-layers-full.html +126 -0
- package/skills/diagram-design/assets/example-layers.html +123 -0
- package/skills/diagram-design/assets/example-line-dark.html +111 -0
- package/skills/diagram-design/assets/example-line-full.html +105 -0
- package/skills/diagram-design/assets/example-line.html +111 -0
- package/skills/diagram-design/assets/example-loop-dark.html +100 -0
- package/skills/diagram-design/assets/example-loop-full.html +137 -0
- package/skills/diagram-design/assets/example-loop-terminal.html +347 -0
- package/skills/diagram-design/assets/example-loop.html +100 -0
- package/skills/diagram-design/assets/example-medallion-dark.html +159 -0
- package/skills/diagram-design/assets/example-medallion-full.html +201 -0
- package/skills/diagram-design/assets/example-medallion.html +159 -0
- package/skills/diagram-design/assets/example-nested-dark.html +132 -0
- package/skills/diagram-design/assets/example-nested-full.html +135 -0
- package/skills/diagram-design/assets/example-nested.html +136 -0
- package/skills/diagram-design/assets/example-org-chart-dark.html +45 -0
- package/skills/diagram-design/assets/example-org-chart-full.html +45 -0
- package/skills/diagram-design/assets/example-org-chart.html +45 -0
- package/skills/diagram-design/assets/example-paved-road-animated.html +546 -0
- package/skills/diagram-design/assets/example-policy-trace-animated.html +490 -0
- package/skills/diagram-design/assets/example-process-dark.html +64 -0
- package/skills/diagram-design/assets/example-process-full.html +74 -0
- package/skills/diagram-design/assets/example-process.html +64 -0
- package/skills/diagram-design/assets/example-pyramid-dark.html +119 -0
- package/skills/diagram-design/assets/example-pyramid-full.html +122 -0
- package/skills/diagram-design/assets/example-pyramid.html +119 -0
- package/skills/diagram-design/assets/example-quadrant-consultant.html +166 -0
- package/skills/diagram-design/assets/example-quadrant-dark.html +135 -0
- package/skills/diagram-design/assets/example-quadrant-full.html +138 -0
- package/skills/diagram-design/assets/example-quadrant.html +135 -0
- package/skills/diagram-design/assets/example-queue-animated.html +577 -0
- package/skills/diagram-design/assets/example-radar-dark.html +139 -0
- package/skills/diagram-design/assets/example-radar-full.html +135 -0
- package/skills/diagram-design/assets/example-radar.html +139 -0
- package/skills/diagram-design/assets/example-scatter-dark.html +141 -0
- package/skills/diagram-design/assets/example-scatter-full.html +116 -0
- package/skills/diagram-design/assets/example-scatter.html +141 -0
- package/skills/diagram-design/assets/example-sequence-dark.html +222 -0
- package/skills/diagram-design/assets/example-sequence-full.html +388 -0
- package/skills/diagram-design/assets/example-sequence-oauth-dark.html +188 -0
- package/skills/diagram-design/assets/example-sequence-oauth-full.html +350 -0
- package/skills/diagram-design/assets/example-sequence-oauth.html +227 -0
- package/skills/diagram-design/assets/example-sequence.html +222 -0
- package/skills/diagram-design/assets/example-state-dark.html +147 -0
- package/skills/diagram-design/assets/example-state-full.html +150 -0
- package/skills/diagram-design/assets/example-state.html +147 -0
- package/skills/diagram-design/assets/example-swimlane-dark.html +172 -0
- package/skills/diagram-design/assets/example-swimlane-full.html +175 -0
- package/skills/diagram-design/assets/example-swimlane.html +172 -0
- package/skills/diagram-design/assets/example-timeline-dark.html +135 -0
- package/skills/diagram-design/assets/example-timeline-full.html +138 -0
- package/skills/diagram-design/assets/example-timeline.html +135 -0
- package/skills/diagram-design/assets/example-tree-dark.html +173 -0
- package/skills/diagram-design/assets/example-tree-full.html +176 -0
- package/skills/diagram-design/assets/example-tree.html +173 -0
- package/skills/diagram-design/assets/example-venn-dark.html +132 -0
- package/skills/diagram-design/assets/example-venn-full.html +135 -0
- package/skills/diagram-design/assets/example-venn.html +110 -0
- package/skills/diagram-design/assets/icons.html +230 -0
- package/skills/diagram-design/assets/index.html +369 -0
- package/skills/diagram-design/assets/template-dark.html +85 -0
- package/skills/diagram-design/assets/template-full.html +413 -0
- package/skills/diagram-design/assets/template-motion.html +434 -0
- package/skills/diagram-design/assets/template-terminal.html +173 -0
- package/skills/diagram-design/assets/template.html +86 -0
- package/skills/diagram-design/references/animation.md +141 -0
- package/skills/diagram-design/references/export.md +136 -0
- package/skills/diagram-design/references/import-drawio.md +171 -0
- package/skills/diagram-design/references/import-mermaid.md +126 -0
- package/skills/diagram-design/references/onboarding.md +297 -0
- package/skills/diagram-design/references/output-spec.md +181 -0
- package/skills/diagram-design/references/primitive-annotation.md +36 -0
- package/skills/diagram-design/references/primitive-icons.md +827 -0
- package/skills/diagram-design/references/primitive-sketchy.md +43 -0
- package/skills/diagram-design/references/primitive-terminal.md +76 -0
- package/skills/diagram-design/references/semantic-patterns.md +122 -0
- package/skills/diagram-design/references/style-guide.md +139 -0
- package/skills/diagram-design/references/type-architecture.md +78 -0
- package/skills/diagram-design/references/type-bar.md +48 -0
- package/skills/diagram-design/references/type-data-flow.md +374 -0
- package/skills/diagram-design/references/type-dp-integration.md +410 -0
- package/skills/diagram-design/references/type-dp-security-matrix.md +379 -0
- package/skills/diagram-design/references/type-er.md +23 -0
- package/skills/diagram-design/references/type-flowchart.md +23 -0
- package/skills/diagram-design/references/type-gantt.md +45 -0
- package/skills/diagram-design/references/type-high-level.md +458 -0
- package/skills/diagram-design/references/type-it-state.md +470 -0
- package/skills/diagram-design/references/type-layers.md +26 -0
- package/skills/diagram-design/references/type-line.md +44 -0
- package/skills/diagram-design/references/type-loop.md +223 -0
- package/skills/diagram-design/references/type-medallion.md +356 -0
- package/skills/diagram-design/references/type-nested.md +22 -0
- package/skills/diagram-design/references/type-org-chart.md +44 -0
- package/skills/diagram-design/references/type-process.md +495 -0
- package/skills/diagram-design/references/type-pyramid.md +33 -0
- package/skills/diagram-design/references/type-quadrant.md +81 -0
- package/skills/diagram-design/references/type-radar.md +80 -0
- package/skills/diagram-design/references/type-scatter.md +39 -0
- package/skills/diagram-design/references/type-sequence.md +130 -0
- package/skills/diagram-design/references/type-state.md +21 -0
- package/skills/diagram-design/references/type-swimlane.md +20 -0
- package/skills/diagram-design/references/type-timeline.md +20 -0
- package/skills/diagram-design/references/type-tree.md +24 -0
- package/skills/diagram-design/references/type-venn.md +26 -0
- package/skills/diagram-design/scripts/drawio_extract.py +856 -0
- package/skills/diagram-design/scripts/mermaid_extract.py +1285 -0
- package/skills/diagram-design/scripts/self_check.py +389 -0
- package/skills/document/bin/doc-gen.cjs +3 -6
- package/skills/document/bin/html2pptx.cjs +17 -9
- package/skills/document/bin/pptx-clone.cjs +41 -30
- package/skills/document/bin/pptx-embed-fonts.cjs +6 -2
- package/skills/document/bin/pptx-slide.cjs +46 -50
- package/skills/document/content-pipeline.md +54 -5
- package/skills/document/layouts/README.md +8 -0
- package/skills/document/layouts/blocks-2x2.tpl +19 -9
- package/skills/document/layouts/cards-3.tpl +1 -1
- package/skills/document/layouts/org-tree.tpl +1 -1
- package/skills/document/layouts/steps-vertical.tpl +1 -1
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8"/>
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
6
|
+
<title>The self-improving loop</title>
|
|
7
|
+
<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"/>
|
|
8
|
+
<style>
|
|
9
|
+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
10
|
+
:root {
|
|
11
|
+
--paper: #f5f5f5; --ink: #2d3142; --muted: #4f5d75; --soft: #7a8399;
|
|
12
|
+
--accent: #eb6c36; --accent-tint: rgba(235,108,54,0.08); --link: #2e5aa8;
|
|
13
|
+
--sans: 'Geist', system-ui, sans-serif; --serif: 'Instrument Serif', serif;
|
|
14
|
+
--mono: 'Geist Mono', ui-monospace, monospace;
|
|
15
|
+
}
|
|
16
|
+
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); }
|
|
17
|
+
.frame { width: 100%; max-width: 1200px; }
|
|
18
|
+
.eyebrow { margin-bottom: 0.5rem; color: var(--muted); font: 500 0.66rem var(--mono); letter-spacing: 0.18em; text-transform: uppercase; }
|
|
19
|
+
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; }
|
|
20
|
+
svg { display: block; width: 100%; min-width: 900px; }
|
|
21
|
+
.ring { fill: none; stroke: var(--muted); stroke-width: 1.2; }
|
|
22
|
+
.spoke { fill: none; stroke: var(--soft); stroke-width: 1; stroke-dasharray: 5 4; }
|
|
23
|
+
.station { fill: var(--paper); stroke: var(--ink); stroke-width: 1; }
|
|
24
|
+
.station.focal { fill: var(--accent-tint); stroke: var(--accent); stroke-width: 1.2; }
|
|
25
|
+
.hub { fill: var(--ink); }
|
|
26
|
+
.node-name { fill: var(--ink); font: 600 12px var(--sans); text-anchor: middle; }
|
|
27
|
+
.focal-name { fill: var(--accent); }
|
|
28
|
+
.sublabel { fill: var(--soft); font: 400 8px var(--mono); text-anchor: middle; }
|
|
29
|
+
.hub-name { fill: var(--paper); font: 600 16px var(--sans); text-anchor: middle; }
|
|
30
|
+
.hub-sub { fill: var(--paper); opacity: 0.72; font: 400 8px var(--mono); text-anchor: middle; }
|
|
31
|
+
.arrow-label { fill: var(--soft); font: 400 8px var(--mono); letter-spacing: 0.06em; text-anchor: middle; }
|
|
32
|
+
</style>
|
|
33
|
+
</head>
|
|
34
|
+
<body>
|
|
35
|
+
<main class="frame">
|
|
36
|
+
<p class="eyebrow">Loop · Diagram Design</p>
|
|
37
|
+
<h1>The self-improving loop</h1>
|
|
38
|
+
|
|
39
|
+
<svg viewBox="0 0 1040 680" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="loop-title loop-desc">
|
|
40
|
+
<title id="loop-title">The self-improving loop</title>
|
|
41
|
+
<desc id="loop-desc">Six stations flow clockwise from Capture through Learn and back to Capture. Each station writes shared state into one central memory hub, with Decide highlighted as the human approval gate.</desc>
|
|
42
|
+
<defs>
|
|
43
|
+
<pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/></pattern>
|
|
44
|
+
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
|
|
45
|
+
<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>
|
|
46
|
+
<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>
|
|
47
|
+
<marker id="arrow-soft" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#7a8399"/></marker>
|
|
48
|
+
</defs>
|
|
49
|
+
<rect width="1040" height="680" fill="#f5f5f5"/>
|
|
50
|
+
<rect width="1040" height="680" fill="url(#dots)" opacity="0.55"/>
|
|
51
|
+
|
|
52
|
+
<!-- Solid clockwise ring: six arcs on the same r=240 station circle. -->
|
|
53
|
+
<path class="ring" d="M600 113.726 A240 240 0 0 1 704.969 187.073" marker-end="url(#arrow)"/>
|
|
54
|
+
<path class="ring" d="M743.285 252 A240 240 0 0 1 743.722 426.882" marker-end="url(#arrow)"/>
|
|
55
|
+
<path class="ring" d="M705.731 492 A240 240 0 0 1 601.130 565.871" marker-end="url(#arrow)"/>
|
|
56
|
+
<path class="ring" d="M440 566.274 A240 240 0 0 1 335.031 492.927" marker-end="url(#arrow)"/>
|
|
57
|
+
<path class="ring" d="M296.715 428 A240 240 0 0 1 296.278 253.118" marker-end="url(#arrow)"/>
|
|
58
|
+
<path class="ring" d="M334.269 188 A240 240 0 0 1 438.870 114.129" marker-end="url(#arrow)"/>
|
|
59
|
+
|
|
60
|
+
<!-- Dashed write-backs: station inner edge to 6px before the hub stroke. -->
|
|
61
|
+
<path class="spoke" d="M520 132 V280" marker-end="url(#arrow-soft)"/>
|
|
62
|
+
<path class="spoke" d="M672 252 L616 284" marker-end="url(#arrow-soft)"/>
|
|
63
|
+
<path class="spoke" d="M672 428 L616 396" marker-end="url(#arrow-soft)"/>
|
|
64
|
+
<path class="spoke" d="M520 548 V400" marker-end="url(#arrow-soft)"/>
|
|
65
|
+
<path class="spoke" d="M368 428 L424 396" marker-end="url(#arrow-soft)"/>
|
|
66
|
+
<path class="spoke" d="M368 252 L424 284" marker-end="url(#arrow-soft)"/>
|
|
67
|
+
|
|
68
|
+
<!-- Curated spoke labels sit beside the line with an 8px visible gap. -->
|
|
69
|
+
<rect x="532" y="200" width="48" height="16" rx="4" fill="#f5f5f5"/>
|
|
70
|
+
<text x="556" y="212" class="arrow-label">SIGNALS</text>
|
|
71
|
+
<rect x="460" y="464" width="52" height="16" rx="4" fill="#f5f5f5"/>
|
|
72
|
+
<text x="486" y="476" class="arrow-label">OUTCOMES</text>
|
|
73
|
+
|
|
74
|
+
<!-- Stations -->
|
|
75
|
+
<rect class="station" x="440" y="68" width="160" height="64" rx="6"/>
|
|
76
|
+
<text x="520" y="96" class="node-name">Capture</text><text x="520" y="116" class="sublabel">signals in / intake</text>
|
|
77
|
+
|
|
78
|
+
<rect class="station" x="648" y="188" width="160" height="64" rx="6"/>
|
|
79
|
+
<text x="728" y="216" class="node-name">Research</text><text x="728" y="236" class="sublabel">evidence pulled</text>
|
|
80
|
+
|
|
81
|
+
<rect class="station focal" x="648" y="428" width="160" height="64" rx="6"/>
|
|
82
|
+
<text x="728" y="456" class="node-name focal-name">Decide</text><text x="728" y="476" class="sublabel">human approves</text>
|
|
83
|
+
|
|
84
|
+
<rect class="station" x="440" y="548" width="160" height="64" rx="6"/>
|
|
85
|
+
<text x="520" y="576" class="node-name">Act</text><text x="520" y="596" class="sublabel">work ships</text>
|
|
86
|
+
|
|
87
|
+
<rect class="station" x="232" y="428" width="160" height="64" rx="6"/>
|
|
88
|
+
<text x="312" y="456" class="node-name">Measure</text><text x="312" y="476" class="sublabel">outcomes logged</text>
|
|
89
|
+
|
|
90
|
+
<rect class="station" x="232" y="188" width="160" height="64" rx="6"/>
|
|
91
|
+
<text x="312" y="216" class="node-name">Learn</text><text x="312" y="236" class="sublabel">playbook updated</text>
|
|
92
|
+
|
|
93
|
+
<!-- The one shared-state hub. -->
|
|
94
|
+
<rect class="hub" x="420" y="288" width="200" height="104" rx="8"/>
|
|
95
|
+
<text x="520" y="336" class="hub-name">Shared memory</text>
|
|
96
|
+
<text x="520" y="360" class="hub-sub">one record, every loop</text>
|
|
97
|
+
</svg>
|
|
98
|
+
</main>
|
|
99
|
+
</body>
|
|
100
|
+
</html>
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>E-commerce analytics · Medallion · Dark</title>
|
|
7
|
+
<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">
|
|
8
|
+
<style>
|
|
9
|
+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
10
|
+
:root {
|
|
11
|
+
--paper: #2d3142; --paper-2: #393e53; --ink: #f5f5f5; --muted: #bfc0c0;
|
|
12
|
+
--soft: #8e98ac; --rule: rgba(245,245,245,0.12); --accent: #f08a59;
|
|
13
|
+
--accent-tint: rgba(240,138,89,0.10); --link: #6a95d8;
|
|
14
|
+
--sans: 'Geist', system-ui, sans-serif; --serif: 'Instrument Serif', serif;
|
|
15
|
+
--mono: 'Geist Mono', ui-monospace, monospace;
|
|
16
|
+
}
|
|
17
|
+
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); }
|
|
18
|
+
.frame { width: 100%; max-width: 1200px; }
|
|
19
|
+
.eyebrow { margin-bottom: 0.5rem; color: var(--muted); font: 500 0.66rem var(--mono); letter-spacing: 0.18em; text-transform: uppercase; }
|
|
20
|
+
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; }
|
|
21
|
+
svg { display: block; width: 100%; min-width: 1040px; }
|
|
22
|
+
.tier-title { fill: var(--ink); font: 600 13px var(--sans); text-anchor: middle; }
|
|
23
|
+
.bucket, .field-value, .example-value { fill: var(--muted); font: 400 9px var(--mono); }
|
|
24
|
+
.bucket { text-anchor: middle; }
|
|
25
|
+
.field-value { color: var(--muted); }
|
|
26
|
+
.focal-text { fill: var(--accent); }
|
|
27
|
+
.field-label { fill: var(--ink); font: 600 11px var(--sans); }
|
|
28
|
+
.example-label, .arc-label, .path-tag { font-family: var(--mono); font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; }
|
|
29
|
+
.example-label { fill: var(--soft); font-size: 8px; }
|
|
30
|
+
.arc-label { font-size: 10px; text-anchor: middle; }
|
|
31
|
+
.path-title { fill: var(--ink); font: 600 11px var(--sans); }
|
|
32
|
+
.path-sub { fill: var(--muted); font: 400 9px var(--mono); }
|
|
33
|
+
</style>
|
|
34
|
+
</head>
|
|
35
|
+
<body>
|
|
36
|
+
<main class="frame">
|
|
37
|
+
<p class="eyebrow">Medallion · Diagram Design</p>
|
|
38
|
+
<h1>Five-tier e-commerce analytics storage</h1>
|
|
39
|
+
|
|
40
|
+
<svg viewBox="0 0 1040 548" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="medallion-dark-title medallion-dark-desc">
|
|
41
|
+
<title id="medallion-dark-title">Five-tier e-commerce analytics medallion</title>
|
|
42
|
+
<desc id="medallion-dark-desc">Clickstream events and order records move from raw storage through anonymized, staging, and aggregated tiers before lifecycle archiving.</desc>
|
|
43
|
+
<defs>
|
|
44
|
+
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#bfc0c0"/></marker>
|
|
45
|
+
<marker id="arrow-accent" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f08a59"/></marker>
|
|
46
|
+
<marker id="arrow-link" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#6a95d8"/></marker>
|
|
47
|
+
<clipPath id="clip-raw"><rect x="16" y="80" width="172" height="380" rx="6"/></clipPath>
|
|
48
|
+
<clipPath id="clip-anon"><rect x="204" y="80" width="172" height="380" rx="6"/></clipPath>
|
|
49
|
+
<clipPath id="clip-stage"><rect x="392" y="80" width="172" height="380" rx="6"/></clipPath>
|
|
50
|
+
<clipPath id="clip-aggregate"><rect x="580" y="80" width="172" height="380" rx="6"/></clipPath>
|
|
51
|
+
<clipPath id="clip-archive"><rect x="768" y="80" width="172" height="380" rx="6"/></clipPath>
|
|
52
|
+
</defs>
|
|
53
|
+
<rect width="1040" height="548" fill="#2d3142"/>
|
|
54
|
+
|
|
55
|
+
<!-- Promotion arcs are the medallion type's required connector grammar. -->
|
|
56
|
+
<path d="M102 80 C102 0 290 0 290 80" fill="none" stroke="#bfc0c0" stroke-width="1.4" marker-end="url(#arrow)"/>
|
|
57
|
+
<path d="M290 80 C290 0 478 0 478 80" fill="none" stroke="#bfc0c0" stroke-width="1.4" marker-end="url(#arrow)"/>
|
|
58
|
+
<path d="M478 80 C478 0 666 0 666 80" fill="none" stroke="#f08a59" stroke-width="1.6" marker-end="url(#arrow-accent)"/>
|
|
59
|
+
<path d="M666 80 C666 0 854 0 854 80" fill="none" stroke="#bfc0c0" stroke-width="1.4" stroke-dasharray="4,3" marker-end="url(#arrow)"/>
|
|
60
|
+
<text x="196" y="50" class="arc-label" fill="#bfc0c0">MASK IDS</text>
|
|
61
|
+
<text x="384" y="50" class="arc-label" fill="#bfc0c0">CLEAN + JOIN</text>
|
|
62
|
+
<text x="572" y="50" class="arc-label" fill="#f08a59">AGGREGATE</text>
|
|
63
|
+
<text x="760" y="50" class="arc-label" fill="#bfc0c0">LIFECYCLE</text>
|
|
64
|
+
|
|
65
|
+
<!-- Raw -->
|
|
66
|
+
<rect x="16" y="80" width="172" height="380" rx="6" fill="rgba(245,245,245,0.04)"/>
|
|
67
|
+
<rect x="16" y="80" width="172" height="50" fill="rgba(142,152,172,0.16)" clip-path="url(#clip-raw)"/>
|
|
68
|
+
<rect x="16" y="80" width="172" height="380" rx="6" fill="none" stroke="#bfc0c0"/>
|
|
69
|
+
<text x="102" y="106" class="tier-title">Raw</text>
|
|
70
|
+
<text x="102" y="144" class="bucket">raw-commerce</text>
|
|
71
|
+
<text x="32" y="180" class="field-label">Tool</text>
|
|
72
|
+
<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>
|
|
73
|
+
<text x="32" y="220" class="field-label">Format</text>
|
|
74
|
+
<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>
|
|
75
|
+
<text x="32" y="260" class="field-label">Writer</text>
|
|
76
|
+
<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>
|
|
77
|
+
<text x="32" y="360" class="example-label">E-COMMERCE EXAMPLE</text>
|
|
78
|
+
<text x="32" y="374" class="example-value">clickstream events</text>
|
|
79
|
+
<text x="32" y="388" class="example-value">order records</text>
|
|
80
|
+
|
|
81
|
+
<!-- Anonymized -->
|
|
82
|
+
<rect x="204" y="80" width="172" height="380" rx="6" fill="rgba(245,245,245,0.04)"/>
|
|
83
|
+
<rect x="204" y="80" width="172" height="50" fill="rgba(245,245,245,0.08)" clip-path="url(#clip-anon)"/>
|
|
84
|
+
<rect x="204" y="80" width="172" height="380" rx="6" fill="none" stroke="rgba(245,245,245,0.30)"/>
|
|
85
|
+
<text x="290" y="106" class="tier-title">Anonymized</text>
|
|
86
|
+
<text x="290" y="144" class="bucket">anon-commerce</text>
|
|
87
|
+
<text x="220" y="180" class="field-label">Tool</text>
|
|
88
|
+
<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>
|
|
89
|
+
<text x="220" y="220" class="field-label">Format</text>
|
|
90
|
+
<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>
|
|
91
|
+
<text x="220" y="260" class="field-label">Writer</text>
|
|
92
|
+
<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>
|
|
93
|
+
<text x="220" y="360" class="example-label">E-COMMERCE EXAMPLE</text>
|
|
94
|
+
<text x="220" y="374" class="example-value">session pseudonyms</text>
|
|
95
|
+
<text x="220" y="388" class="example-value">masked customer IDs</text>
|
|
96
|
+
|
|
97
|
+
<!-- Staging -->
|
|
98
|
+
<rect x="392" y="80" width="172" height="380" rx="6" fill="rgba(245,245,245,0.04)"/>
|
|
99
|
+
<rect x="392" y="80" width="172" height="50" fill="rgba(245,245,245,0.08)" clip-path="url(#clip-stage)"/>
|
|
100
|
+
<rect x="392" y="80" width="172" height="380" rx="6" fill="none" stroke="rgba(245,245,245,0.30)"/>
|
|
101
|
+
<text x="478" y="106" class="tier-title">Staging</text>
|
|
102
|
+
<text x="478" y="144" class="bucket">staging-commerce</text>
|
|
103
|
+
<text x="408" y="180" class="field-label">Tool</text>
|
|
104
|
+
<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>
|
|
105
|
+
<text x="408" y="220" class="field-label">Format</text>
|
|
106
|
+
<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>
|
|
107
|
+
<text x="408" y="260" class="field-label">Writer</text>
|
|
108
|
+
<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>
|
|
109
|
+
<text x="408" y="360" class="example-label">E-COMMERCE EXAMPLE</text>
|
|
110
|
+
<text x="408" y="374" class="example-value">joined order facts</text>
|
|
111
|
+
<text x="408" y="388" class="example-value">validated event rows</text>
|
|
112
|
+
|
|
113
|
+
<!-- Aggregated focal tier -->
|
|
114
|
+
<rect x="580" y="80" width="172" height="380" rx="6" fill="rgba(240,138,89,0.12)"/>
|
|
115
|
+
<rect x="580" y="80" width="172" height="50" fill="rgba(240,138,89,0.20)" clip-path="url(#clip-aggregate)"/>
|
|
116
|
+
<rect x="580" y="80" width="172" height="380" rx="6" fill="none" stroke="#f08a59" stroke-width="1.6"/>
|
|
117
|
+
<text x="666" y="106" class="tier-title">Aggregated</text>
|
|
118
|
+
<text x="666" y="144" class="bucket focal-text">analytics-marts</text>
|
|
119
|
+
<text x="596" y="180" class="field-label">Tool</text>
|
|
120
|
+
<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>
|
|
121
|
+
<text x="596" y="220" class="field-label">Format</text>
|
|
122
|
+
<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>
|
|
123
|
+
<text x="596" y="260" class="field-label">Writer</text>
|
|
124
|
+
<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>
|
|
125
|
+
<text x="596" y="360" class="example-label">E-COMMERCE EXAMPLE</text>
|
|
126
|
+
<text x="596" y="374" class="example-value focal-text">daily conversion rate</text>
|
|
127
|
+
<text x="596" y="388" class="example-value focal-text">revenue by channel</text>
|
|
128
|
+
|
|
129
|
+
<!-- Archive -->
|
|
130
|
+
<rect x="768" y="80" width="172" height="380" rx="6" fill="rgba(245,245,245,0.06)"/>
|
|
131
|
+
<rect x="768" y="80" width="172" height="50" fill="rgba(142,152,172,0.24)" clip-path="url(#clip-archive)"/>
|
|
132
|
+
<rect x="768" y="80" width="172" height="380" rx="6" fill="none" stroke="#bfc0c0" stroke-dasharray="5,3"/>
|
|
133
|
+
<text x="854" y="106" class="tier-title">Archive</text>
|
|
134
|
+
<text x="854" y="144" class="bucket">archive-commerce</text>
|
|
135
|
+
<text x="784" y="180" class="field-label">Tool</text>
|
|
136
|
+
<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>
|
|
137
|
+
<text x="784" y="220" class="field-label">Format</text>
|
|
138
|
+
<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>
|
|
139
|
+
<text x="784" y="260" class="field-label">Writer</text>
|
|
140
|
+
<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>
|
|
141
|
+
<text x="784" y="360" class="example-label">E-COMMERCE EXAMPLE</text>
|
|
142
|
+
<text x="784" y="374" class="example-value">retained clickstream</text>
|
|
143
|
+
<text x="784" y="388" class="example-value">closed order snapshots</text>
|
|
144
|
+
|
|
145
|
+
<!-- Write-method paths -->
|
|
146
|
+
<rect x="16" y="476" width="460" height="56" rx="6" fill="rgba(245,245,245,0.04)" stroke="rgba(245,245,245,0.20)"/>
|
|
147
|
+
<rect x="24" y="482" width="64" height="12" rx="2" fill="none" stroke="rgba(245,245,245,0.30)" stroke-width="0.8"/>
|
|
148
|
+
<text x="56" y="491" class="path-tag" fill="#f5f5f5" font-size="7" text-anchor="middle">SQL PATH</text>
|
|
149
|
+
<text x="96" y="506" class="path-title">Trino INSERT INTO … SELECT</text>
|
|
150
|
+
<text x="96" y="522" class="path-sub">filter · join · aggregate — repeatable transforms</text>
|
|
151
|
+
<rect x="492" y="476" width="460" height="56" rx="6" fill="rgba(245,245,245,0.04)" stroke="rgba(245,245,245,0.20)"/>
|
|
152
|
+
<rect x="500" y="482" width="96" height="12" rx="2" fill="none" stroke="rgba(245,245,245,0.30)" stroke-width="0.8"/>
|
|
153
|
+
<text x="548" y="491" class="path-tag" fill="#f5f5f5" font-size="7" text-anchor="middle">NOTEBOOK PATH</text>
|
|
154
|
+
<text x="604" y="506" class="path-title">Python notebooks on object storage</text>
|
|
155
|
+
<text x="604" y="522" class="path-sub">explore · validate · model — interactive analysis</text>
|
|
156
|
+
</svg>
|
|
157
|
+
</main>
|
|
158
|
+
</body>
|
|
159
|
+
</html>
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>E-commerce analytics · Medallion · Full</title>
|
|
7
|
+
<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">
|
|
8
|
+
<style>
|
|
9
|
+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
10
|
+
:root {
|
|
11
|
+
--paper: #f5f5f5; --paper-2: #ececec; --ink: #2d3142; --muted: #4f5d75;
|
|
12
|
+
--soft: #7a8399; --rule: rgba(45,49,66,0.12); --accent: #eb6c36;
|
|
13
|
+
--accent-tint: rgba(235,108,54,0.08); --link: #2e5aa8;
|
|
14
|
+
--sans: 'Geist', system-ui, sans-serif; --serif: 'Instrument Serif', serif;
|
|
15
|
+
--mono: 'Geist Mono', ui-monospace, monospace;
|
|
16
|
+
}
|
|
17
|
+
body { min-height: 100vh; padding: 3rem 2rem; background: var(--paper); color: var(--ink); font-family: var(--sans); }
|
|
18
|
+
.container { width: 100%; max-width: 1200px; margin: 0 auto; }
|
|
19
|
+
.eyebrow { margin-bottom: 0.5rem; color: var(--muted); font: 500 0.66rem var(--mono); letter-spacing: 0.18em; text-transform: uppercase; }
|
|
20
|
+
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; }
|
|
21
|
+
svg { display: block; width: 100%; min-width: 1040px; }
|
|
22
|
+
.tier-title { fill: var(--ink); font: 600 13px var(--sans); text-anchor: middle; }
|
|
23
|
+
.bucket, .field-value, .example-value { fill: var(--muted); font: 400 9px var(--mono); }
|
|
24
|
+
.bucket { text-anchor: middle; }
|
|
25
|
+
.field-value { color: var(--muted); }
|
|
26
|
+
.focal-text { fill: var(--accent); }
|
|
27
|
+
.field-label { fill: var(--ink); font: 600 11px var(--sans); }
|
|
28
|
+
.example-label, .arc-label, .path-tag { font-family: var(--mono); font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; }
|
|
29
|
+
.example-label { fill: var(--soft); font-size: 8px; }
|
|
30
|
+
.arc-label { font-size: 10px; text-anchor: middle; }
|
|
31
|
+
.path-title { fill: var(--ink); font: 600 11px var(--sans); }
|
|
32
|
+
.path-sub { fill: var(--muted); font: 400 9px var(--mono); }
|
|
33
|
+
.header { margin-bottom: 2.5rem; }
|
|
34
|
+
.header h1 { margin-bottom: 0.5rem; }
|
|
35
|
+
.subtitle { max-width: 62ch; color: var(--muted); font-size: 1rem; line-height: 1.55; }
|
|
36
|
+
.diagram-container { overflow-x: auto; padding: 1.5rem; background: var(--paper-2); border: 1px solid var(--rule); border-radius: 8px; }
|
|
37
|
+
.cards { display: grid; grid-template-columns: 1.1fr 1fr 0.9fr; gap: 1rem; margin-top: 1.5rem; }
|
|
38
|
+
.card { padding: 1.25rem; background: #fff; border: 1px solid var(--rule); border-radius: 6px; }
|
|
39
|
+
.card .card-eyebrow { margin-bottom: 0.5rem; color: var(--muted); font: 500 0.5rem var(--mono); letter-spacing: 0.18em; text-transform: uppercase; }
|
|
40
|
+
.card-header { display: flex; gap: 0.6rem; align-items: center; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(45,49,66,0.08); }
|
|
41
|
+
.card-dot { width: 7px; height: 7px; border-radius: 50%; }
|
|
42
|
+
.card-dot.coral { background: var(--accent); } .card-dot.ink { background: var(--ink); } .card-dot.muted { background: var(--muted); }
|
|
43
|
+
.card h2 { font-size: 0.875rem; font-weight: 600; }
|
|
44
|
+
.card p, .card ul { color: var(--muted); font-size: 0.8125rem; line-height: 1.55; list-style: none; }
|
|
45
|
+
.card li { position: relative; margin-bottom: 0.3rem; padding-left: 0.875rem; }
|
|
46
|
+
.card li::before { position: absolute; left: 0; color: rgba(45,49,66,0.25); content: '—'; }
|
|
47
|
+
.footer { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.5rem; margin-top: 2rem; padding-top: 1.5rem; color: var(--soft); border-top: 1px solid rgba(45,49,66,0.10); font: 400 0.72rem var(--mono); letter-spacing: 0.06em; }
|
|
48
|
+
@media (max-width: 820px) { .cards { grid-template-columns: 1fr; } }
|
|
49
|
+
</style>
|
|
50
|
+
</head>
|
|
51
|
+
<body>
|
|
52
|
+
<main class="container">
|
|
53
|
+
<header class="header">
|
|
54
|
+
<p class="eyebrow">Medallion · Diagram Design</p>
|
|
55
|
+
<h1>Five-tier e-commerce analytics storage</h1>
|
|
56
|
+
<p class="subtitle">A quality ladder for clickstream events and order records, from immutable landing data to dashboard-ready metrics and cold retention.</p>
|
|
57
|
+
</header>
|
|
58
|
+
|
|
59
|
+
<div class="diagram-container">
|
|
60
|
+
<svg viewBox="0 0 1040 548" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="medallion-full-title medallion-full-desc">
|
|
61
|
+
<title id="medallion-full-title">Five-tier e-commerce analytics medallion</title>
|
|
62
|
+
<desc id="medallion-full-desc">Clickstream events and order records move from raw storage through anonymized, staging, and aggregated tiers before lifecycle archiving.</desc>
|
|
63
|
+
<defs>
|
|
64
|
+
<marker id="arrow" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#4f5d75"/></marker>
|
|
65
|
+
<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>
|
|
66
|
+
<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>
|
|
67
|
+
<clipPath id="clip-raw"><rect x="16" y="80" width="172" height="380" rx="6"/></clipPath>
|
|
68
|
+
<clipPath id="clip-anon"><rect x="204" y="80" width="172" height="380" rx="6"/></clipPath>
|
|
69
|
+
<clipPath id="clip-stage"><rect x="392" y="80" width="172" height="380" rx="6"/></clipPath>
|
|
70
|
+
<clipPath id="clip-aggregate"><rect x="580" y="80" width="172" height="380" rx="6"/></clipPath>
|
|
71
|
+
<clipPath id="clip-archive"><rect x="768" y="80" width="172" height="380" rx="6"/></clipPath>
|
|
72
|
+
</defs>
|
|
73
|
+
<rect width="1040" height="548" fill="#f5f5f5"/>
|
|
74
|
+
|
|
75
|
+
<!-- Promotion arcs are the medallion type's required connector grammar. -->
|
|
76
|
+
<path d="M102 80 C102 0 290 0 290 80" fill="none" stroke="#4f5d75" stroke-width="1.4" marker-end="url(#arrow)"/>
|
|
77
|
+
<path d="M290 80 C290 0 478 0 478 80" fill="none" stroke="#4f5d75" stroke-width="1.4" marker-end="url(#arrow)"/>
|
|
78
|
+
<path d="M478 80 C478 0 666 0 666 80" fill="none" stroke="#eb6c36" stroke-width="1.6" marker-end="url(#arrow-accent)"/>
|
|
79
|
+
<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)"/>
|
|
80
|
+
<text x="196" y="50" class="arc-label" fill="#4f5d75">MASK IDS</text>
|
|
81
|
+
<text x="384" y="50" class="arc-label" fill="#4f5d75">CLEAN + JOIN</text>
|
|
82
|
+
<text x="572" y="50" class="arc-label" fill="#eb6c36">AGGREGATE</text>
|
|
83
|
+
<text x="760" y="50" class="arc-label" fill="#4f5d75">LIFECYCLE</text>
|
|
84
|
+
|
|
85
|
+
<!-- Raw -->
|
|
86
|
+
<rect x="16" y="80" width="172" height="380" rx="6" fill="#fff"/>
|
|
87
|
+
<rect x="16" y="80" width="172" height="50" fill="rgba(79,93,117,0.10)" clip-path="url(#clip-raw)"/>
|
|
88
|
+
<rect x="16" y="80" width="172" height="380" rx="6" fill="none" stroke="#4f5d75"/>
|
|
89
|
+
<text x="102" y="106" class="tier-title">Raw</text>
|
|
90
|
+
<text x="102" y="144" class="bucket">raw-commerce</text>
|
|
91
|
+
<text x="32" y="180" class="field-label">Tool</text>
|
|
92
|
+
<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>
|
|
93
|
+
<text x="32" y="220" class="field-label">Format</text>
|
|
94
|
+
<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>
|
|
95
|
+
<text x="32" y="260" class="field-label">Writer</text>
|
|
96
|
+
<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>
|
|
97
|
+
<text x="32" y="360" class="example-label">E-COMMERCE EXAMPLE</text>
|
|
98
|
+
<text x="32" y="374" class="example-value">clickstream events</text>
|
|
99
|
+
<text x="32" y="388" class="example-value">order records</text>
|
|
100
|
+
|
|
101
|
+
<!-- Anonymized -->
|
|
102
|
+
<rect x="204" y="80" width="172" height="380" rx="6" fill="#fff"/>
|
|
103
|
+
<rect x="204" y="80" width="172" height="50" fill="rgba(45,49,66,0.06)" clip-path="url(#clip-anon)"/>
|
|
104
|
+
<rect x="204" y="80" width="172" height="380" rx="6" fill="none" stroke="#2d3142"/>
|
|
105
|
+
<text x="290" y="106" class="tier-title">Anonymized</text>
|
|
106
|
+
<text x="290" y="144" class="bucket">anon-commerce</text>
|
|
107
|
+
<text x="220" y="180" class="field-label">Tool</text>
|
|
108
|
+
<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>
|
|
109
|
+
<text x="220" y="220" class="field-label">Format</text>
|
|
110
|
+
<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>
|
|
111
|
+
<text x="220" y="260" class="field-label">Writer</text>
|
|
112
|
+
<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>
|
|
113
|
+
<text x="220" y="360" class="example-label">E-COMMERCE EXAMPLE</text>
|
|
114
|
+
<text x="220" y="374" class="example-value">session pseudonyms</text>
|
|
115
|
+
<text x="220" y="388" class="example-value">masked customer IDs</text>
|
|
116
|
+
|
|
117
|
+
<!-- Staging -->
|
|
118
|
+
<rect x="392" y="80" width="172" height="380" rx="6" fill="#fff"/>
|
|
119
|
+
<rect x="392" y="80" width="172" height="50" fill="rgba(45,49,66,0.06)" clip-path="url(#clip-stage)"/>
|
|
120
|
+
<rect x="392" y="80" width="172" height="380" rx="6" fill="none" stroke="#2d3142"/>
|
|
121
|
+
<text x="478" y="106" class="tier-title">Staging</text>
|
|
122
|
+
<text x="478" y="144" class="bucket">staging-commerce</text>
|
|
123
|
+
<text x="408" y="180" class="field-label">Tool</text>
|
|
124
|
+
<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>
|
|
125
|
+
<text x="408" y="220" class="field-label">Format</text>
|
|
126
|
+
<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>
|
|
127
|
+
<text x="408" y="260" class="field-label">Writer</text>
|
|
128
|
+
<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>
|
|
129
|
+
<text x="408" y="360" class="example-label">E-COMMERCE EXAMPLE</text>
|
|
130
|
+
<text x="408" y="374" class="example-value">joined order facts</text>
|
|
131
|
+
<text x="408" y="388" class="example-value">validated event rows</text>
|
|
132
|
+
|
|
133
|
+
<!-- Aggregated focal tier -->
|
|
134
|
+
<rect x="580" y="80" width="172" height="380" rx="6" fill="rgba(235,108,54,0.07)"/>
|
|
135
|
+
<rect x="580" y="80" width="172" height="50" fill="rgba(235,108,54,0.14)" clip-path="url(#clip-aggregate)"/>
|
|
136
|
+
<rect x="580" y="80" width="172" height="380" rx="6" fill="none" stroke="#eb6c36" stroke-width="1.6"/>
|
|
137
|
+
<text x="666" y="106" class="tier-title">Aggregated</text>
|
|
138
|
+
<text x="666" y="144" class="bucket focal-text">analytics-marts</text>
|
|
139
|
+
<text x="596" y="180" class="field-label">Tool</text>
|
|
140
|
+
<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>
|
|
141
|
+
<text x="596" y="220" class="field-label">Format</text>
|
|
142
|
+
<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>
|
|
143
|
+
<text x="596" y="260" class="field-label">Writer</text>
|
|
144
|
+
<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>
|
|
145
|
+
<text x="596" y="360" class="example-label">E-COMMERCE EXAMPLE</text>
|
|
146
|
+
<text x="596" y="374" class="example-value focal-text">daily conversion rate</text>
|
|
147
|
+
<text x="596" y="388" class="example-value focal-text">revenue by channel</text>
|
|
148
|
+
|
|
149
|
+
<!-- Archive -->
|
|
150
|
+
<rect x="768" y="80" width="172" height="380" rx="6" fill="#ececec"/>
|
|
151
|
+
<rect x="768" y="80" width="172" height="50" fill="rgba(79,93,117,0.18)" clip-path="url(#clip-archive)"/>
|
|
152
|
+
<rect x="768" y="80" width="172" height="380" rx="6" fill="none" stroke="#4f5d75" stroke-dasharray="5,3"/>
|
|
153
|
+
<text x="854" y="106" class="tier-title">Archive</text>
|
|
154
|
+
<text x="854" y="144" class="bucket">archive-commerce</text>
|
|
155
|
+
<text x="784" y="180" class="field-label">Tool</text>
|
|
156
|
+
<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>
|
|
157
|
+
<text x="784" y="220" class="field-label">Format</text>
|
|
158
|
+
<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>
|
|
159
|
+
<text x="784" y="260" class="field-label">Writer</text>
|
|
160
|
+
<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>
|
|
161
|
+
<text x="784" y="360" class="example-label">E-COMMERCE EXAMPLE</text>
|
|
162
|
+
<text x="784" y="374" class="example-value">retained clickstream</text>
|
|
163
|
+
<text x="784" y="388" class="example-value">closed order snapshots</text>
|
|
164
|
+
|
|
165
|
+
<!-- Write-method paths -->
|
|
166
|
+
<rect x="16" y="476" width="460" height="56" rx="6" fill="#fff" stroke="rgba(45,49,66,0.20)"/>
|
|
167
|
+
<rect x="24" y="482" width="64" height="12" rx="2" fill="none" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
|
|
168
|
+
<text x="56" y="491" class="path-tag" fill="#2d3142" font-size="7" text-anchor="middle">SQL PATH</text>
|
|
169
|
+
<text x="96" y="506" class="path-title">Trino INSERT INTO … SELECT</text>
|
|
170
|
+
<text x="96" y="522" class="path-sub">filter · join · aggregate — repeatable transforms</text>
|
|
171
|
+
<rect x="492" y="476" width="460" height="56" rx="6" fill="#fff" stroke="rgba(45,49,66,0.20)"/>
|
|
172
|
+
<rect x="500" y="482" width="96" height="12" rx="2" fill="none" stroke="rgba(45,49,66,0.30)" stroke-width="0.8"/>
|
|
173
|
+
<text x="548" y="491" class="path-tag" fill="#2d3142" font-size="7" text-anchor="middle">NOTEBOOK PATH</text>
|
|
174
|
+
<text x="604" y="506" class="path-title">Python notebooks on object storage</text>
|
|
175
|
+
<text x="604" y="522" class="path-sub">explore · validate · model — interactive analysis</text>
|
|
176
|
+
</svg>
|
|
177
|
+
</div>
|
|
178
|
+
|
|
179
|
+
<section class="cards" aria-label="Diagram summary">
|
|
180
|
+
<article class="card">
|
|
181
|
+
<p class="card-eyebrow">THE HEADLINE</p>
|
|
182
|
+
<div class="card-header"><span class="card-dot coral"></span><h2>Aggregated is the query surface</h2></div>
|
|
183
|
+
<p>Dashboards read stable metrics instead of recomputing joins across raw commerce records.</p>
|
|
184
|
+
</article>
|
|
185
|
+
<article class="card">
|
|
186
|
+
<div class="card-header"><span class="card-dot ink"></span><h2>Quality rises by tier</h2></div>
|
|
187
|
+
<ul><li>Identifiers are masked first</li><li>Events and orders are validated</li><li>Metrics are versioned for reuse</li></ul>
|
|
188
|
+
</article>
|
|
189
|
+
<article class="card">
|
|
190
|
+
<div class="card-header"><span class="card-dot muted"></span><h2>Two write modes</h2></div>
|
|
191
|
+
<p>Trino handles repeatable promotion jobs; notebooks support exploration before logic is operationalized.</p>
|
|
192
|
+
</article>
|
|
193
|
+
</section>
|
|
194
|
+
|
|
195
|
+
<footer class="footer">
|
|
196
|
+
<span>e-commerce analytics · medallion</span>
|
|
197
|
+
<span>example · schematic skill</span>
|
|
198
|
+
</footer>
|
|
199
|
+
</main>
|
|
200
|
+
</body>
|
|
201
|
+
</html>
|