跳到正文
册页

图示

DataflowFigure - 数据流图

一条管线:数据从哪来、经过了什么、最后落到谁手里。

用法

什么时候用它

结构上跟架构图很像,读的却是另一个问题。classification 单独占一个标签,因为做治理审查的人找的正是那一项。

来自@misoto22/folio/diagrams

TSX
import { DataflowFigure } from '@misoto22/folio/diagrams'

说明

一条管线:数据从哪来、经过了什么、最后落到谁手里。

结构上跟架构图很像,读的却完全是另一个问题——所以它是一个独立的渲染器而不是一个预设。架构图读的是「谁跟谁说话」。数据流图读的是「这根箭头里装的是什么」——正是这个问题,让 classification 在标签下面单独拿到一枚等宽小标,而不是被揉进措辞里。clickstream / PII touch 和 clickstream 是两个不同的事实,而做治理审查的人找的是后面那个。

阶段印成顶部一条线上的列标题。它们是这张图的坐标轴:一个节点的 stage 就是它在管线上的位置,读者应该靠往上看、而不是靠追箭头,来回答「这走到哪一步了」。

结构

DataflowFigure anatomy
部件说明
图外框必填画面外面的那个框。一条管线交给它的是一份把 classification 并进去的流列表——「clickstream — PII touch」——于是这张图被打开时真正要找的那个事实,也能传达给从没看见那枚标签的读者。
阶段表头必填一个 stage 一行等宽小标题,落在顶部一条横线上。它就是那根轴:一个节点的 stage 就是它在管线上走到了多远,所以「这份数据聚合过了吗」是靠往上看回答的,不是靠顺着箭头追。
节点板块必填一个节点一个方框,横向按 stage 摆、纵向按 row 摆。行距在同一列的两个方框之间留出一条干净的带子,线和线上的文字就走在那里。
流一条布好线的连线,只有一个箭头,在它的 to 端。整张图被读,读的就是它给出的那个方向主张。
分级标签classification,用等宽字印在文字下方,而不是塞进文字里。「clickstream」和「clickstream / PII touch」是两个不同的事实,而治理审查冲着来的只是其中一个。

实践建议

推荐

  • 治理相关的事实要放进 classification,不要写在 label 里。它会在线上印成一枚自己的标签,也会被追加到这条流的摘要行上,所以扫图的读者和只拿得到文字的读者,两边它都活得下来。
  • stage 要留在你声明过的那些 stage 之内。节点的 x 是拿它自己的 stage 索引算出来的,不是查出来的,所以只有四个阶段时一个 stage 5 的节点,会被画到最后一个表头再往外整整一列,底下压根没有任何表头——开发环境会打印 DIAGRAM_STAGE_OUT_OF_RANGE,摘要则把它归进一条叫 outside the declared stages 的带子里,而不是摆在坐标轴真正标注了的那些节点旁边。
  • 双向的往来要写成两条流。每条线只在 to 端带箭头,所以一个服务和它的缓存之间只画一条流,说的就是数据只往一个方向走,不管标签上关于往返写了什么。

避免

  • via、channelX 和 channelY 在这里从来不作数——数据流的节点永远是按 stage 和 row 摆的,所以作者给的路点指的是一张这个渲染器并没有搭出来的网格。它们会被丢掉,每条线都从头重新布线:规格照样过类型检查,而画面不是它画的那一张。
  • 当心汇入。同一面上的线会沿着这一面均匀铺开,而一个箭头是 11 个用户单位宽,板块大约只有 55 个单位高——所以四条线进同一面,就是箭头开始相接的地方,第五条和第六条到达时会并成一道粗痕。到了这个密度的管线该拆,而不是再加边。

示例

default

两个来源汇入同一道闸口。每个标签底下那枚等宽字芯片是分级,之所以和文案分开印,是因为一条流水线被读的是箭头里面装着什么,而不是这条箭头叫什么——clickstream 和「无 PII」回答的是不同的问题,而其中只有一个是合规审查者此行带来的那个问题。阶段标题就是那根轴,所以「某样东西走到哪一步了」是靠往上看回答的,不是靠追踪。

Event pipeline

What is in the arrow matters more than the arrow.
Event pipeline4 elements and 3 relationships. What is in the arrow matters more than the arrow.eventsWeb SDKbrowsereventsMobileiOS / AndroidPII guardConsent gatepolicy filtercuratedWarehouseanalytics tables

4 elements and 3 relationships. What is in the arrow matters more than the arrow.

  • Stage: Sources
    • Web SDK (frontend) — browser
    • Mobile (frontend) — iOS / Android
  • Stage: Gate
    • Consent gate (security) — policy filter
  • Stage: Store
    • Warehouse (database) — analytics tables
  • Web SDK → Consent gate: clickstream — user events
  • Mobile → Consent gate: app events — device events
  • Consent gate → Warehouse: accepted — no PII
Key
  • CLIENT
  • POLICY
  • DATA

one source three consumers

一次扇出,以及分级之所以是一个字段、而不是标签里一个词的理由:一张表喂给三个消费方,而每条箭头离开时携带的东西都不一样。这里三条流共用一个面,所以路由器把它们的端口摊开在这个面上——若是全叠在这个面的中点上,三个箭头会被读成一个。广告合作方是唯一一个在账户之外的消费方,这也是为什么它那条流是被画成跨越边界的那一条。

What leaves the events table

One source, three consumers, three payloads.
What leaves the events table4 elements and 3 relationships. One source, three consumers, three payloads.PIIEvents tablerawCLOUDBI dashboardsinternalSERVICEModel trainingnightlyEXTERNALAd partnerthird party

4 elements and 3 relationships. One source, three consumers, three payloads.

  • Stage: Source
    • Events table (database) — raw
  • Stage: Consumers
    • BI dashboards (cloud) — internal
    • Model training (backend) — nightly
    • Ad partner (external) — third party
  • Events table → BI dashboards: daily rollup — aggregated
  • Events table → Model training: training set — hashed ids
  • Events table → Ad partner: conversions — no PII
Key
  • DATA
  • CLOUD
  • SERVICE
  • EXTERNAL
Leaving the estate
  • Only the ad partner sits outside the account.
  • That is the arrow a reviewer reads first.

a stage the data skips

一个阶段是关于「某样东西走到哪一步」的断言,而正是这根轴让这次绕行变得看得见:那份采样副本在阶段零离开 SDK,到达阶段二,中途没有经过脱敏器,仍然带着它的 PII 芯片。同样这三条流,写成一份成对的列表就会把这件事藏起来,因为一份列表没有轴可供跳过。被强调的那条线是这条流水线存在的目的;那条虚线是留了一份百分之一的采样,好让某个人能去调试一段载荷,而那恰恰是一次审计最后才发现的那类路径。

Clickstream

Three stages, and one copy that skips the middle one.
Clickstream4 elements and 3 relationships. Three stages, and one copy that skips the middle one.rawWeb SDKbrowserPOLICYRedactordrops identifierscuratedLakepartitionedDATADebug bucket7-day TTL

4 elements and 3 relationships. Three stages, and one copy that skips the middle one.

  • Stage: Collect
    • Web SDK (frontend) — browser
  • Stage: Scrub
    • Redactor (security) — drops identifiers
  • Stage: Serve
    • Lake (database) — partitioned
    • Debug bucket (database) — 7-day TTL
  • Web SDK → Redactor: events — PII
  • Redactor → Lake: hourly — no PII
  • Web SDK → Debug bucket: sampled 1% — PII
Key
  • CLIENT
  • POLICY
  • DATA

what is in the arrow

四个阶段,因为最小化本身就是一个阶段:审查者的问题是「还标着 PII 的东西有没有到达数仓」,而答案是一条你可以顺着走下去的线,不是一段你只能选择相信的话。每一个分级除了印在芯片上,也一并折进无障碍摘要里,所以一个看不见这幅画的读者拿到的是「卡号和邮箱 — PII」,而不是光秃秃的「卡号和邮箱」。哪怕文案和分级感觉像是一句话,也要把它们分开;两者一旦合并,芯片就不再是一个可供任何东西去核对的字段了。

Card data, minimised

Read for what crosses each stage, not for what talks to what.
Card data, minimised5 elements and 4 relationships. Read for what crosses each stage, not for what talks to what.rawCheckout formbrowserrawSupport inboxticket bodiesPOLICYTokeniserVault transitDATAWarehouseorder tablesSERVICEDashboardsfinance team

5 elements and 4 relationships. Read for what crosses each stage, not for what talks to what.

  • Stage: Collected
    • Checkout form (frontend) — browser
    • Support inbox (frontend) — ticket bodies
  • Stage: Minimised
    • Tokeniser (security) — Vault transit
  • Stage: Stored
    • Warehouse (database) — order tables
  • Stage: Served
    • Dashboards (backend) — finance team
  • Checkout form → Tokeniser: card and email — PII
  • Support inbox → Tokeniser: free text — PII, unstructured
  • Tokeniser → Warehouse: order rows — tokenised, no PAN
  • Warehouse → Dashboards: daily rollup — aggregated
Key
  • CLIENT
  • POLICY
  • DATA
  • SERVICE

无障碍

  • 一条流的 classification 会并进它的摘要行,所以「clickstream — PII touch」能传达给看不到那枚标签的人。