Skip to content

Instantly share code, notes, and snippets.

@lassebenni
Created August 17, 2026 07:58
Show Gist options
  • Select an option

  • Save lassebenni/e2195ff7ffc5dfcbff3fe9028fbd2f90 to your computer and use it in GitHub Desktop.

Select an option

Save lassebenni/e2195ff7ffc5dfcbff3fe9028fbd2f90 to your computer and use it in GitHub Desktop.
Visual: Week 15 staging table swap
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Visual: Staging table swap</title>
<style>
body {
background-color: #1a1a1a;
color: #f0f0f0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
margin: 0;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
svg {
background-color: #252526;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
width: 100%;
max-width: 640px;
}
.schema-label { fill: #8b949e; font-size: 12px; font-weight: 600; }
.table-box { stroke-width: 2; rx: 6; }
.table-live { fill: rgba(56, 142, 60, 0.15); stroke: #388e3c; }
.table-staging { fill: rgba(88, 166, 255, 0.12); stroke: #58a6ff; }
.table-empty { fill: rgba(248, 81, 73, 0.08); stroke: #f85149; stroke-dasharray: 6 4; }
.table-text { fill: #e0e0e0; font-family: monospace; font-size: 13px; text-anchor: middle; }
.step-label { fill: #c9d1d9; font-size: 13px; font-weight: 600; }
.note { fill: #a0a0a0; font-size: 12px; }
.arrow { stroke: #888; stroke-width: 2; fill: none; }
.arrow-head { fill: #888; }
.reader { fill: #ffa657; font-size: 11px; font-weight: 700; }
.ok { fill: #3fb950; }
.bad { fill: #f85149; }
</style>
</head>
<body>
<svg viewBox="0 0 640 420" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" class="arrow-head" />
</marker>
</defs>
<text x="320" y="28" fill="#f0f0f0" font-size="16" font-weight="700" text-anchor="middle">Outbound publish: load staging, then swap in one transaction</text>
<!-- Step 1 -->
<text class="step-label" x="24" y="58">1. Before</text>
<text class="schema-label" x="120" y="78">analytics schema</text>
<rect class="table-box table-live" x="60" y="88" width="160" height="44" />
<text class="table-text" x="140" y="114">fct_postings</text>
<text class="note" x="140" y="148" text-anchor="middle">yesterday's rows (readers see this)</text>
<text class="reader ok" x="250" y="114">reader ✓</text>
<!-- Step 2 -->
<text class="step-label" x="24" y="188">2. Load staging</text>
<rect class="table-box table-live" x="60" y="198" width="160" height="44" />
<text class="table-text" x="140" y="224">fct_postings</text>
<rect class="table-box table-staging" x="280" y="198" width="200" height="44" />
<text class="table-text" x="380" y="224">fct_postings__staging</text>
<path class="arrow" d="M 240 220 L 272 220" marker-end="url(#arrowhead)" />
<text class="note" x="380" y="258" text-anchor="middle">INSERT today's rows here</text>
<text class="reader ok" x="520" y="224">reader still ✓</text>
<!-- Step 3 -->
<text class="step-label" x="24" y="298">3. Swap (one transaction)</text>
<rect class="table-box table-empty" x="60" y="308" width="160" height="44" />
<text class="table-text" x="140" y="334">(dropped)</text>
<rect class="table-box table-live" x="280" y="308" width="200" height="44" />
<text class="table-text" x="380" y="334">fct_postings</text>
<text class="note" x="380" y="368" text-anchor="middle">RENAME staging → published</text>
<text class="reader ok" x="520" y="334">reader ✓</text>
<!-- Bad path -->
<text class="step-label bad" x="24" y="400">Never: truncate live table first</text>
<rect class="table-box table-empty" x="200" y="386" width="160" height="28" />
<text class="table-text" x="280" y="405" font-size="11">empty table mid-sync</text>
<text class="reader bad" x="400" y="405">reader ✗</text>
</svg>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment