Skip to content

Commit 7a8f7ca

Browse files
committed
feat: rewrite engineering blog posts around the actual design story, add diagrams
Reframes all 4 posts around the novel decision and how it arose instead of describing full system state: cuts the CRDT post's from-scratch tutorial in favor of the wall-clock bug that motivated the stamp, moves the how-feedback post's job-ID incident to the top as the hook, and drops forward-looking "planned for later" framing from the architecture and CRDT posts per review feedback. Adds one inline-SVG diagram per post showing the actual mechanism (write path, stamp comparison, feedback loop, two doors), reused as a compact card thumbnail on the listing page via a new `heroDiagram` frontmatter field and a shared diagram registry. Fixes the engineering-blog index, which had leaked the internal primer's "Understand this system" title instead of its own. - Fixes #15640
1 parent 4b06605 commit 7a8f7ca

15 files changed

Lines changed: 1071 additions & 166 deletions

apps/website/src/components/engineering-blog/PostBody.astro

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { render } from 'astro:content'
33
44
import type { EngineeringBlogPostEntry } from '../../utils/engineeringBlog'
55
import Callout from './content/Callout.astro'
6+
import { diagramRegistry } from './diagrams/registry'
67
import Code from './content/Code.astro'
78
import Divider from './content/Divider.astro'
89
import Heading2 from './content/Heading2.astro'
@@ -41,7 +42,11 @@ const contentComponents = {
4142
thead: TableHead,
4243
tr: TableRow,
4344
th: TableHeaderCell,
44-
td: TableCell
45+
td: TableCell,
46+
ArchitectureDiagram: diagramRegistry.architecture,
47+
StampDiagram: diagramRegistry.stamp,
48+
FeedbackLoopDiagram: diagramRegistry['feedback-loop'],
49+
TwoDoorsDiagram: diagramRegistry['two-doors']
4550
}
4651
---
4752

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
---
2+
import DiagramFrame from './DiagramFrame.astro'
3+
4+
interface Props {
5+
variant?: 'full' | 'card'
6+
}
7+
8+
const { variant = 'full' } = Astro.props
9+
const label =
10+
'Diagram: an edit flows from the browser or agent through ingest to the single-writer agent service, which asks the doc host to merge it over a loopback call, then writes the result to the database as truth while a fast fan-out layer broadcasts it for speed, and connected browsers pick up the change either way.'
11+
---
12+
13+
{
14+
variant === 'card' ? (
15+
<DiagramFrame viewBox="0 0 320 200" label={label} variant="card">
16+
<defs>
17+
<marker
18+
id="arrow-architecture-card"
19+
viewBox="0 0 10 10"
20+
refX="8"
21+
refY="5"
22+
markerWidth="6"
23+
markerHeight="6"
24+
orient="auto-start-reverse"
25+
>
26+
<path d="M0,0 L10,5 L0,10 z" class="eb-diagram-arrowhead" />
27+
</marker>
28+
</defs>
29+
<rect x="12" y="72" width="90" height="56" rx="10" class="eb-diagram-box" />
30+
<text x="57" y="105" text-anchor="middle" class="eb-diagram-label">
31+
Browser
32+
</text>
33+
<line
34+
x1="106"
35+
y1="100"
36+
x2="150"
37+
y2="100"
38+
class="eb-diagram-arrow"
39+
marker-end="url(#arrow-architecture-card)"
40+
/>
41+
<rect
42+
x="154"
43+
y="60"
44+
width="110"
45+
height="80"
46+
rx="10"
47+
class="eb-diagram-box-accent"
48+
/>
49+
<text x="209" y="97" text-anchor="middle" class="eb-diagram-label-accent">
50+
Agent
51+
</text>
52+
<text x="209" y="117" text-anchor="middle" class="eb-diagram-label-accent">
53+
Service
54+
</text>
55+
<line
56+
x1="264"
57+
y1="85"
58+
x2="300"
59+
y2="55"
60+
class="eb-diagram-arrow"
61+
marker-end="url(#arrow-architecture-card)"
62+
/>
63+
<line
64+
x1="264"
65+
y1="115"
66+
x2="300"
67+
y2="145"
68+
class="eb-diagram-arrow"
69+
marker-end="url(#arrow-architecture-card)"
70+
/>
71+
<text x="303" y="45" text-anchor="end" class="eb-diagram-sublabel">
72+
truth
73+
</text>
74+
<text x="303" y="162" text-anchor="end" class="eb-diagram-sublabel">
75+
speed
76+
</text>
77+
</DiagramFrame>
78+
) : (
79+
<DiagramFrame viewBox="0 0 640 600" label={label}>
80+
<defs>
81+
<marker
82+
id="arrow-architecture"
83+
viewBox="0 0 10 10"
84+
refX="8"
85+
refY="5"
86+
markerWidth="7"
87+
markerHeight="7"
88+
orient="auto-start-reverse"
89+
>
90+
<path d="M0,0 L10,5 L0,10 z" class="eb-diagram-arrowhead" />
91+
</marker>
92+
<marker
93+
id="arrow-architecture-accent"
94+
viewBox="0 0 10 10"
95+
refX="8"
96+
refY="5"
97+
markerWidth="7"
98+
markerHeight="7"
99+
orient="auto-start-reverse"
100+
>
101+
<path d="M0,0 L10,5 L0,10 z" class="eb-diagram-arrowhead-accent" />
102+
</marker>
103+
</defs>
104+
105+
<rect x="200" y="20" width="240" height="60" rx="12" class="eb-diagram-box" />
106+
<text x="320" y="55" text-anchor="middle" class="eb-diagram-label">
107+
Human or agent edit
108+
</text>
109+
110+
<line
111+
x1="320"
112+
y1="80"
113+
x2="320"
114+
y2="112"
115+
class="eb-diagram-arrow"
116+
marker-end="url(#arrow-architecture)"
117+
/>
118+
119+
<rect x="200" y="112" width="240" height="60" rx="12" class="eb-diagram-box" />
120+
<text x="320" y="138" text-anchor="middle" class="eb-diagram-label">
121+
Ingest
122+
</text>
123+
<text x="320" y="158" text-anchor="middle" class="eb-diagram-sublabel">
124+
relay only — byte for byte
125+
</text>
126+
127+
<line
128+
x1="320"
129+
y1="172"
130+
x2="320"
131+
y2="204"
132+
class="eb-diagram-arrow"
133+
marker-end="url(#arrow-architecture)"
134+
/>
135+
136+
<rect
137+
x="180"
138+
y="204"
139+
width="280"
140+
height="70"
141+
rx="12"
142+
class="eb-diagram-box-accent"
143+
/>
144+
<text x="320" y="235" text-anchor="middle" class="eb-diagram-label-accent">
145+
Agent Service
146+
</text>
147+
<text x="320" y="256" text-anchor="middle" class="eb-diagram-sublabel">
148+
the single writer
149+
</text>
150+
151+
<line
152+
x1="460"
153+
y1="239"
154+
x2="520"
155+
y2="239"
156+
class="eb-diagram-arrow"
157+
marker-end="url(#arrow-architecture)"
158+
/>
159+
<line
160+
x1="520"
161+
y1="255"
162+
x2="460"
163+
y2="255"
164+
class="eb-diagram-arrow"
165+
marker-end="url(#arrow-architecture)"
166+
/>
167+
<text x="490" y="222" text-anchor="middle" class="eb-diagram-caption">
168+
loopback
169+
</text>
170+
171+
<rect x="520" y="209" width="120" height="60" rx="12" class="eb-diagram-box" />
172+
<text x="580" y="235" text-anchor="middle" class="eb-diagram-label">
173+
Doc host
174+
</text>
175+
<text x="580" y="253" text-anchor="middle" class="eb-diagram-sublabel">
176+
stateless merge
177+
</text>
178+
179+
<line
180+
x1="320"
181+
y1="274"
182+
x2="320"
183+
y2="300"
184+
class="eb-diagram-arrow"
185+
/>
186+
<line
187+
x1="320"
188+
y1="300"
189+
x2="200"
190+
y2="332"
191+
class="eb-diagram-arrow"
192+
marker-end="url(#arrow-architecture)"
193+
/>
194+
<line
195+
x1="320"
196+
y1="300"
197+
x2="440"
198+
y2="332"
199+
class="eb-diagram-arrow"
200+
marker-end="url(#arrow-architecture)"
201+
/>
202+
203+
<rect x="90" y="332" width="220" height="70" rx="12" class="eb-diagram-box" />
204+
<text x="200" y="363" text-anchor="middle" class="eb-diagram-label">
205+
Database
206+
</text>
207+
<text x="200" y="383" text-anchor="middle" class="eb-diagram-sublabel">
208+
truth — atomic write
209+
</text>
210+
211+
<rect x="330" y="332" width="220" height="70" rx="12" class="eb-diagram-box" />
212+
<text x="440" y="363" text-anchor="middle" class="eb-diagram-label">
213+
Fast fan-out
214+
</text>
215+
<text x="440" y="383" text-anchor="middle" class="eb-diagram-sublabel">
216+
speed — fire and forget
217+
</text>
218+
219+
<path
220+
d="M 200 402 C 130 460, 150 500, 220 508"
221+
class="eb-diagram-arrow-dashed"
222+
marker-end="url(#arrow-architecture)"
223+
/>
224+
<text x="130" y="465" text-anchor="middle" class="eb-diagram-caption">
225+
resync on
226+
</text>
227+
<text x="130" y="480" text-anchor="middle" class="eb-diagram-caption">
228+
reconnect
229+
</text>
230+
231+
<path
232+
d="M 440 402 C 510 460, 480 500, 420 508"
233+
class="eb-diagram-arrow-dashed"
234+
marker-end="url(#arrow-architecture)"
235+
/>
236+
<text x="512" y="465" text-anchor="middle" class="eb-diagram-caption">
237+
broadcast,
238+
</text>
239+
<text x="512" y="480" text-anchor="middle" class="eb-diagram-caption">
240+
milliseconds
241+
</text>
242+
243+
<rect x="200" y="510" width="240" height="60" rx="12" class="eb-diagram-box" />
244+
<text x="320" y="536" text-anchor="middle" class="eb-diagram-label">
245+
Connected browsers
246+
</text>
247+
<text x="320" y="554" text-anchor="middle" class="eb-diagram-sublabel">
248+
see the change either way
249+
</text>
250+
</DiagramFrame>
251+
)
252+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
---
2+
interface Props {
3+
viewBox: string
4+
label: string
5+
variant?: 'full' | 'card'
6+
}
7+
8+
const { viewBox, label, variant = 'full' } = Astro.props
9+
---
10+
11+
<figure class={variant === 'card' ? 'h-full w-full' : 'my-8'}>
12+
<svg
13+
viewBox={viewBox}
14+
role="img"
15+
aria-label={label}
16+
class="h-auto w-full"
17+
xmlns="http://www.w3.org/2000/svg"
18+
>
19+
<slot />
20+
</svg>
21+
</figure>
22+
23+
<style is:global>
24+
/*
25+
* Shared visual language for the engineering-blog diagrams. Global so it
26+
* reaches the SVG markup slotted in from each diagram component (Astro's
27+
* scoped styles don't cross that boundary) — see
28+
* src/components/engineering-blog/diagrams/*.astro.
29+
*/
30+
.eb-diagram-box {
31+
fill: var(--color-site-bg-soft);
32+
stroke: var(--color-transparency-white-t20);
33+
stroke-width: 1.5;
34+
}
35+
.eb-diagram-box-accent {
36+
fill: var(--color-site-bg-soft);
37+
stroke: var(--color-primary-comfy-yellow);
38+
stroke-width: 2;
39+
}
40+
.eb-diagram-box-solid {
41+
fill: var(--color-transparency-white-t8);
42+
stroke: var(--color-transparency-white-t20);
43+
stroke-width: 1.5;
44+
}
45+
.eb-diagram-label {
46+
fill: var(--color-primary-warm-white);
47+
font: 600 15px Inter, sans-serif;
48+
}
49+
.eb-diagram-label-accent {
50+
fill: var(--color-primary-comfy-yellow);
51+
font: 600 15px Inter, sans-serif;
52+
}
53+
.eb-diagram-sublabel {
54+
fill: var(--color-primary-comfy-canvas);
55+
font: 400 12px Inter, sans-serif;
56+
}
57+
.eb-diagram-caption {
58+
fill: var(--color-primary-comfy-canvas);
59+
font: 400 12px Inter, sans-serif;
60+
}
61+
.eb-diagram-mono {
62+
fill: var(--color-primary-comfy-canvas);
63+
font: 400 12px ui-monospace, monospace;
64+
}
65+
.eb-diagram-mono-accent {
66+
fill: var(--color-primary-comfy-yellow);
67+
font: 600 12px ui-monospace, monospace;
68+
}
69+
.eb-diagram-arrow {
70+
stroke: var(--color-transparency-white-t20);
71+
stroke-width: 1.75;
72+
fill: none;
73+
}
74+
.eb-diagram-arrow-accent {
75+
stroke: var(--color-primary-comfy-yellow);
76+
stroke-width: 1.75;
77+
fill: none;
78+
}
79+
.eb-diagram-arrow-dashed {
80+
stroke: var(--color-transparency-white-t20);
81+
stroke-width: 1.5;
82+
fill: none;
83+
stroke-dasharray: 5 5;
84+
}
85+
.eb-diagram-arrowhead {
86+
fill: var(--color-transparency-white-t20);
87+
}
88+
.eb-diagram-arrowhead-accent {
89+
fill: var(--color-primary-comfy-yellow);
90+
}
91+
</style>

0 commit comments

Comments
 (0)