diff --git a/docs/dv2-multi-branch/demo.cast.README.md b/docs/dv2-multi-branch/demo.cast.README.md index 7231116..65ab11c 100644 --- a/docs/dv2-multi-branch/demo.cast.README.md +++ b/docs/dv2-multi-branch/demo.cast.README.md @@ -1,5 +1,15 @@ # demo.cast — terminal recording of the live 2-minute pitch +> **⚠ Superseded (legend reset).** `demo.cast` and `demo_voiced.mp4` were +> captured 2026-05-23, before the kitchen-appliance-importer legend migration +> (2026-07-03) — the video/audio still shows the retired fashion-retailer +> framing and the old 40/25/15/10/10 branch split. The narration and transcript +> **text** were rewritten to the current legend in the G2 S5 follow-up PR +> (`demo_voiced.narration.txt`, `demo_transcript.txt`); the media itself is +> pending re-recording on the Mac kind stand (plan step S6). Until that +> re-recording happens, treat the `.cast`/`.mp4` files as stale and read the +> text scripts (or `demo_evidence.md`) for the current numbers. + `demo.cast` is an [asciinema](https://asciinema.org/) v2 recording of `bash demo_runner.sh` executed against the `hq-demo` cluster. Captured on 2026-05-23 at 130×35 with `xterm-256color`. Total runtime ~42 s @@ -69,12 +79,18 @@ the running cluster: | Beat | Command | Live output | |------|---------|-------------| | 1 | `kubectl get nodes --show-labels` | 3 nodes with `branch=msk` / `nodepool` / `workload` labels | -| 2 | CH: count tables in `rv` by prefix | bv=6, hub=8, lnk=8, sat=39 | -| 3 | CH: `record_source` distribution from `hub_order` | msk 40.5% / spb 24.1% / ekb 14.5% / dxb 11.2% / ala 9.7% | -| 4 | CH: BV MDM PII + loyalty per branch | msk 800/800/640, dxb 200/200/0 | +| 2 | CH: count tables in `rv` by prefix | bv=6, hub=8, lnk=8, sat=48 | +| 3 | CH: `record_source` distribution from `hub_order`, collapsed to branch | msk 95.4% / spb 1.8% / ekb 1.3% / dxb 0.8% / ala 0.8% | +| 4 | CH: BV MDM PII + loyalty per branch | msk 2190/2190/152, dxb 60/60/0 | | 5a | `kubectl create job --from=cronjob/dv2-cold-offload-msk` | job created, succeeds in ~8 s | | 5b | `mc ls -r local/cold-tier` | parquet files in MinIO for all 5 branches | +Beats 2–4 reflect the current kitchen-appliance-importer legend (matching +`demo_evidence.md` §4/§5/§8, re-captured 2026-07-03). Beats 1, 5a and 5b are +still the pre-migration `demo.cast` capture — legend-independent mechanism, +row counts/labels pending Mac re-recording (see the superseded notice above +and `demo_evidence.md` §1/§9). + The recording was made on the `hq-demo` cluster in the multi-branch state described by the DV2 docs in this directory. diff --git a/docs/dv2-multi-branch/demo.html b/docs/dv2-multi-branch/demo.html index 7c14fd2..47f5969 100644 --- a/docs/dv2-multi-branch/demo.html +++ b/docs/dv2-multi-branch/demo.html @@ -101,6 +101,16 @@

DV2.0 Multi-Branch — Live Demo

Self-hosted upstream Kubernetes, ClickHouse 25.5 + Postgres 17 + MinIO, Data Vault 2.0 schema with five-branch record_source dimension.

+

+ Superseded — pending re-recording. The embedded + demo.cast below was captured 2026-05-23, before the + kitchen-appliance-importer legend migration (2026-07-03), and the beat + table beneath it is written to the current legend's numbers, not the + figures the old recording actually shows. Media re-recording on the Mac + kind stand is tracked as plan step S6; until then, treat the playing + video as stale. See demo.cast.README.md and + demo_evidence.md. +

@@ -117,9 +127,9 @@

DV2.0 Multi-Branch — Live Demo

Time
Beat
Output
00:00
Cluster topology — kubectl get nodes
3 nodes, labelled branch / nodepool / workload
-
00:08
Model surface — table kinds in rv
bv 6, hub 8, lnk 8, sat 39
-
00:14
Multi-branch distribution from hub_order
msk 40.5 / spb 24.1 / ekb 14.5 / dxb 11.2 / ala 9.7 %
-
00:22
Business Vault MDM — PII + loyalty
msk 800/800/640, dxb 200/200/0
+
00:08
Model surface — table kinds in rv
bv 6, hub 8, lnk 8, sat 48
+
00:14
Multi-branch distribution from hub_order
msk 95.4 / spb 1.8 / ekb 1.3 / dxb 0.8 / ala 0.8 %
+
00:22
Business Vault MDM — PII + loyalty
msk 2190/2190/152, dxb 60/60/0
00:30
Cold-offload kubectl create job + MinIO listing
parquet files for all 5 branches in local/cold-tier
00:40
Closing — single bootstrap reproduces everything
bash infrastructure/dv2/bootstrap.sh
diff --git a/docs/dv2-multi-branch/demo_evidence.md b/docs/dv2-multi-branch/demo_evidence.md index 1294e87..d9819cb 100644 --- a/docs/dv2-multi-branch/demo_evidence.md +++ b/docs/dv2-multi-branch/demo_evidence.md @@ -23,6 +23,14 @@ Docker: > seed is now **2,500 customers / 10,000 orders / 160 SKU / 14,853 line > items, priced in ₽** — see `docs/domain.md` and `docs/generator-spec.md` > for the model. +> +> **⚠ `demo_voiced.mp4` / `demo.cast` are superseded.** Both were captured +> 2026-05-23, before this legend reset, and still show the retired +> fashion-retailer narration and the old 40/25/15/10/10 branch split. +> `demo_voiced.narration.txt` and `demo_transcript.txt` (the scripts behind +> them) were rewritten to the current legend in the G2 S5 follow-up PR; the +> `.mp4`/`.cast` media itself is pending re-recording on the Mac kind stand +> (plan step S6) — see `demo.cast.README.md` for detail. > **⚠ Infra sections (§1–3, §9–15) are pending re-capture on the kind > cluster (Mac stand).** Topology, workload pinning, PVCs, the MinIO cold diff --git a/docs/dv2-multi-branch/demo_transcript.txt b/docs/dv2-multi-branch/demo_transcript.txt index 0e7f4cd..8911b00 100644 --- a/docs/dv2-multi-branch/demo_transcript.txt +++ b/docs/dv2-multi-branch/demo_transcript.txt @@ -1,48 +1,48 @@ - -# === Beat 1 — Cluster topology (00:25) === -$ kubectl get nodes --show-labels | head -5 -NAME STATUS ROLES AGE VERSION LABELS -hq-demo-control-plane Ready control-plane 6h18m v1.35.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,branch=msk,kubernetes.io/arch=amd64,kubernetes.io/hostname=hq-demo-control-plane,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node.kubernetes.io/exclude-from-external-load-balancers=,nodepool=hq-control -hq-demo-worker Ready 6h18m v1.35.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,branch=msk,kubernetes.io/arch=amd64,kubernetes.io/hostname=hq-demo-worker,kubernetes.io/os=linux,nodepool=hq-data-tier-a,workload=postgres -hq-demo-worker2 Ready 6h18m v1.35.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,branch=msk,kubernetes.io/arch=amd64,kubernetes.io/hostname=hq-demo-worker2,kubernetes.io/os=linux,nodepool=hq-data-tier-b,workload=clickhouse - -# === Beat 2 — DV2.0 model surface (00:45) === -$ kubectl exec -n dv2 clickhouse-0 -- clickhouse-client --user default --password demo --query "SELECT splitByString('_', name)[1] AS kind, count() FROM system.tables WHERE database='rv' GROUP BY kind ORDER BY kind" -bv 6 -hub 8 -lnk 8 -sat 39 - -# === Beat 3 — Multi-branch distribution (01:05) === -$ kubectl exec -n dv2 clickhouse-0 -- clickhouse-client --user default --password demo --query "SELECT splitByString('__', record_source)[2] AS branch, count() AS orders, round(count()*100.0/(SELECT count() FROM rv.hub_order),1) AS pct FROM rv.hub_order GROUP BY branch ORDER BY pct DESC FORMAT PrettyCompact" - ┌─branch─┬─orders─┬──pct─┐ -1. │ msk │ 4200 │ 40.5 │ -2. │ spb │ 2500 │ 24.1 │ -3. │ ekb │ 1500 │ 14.5 │ -4. │ dxb │ 1160 │ 11.2 │ -5. │ ala │ 1000 │ 9.7 │ - └────────┴────────┴──────┘ - -# === Beat 4 — Business Vault MDM (01:25) === -$ kubectl exec -n dv2 clickhouse-0 -- clickhouse-client --user default --password demo --multiline --query "SELECT 'msk' AS branch, count() AS rows, countIf(first_name != '') AS with_pii, countIf(loyalty_segment != '') AS with_loyalty FROM rv.bv_customer_mdm__msk UNION ALL SELECT 'dxb', count(), countIf(first_name != ''), countIf(loyalty_segment IS NOT NULL AND loyalty_segment != '') FROM rv.bv_customer_mdm__dxb FORMAT PrettyCompact" - ┌─branch─┬─rows─┬─with_pii─┬─with_loyalty─┐ -1. │ dxb │ 200 │ 200 │ 0 │ -2. │ msk │ 800 │ 800 │ 640 │ - └────────┴──────┴──────────┴──────────────┘ - -# === Beat 5a — Cold offload (01:50) === -$ kubectl create job --from=cronjob/dv2-cold-offload-msk cold-demo-3455 -n dv2 -job.batch/cold-demo-3455 created - -# === Beat 5b — MinIO parquet listing === -$ kubectl exec -n dv2 minio-0 -- mc ls -r local/cold-tier | tail -5 -[2026-05-23 09:44:37 UTC] 6.7KiB STANDARD branch=ala/year=2026/month=05/customers_anon.parquet -[2026-05-23 09:44:32 UTC] 6.7KiB STANDARD branch=dxb/year=2026/month=05/customers_anon.parquet -[2026-05-23 09:44:37 UTC] 8.6KiB STANDARD branch=ekb/year=2026/month=05/customers_anon.parquet -[2026-05-23 10:20:13 UTC] 20KiB STANDARD branch=msk/year=2026/month=05/customers_anon.parquet -[2026-05-23 09:44:32 UTC] 13KiB STANDARD branch=spb/year=2026/month=05/customers_anon.parquet - -# === Closing (02:00) — Single bootstrap reproduces everything === -$ bash infrastructure/dv2/bootstrap.sh - -Demo complete. See docs/dv2-multi-branch/demo_evidence.md for the full breakdown. + +# === Beat 1 — Cluster topology (00:25) === +$ kubectl get nodes --show-labels | head -5 +NAME STATUS ROLES AGE VERSION LABELS +hq-demo-control-plane Ready control-plane 6h18m v1.35.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,branch=msk,kubernetes.io/arch=amd64,kubernetes.io/hostname=hq-demo-control-plane,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node.kubernetes.io/exclude-from-external-load-balancers=,nodepool=hq-control +hq-demo-worker Ready 6h18m v1.35.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,branch=msk,kubernetes.io/arch=amd64,kubernetes.io/hostname=hq-demo-worker,kubernetes.io/os=linux,nodepool=hq-data-tier-a,workload=postgres +hq-demo-worker2 Ready 6h18m v1.35.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,branch=msk,kubernetes.io/arch=amd64,kubernetes.io/hostname=hq-demo-worker2,kubernetes.io/os=linux,nodepool=hq-data-tier-b,workload=clickhouse + +# === Beat 2 — DV2.0 model surface (00:45) === +$ kubectl exec -n dv2 clickhouse-0 -- clickhouse-client --user default --password demo --query "SELECT splitByString('_', name)[1] AS kind, count() FROM system.tables WHERE database='rv' GROUP BY kind ORDER BY kind" +bv 6 +hub 8 +lnk 8 +sat 48 + +# === Beat 3 — Multi-branch distribution (01:05) === +$ kubectl exec -n dv2 clickhouse-0 -- clickhouse-client --user default --password demo --query "SELECT splitByString('__', record_source)[2] AS branch, count() AS orders, round(count()*100.0/(SELECT count() FROM rv.hub_order),1) AS pct FROM rv.hub_order GROUP BY branch ORDER BY pct DESC FORMAT PrettyCompact" + ┌─branch─┬─orders─┬──pct─┐ +1. │ msk │ 9540 │ 95.4 │ +2. │ spb │ 180 │ 1.8 │ +3. │ ekb │ 130 │ 1.3 │ +4. │ dxb │ 75 │ 0.8 │ +5. │ ala │ 75 │ 0.8 │ + └────────┴────────┴──────┘ + +# === Beat 4 — Business Vault MDM (01:25) === +$ kubectl exec -n dv2 clickhouse-0 -- clickhouse-client --user default --password demo --multiline --query "SELECT 'msk' AS branch, count() AS rows, countIf(first_name != '') AS with_pii, countIf(loyalty_segment != '') AS with_loyalty FROM rv.bv_customer_mdm__msk UNION ALL SELECT 'dxb', count(), countIf(first_name != ''), countIf(loyalty_segment IS NOT NULL AND loyalty_segment != '') FROM rv.bv_customer_mdm__dxb FORMAT PrettyCompact" + ┌─branch─┬─rows─┬─with_pii─┬─with_loyalty─┐ +1. │ dxb │ 60 │ 60 │ 0 │ +2. │ msk │ 2190 │ 2190 │ 152 │ + └────────┴──────┴──────────┴──────────────┘ + +# === Beat 5a — Cold offload (01:50) === +$ kubectl create job --from=cronjob/dv2-cold-offload-msk cold-demo-3455 -n dv2 +job.batch/cold-demo-3455 created + +# === Beat 5b — MinIO parquet listing === +$ kubectl exec -n dv2 minio-0 -- mc ls -r local/cold-tier | tail -5 +[2026-05-23 09:44:37 UTC] 6.7KiB STANDARD branch=ala/year=2026/month=05/customers_anon.parquet +[2026-05-23 09:44:32 UTC] 6.7KiB STANDARD branch=dxb/year=2026/month=05/customers_anon.parquet +[2026-05-23 09:44:37 UTC] 8.6KiB STANDARD branch=ekb/year=2026/month=05/customers_anon.parquet +[2026-05-23 10:20:13 UTC] 20KiB STANDARD branch=msk/year=2026/month=05/customers_anon.parquet +[2026-05-23 09:44:32 UTC] 13KiB STANDARD branch=spb/year=2026/month=05/customers_anon.parquet + +# === Closing (02:00) — Single bootstrap reproduces everything === +$ bash infrastructure/dv2/bootstrap.sh + +Demo complete. See docs/dv2-multi-branch/demo_evidence.md for the full breakdown. diff --git a/docs/dv2-multi-branch/demo_voiced.narration.txt b/docs/dv2-multi-branch/demo_voiced.narration.txt index 8e0b7ad..a79415a 100644 --- a/docs/dv2-multi-branch/demo_voiced.narration.txt +++ b/docs/dv2-multi-branch/demo_voiced.narration.txt @@ -1,12 +1,12 @@ -Mid-market fashion ритейлер. 50 человек, пять локаций — Москва, Питер, Екатеринбург, Дубай, Алматы. 18 процентов возвратов съедают маржу, реконсиляция шла 72 часа. Мы построили DV2.0 хранилище, и цикл сжался до четырёх часов. Покажу. +Импортёр мелкой кухонной техники под собственным брендом. Пять локаций — Москва, Питер, Екатеринбург, Дубай, Алматы. Три боли: кросс-канальный оверселл — один склад на все каналы, и партия дилеру должна попасть в остаток раньше, чем маркетплейсы допродадут те же единицы; контейнеры из Китая идут 40-60 дней, и застрявший на таможне груз — риск топ-3; операционка жонглирует пятью программами — 1С, Битрикс24, экран WMS, кабинеты маркетплейсов, Excel — ради ответа об одном заказе. Мы построили DV2.0 хранилище и операционный слой поверх: один ответ вместо пяти вкладок. Покажу. Кластер. Три ноды Kubernetes, лейблы branch равно msk, dxb, ala. По ним nodeSelector закрепляет Postgres и ClickHouse — data sovereignty на уровне планировщика. -Модель. Шестьдесят таблиц: восемь хабов, восемь линков, под сорок сателлитов, BV вьюхи поверх. Сателлиты разрезаны по record_source равно система плюс филиал. Один customer_hk из 1С и из Битрикса — конфликт решается приоритетом, аудит сохраняется. +Модель. Семьдесят таблиц: восемь хабов, восемь линков, сорок восемь сателлитов, шесть BV вьюх поверх. Сателлиты разрезаны по record_source равно система плюс филиал. Один customer_hk из 1С и из Битрикса — конфликт решается приоритетом, аудит сохраняется. -Multi-branch. Распределение 40, 25, 15, 10, 10 — consistent hashing на store_id. Три миллисекунды на 10 тысяч строк. Production-движок даёт тот же план. +Multi-branch. Заказы концентрируются в MSK — девяносто пять процентов, весь e-com отгружается только оттуда; остальное — дилерский B2B по SPB, EKB, DXB и ALA. Пятнадцать миллисекунд на 10 тысяч строк. Production-движок даёт тот же план. -Business Vault. PII из 1С, loyalty из Битрикса, argMax по load_ts, source колонки для аудита. Дубайский view — отдельные сателлиты, PII никогда не пересекается с МСК. +Business Vault. PII из 1С, дилерские бонусы из Битрикса, argMax по load_ts, source колонки для аудита. Дубайский view — отдельные сателлиты, PII никогда не пересекается с МСК. Холодный слой. CronJob раз в сутки выгружает только anon-сателлиты в S3, без PII. В проде — B2 или Hugging Face Datasets. 152 ФЗ и закон Казахстана соблюдены.