<mxfile host="app.diagrams.net" modified="2026-06-30T00:00:00.000Z" agent="Codex" version="24.7.17" type="device">
  <diagram id="langfuse-current-architecture" name="Langfuse 当前架构">
    <mxGraphModel dx="1800" dy="1200" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1700" pageHeight="1200" math="0" shadow="0">
      <root>
        <mxCell id="0" />
        <mxCell id="1" parent="0" />

        <mxCell id="title" value="Langfuse 当前仓库架构：分层契约与运行链路" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=22;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="190" y="20" width="1320" height="40" as="geometry" />
        </mxCell>

        <mxCell id="lane-external" value="1. 外部入口" style="swimlane;html=1;horizontal=0;startSize=34;fillColor=#f8fafc;strokeColor=#cbd5e1;fontStyle=1;fontSize=14;rounded=1;whiteSpace=wrap" vertex="1" parent="1">
          <mxGeometry x="40" y="80" width="1620" height="130" as="geometry" />
        </mxCell>
        <mxCell id="lane-web" value="2. web/ - 同步产品界面与 API 入口" style="swimlane;html=1;horizontal=0;startSize=34;fillColor=#eef2ff;strokeColor=#818cf8;fontStyle=1;fontSize=14;rounded=1;whiteSpace=wrap" vertex="1" parent="1">
          <mxGeometry x="40" y="230" width="1620" height="220" as="geometry" />
        </mxCell>
        <mxCell id="lane-shared" value="3. packages/shared - 契约、领域模型、服务、仓储" style="swimlane;html=1;horizontal=0;startSize=34;fillColor=#fffbeb;strokeColor=#f59e0b;fontStyle=1;fontSize=14;rounded=1;whiteSpace=wrap" vertex="1" parent="1">
          <mxGeometry x="40" y="470" width="1620" height="250" as="geometry" />
        </mxCell>
        <mxCell id="lane-worker" value="4. worker/ - 异步执行与后台处理" style="swimlane;html=1;horizontal=0;startSize=34;fillColor=#ecfdf5;strokeColor=#10b981;fontStyle=1;fontSize=14;rounded=1;whiteSpace=wrap" vertex="1" parent="1">
          <mxGeometry x="40" y="740" width="1620" height="190" as="geometry" />
        </mxCell>
        <mxCell id="lane-data" value="5. 数据与基础设施" style="swimlane;html=1;horizontal=0;startSize=34;fillColor=#fef2f2;strokeColor=#ef4444;fontStyle=1;fontSize=14;rounded=1;whiteSpace=wrap" vertex="1" parent="1">
          <mxGeometry x="40" y="950" width="1620" height="190" as="geometry" />
        </mxCell>

        <mxCell id="browser" value="浏览器 UI&#xa;React / Next.js 页面&#xa;表格、筛选、仪表盘" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#64748b;fontSize=12" vertex="1" parent="1">
          <mxGeometry x="95" y="115" width="190" height="70" as="geometry" />
        </mxCell>
        <mxCell id="sdk" value="SDK / 公共 API 客户端&#xa;REST 摄取、追踪、评分、数据集" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#64748b;fontSize=12" vertex="1" parent="1">
          <mxGeometry x="335" y="115" width="215" height="70" as="geometry" />
        </mxCell>
        <mxCell id="otel" value="OTel SDK / 收集器&#xa;原生遥测 span" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#64748b;fontSize=12" vertex="1" parent="1">
          <mxGeometry x="600" y="115" width="185" height="70" as="geometry" />
        </mxCell>
        <mxCell id="admins" value="内部 / 管理触发器&#xa;计费、迁移、定时任务" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#64748b;fontSize=12" vertex="1" parent="1">
          <mxGeometry x="835" y="115" width="220" height="70" as="geometry" />
        </mxCell>
        <mxCell id="external-services" value="外部集成入口&#xa;LLM API、webhook、Slack、CRM" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#64748b;fontSize=12" vertex="1" parent="1">
          <mxGeometry x="1105" y="115" width="230" height="70" as="geometry" />
        </mxCell>

        <mxCell id="next-ui" value="Next.js App + Pages UI&#xa;AppLayout、表格、详情页、设置" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#4f46e5;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="95" y="275" width="220" height="75" as="geometry" />
        </mxCell>
        <mxCell id="trpc" value="tRPC 根路由&#xa;protectedProjectProcedure&#xa;会话、RBAC、组织/项目上下文" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#4f46e5;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="365" y="260" width="230" height="95" as="geometry" />
        </mxCell>
        <mxCell id="public-api" value="公共 REST API&#xa;withMiddlewares + createAuthedProjectAPIRoute&#xa;Zod 请求/响应 + 限流" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#4f46e5;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="645" y="260" width="260" height="95" as="geometry" />
        </mxCell>
        <mxCell id="ingestion-api" value="/api/public/ingestion&#xa;批量校验、鉴权、限流&#xa;委托给 processEventBatch" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#4f46e5;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="955" y="260" width="240" height="95" as="geometry" />
        </mxCell>
        <mxCell id="web-contract-note" value="Web 层原则：入口层保持轻薄，只做鉴权、校验、遥测上下文设置，然后调用 shared 服务/仓储或投递队列。" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e0e7ff;strokeColor=#818cf8;fontSize=12" vertex="1" parent="1">
          <mxGeometry x="1245" y="265" width="330" height="85" as="geometry" />
        </mxCell>

        <mxCell id="domain-contracts" value="领域契约&#xa;TraceDomain、ObservationSchema、ScoreSchema&#xa;Zod 运行时类型 + TS 推导" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#d97706;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="95" y="515" width="235" height="85" as="geometry" />
        </mxCell>
        <mxCell id="filter-contracts" value="筛选与表格契约&#xa;FilterState / singleFilter&#xa;ColumnDefinition、搜索栏语法" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#d97706;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="365" y="515" width="245" height="85" as="geometry" />
        </mxCell>
        <mxCell id="query-contracts" value="查询契约&#xa;EventsQueryBuilder、FIELD_SETS&#xa;FilterState lowering、tenant filter、表选择" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#d97706;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="645" y="515" width="245" height="85" as="geometry" />
        </mxCell>
        <mxCell id="queue-contracts" value="队列契约&#xa;QueueName、QueueJobs、TQueueJobTypes&#xa;Zod 载荷 schema" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#d97706;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="925" y="515" width="245" height="85" as="geometry" />
        </mxCell>
        <mxCell id="repos-services" value="服务与仓储&#xa;Prisma CRUD、ClickHouse 仓储&#xa;events 查询构建、鉴权、存储、LLM" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#d97706;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="1205" y="500" width="300" height="100" as="geometry" />
        </mxCell>
        <mxCell id="v4-contracts" value="v4 events 抽象&#xa;events_core = 列表/筛选/聚合的轻量投影&#xa;events_full = 完整 I/O 与 metadata" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fef3c7;strokeColor=#d97706;fontSize=12" vertex="1" parent="1">
          <mxGeometry x="365" y="625" width="525" height="70" as="geometry" />
        </mxCell>
        <mxCell id="shared-principle" value="Shared 层原则：公共行为通过 schema、列映射、队列载荷类型和查询构建器表达。web 与 worker 消费这些契约，而不是复制规则。" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fef3c7;strokeColor=#d97706;fontSize=12" vertex="1" parent="1">
          <mxGeometry x="925" y="625" width="580" height="70" as="geometry" />
        </mxCell>

        <mxCell id="worker-manager" value="WorkerManager&#xa;注册 BullMQ worker&#xa;指标、重试、停滞/错误 hook" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#059669;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="95" y="785" width="230" height="85" as="geometry" />
        </mxCell>
        <mxCell id="ingestion-worker" value="摄取处理器&#xa;读取 S3 事件正文&#xa;合并 legacy 记录或创建 v4 EventRecord" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#059669;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="365" y="785" width="260" height="85" as="geometry" />
        </mxCell>
        <mxCell id="eval-worker" value="Eval / 批处理 / 导出 / 删除 worker&#xa;trace upsert、eval 执行、批量动作、数据保留" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#059669;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="665" y="785" width="285" height="85" as="geometry" />
        </mxCell>
        <mxCell id="clickhouse-writer" value="ClickhouseWriter 单例&#xa;按表维护内存队列&#xa;批量刷写、重试、截断、Decimal 保护" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#059669;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="990" y="785" width="270" height="85" as="geometry" />
        </mxCell>
        <mxCell id="worker-principle" value="Worker 层原则：耗时且可重试的工作离开请求链路。队列载荷在 shared 中定义类型，处理器复用与 web 相同的服务/仓储。" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d1fae5;strokeColor=#059669;fontSize=12" vertex="1" parent="1">
          <mxGeometry x="1300" y="785" width="285" height="85" as="geometry" />
        </mxCell>

        <mxCell id="postgres" value="PostgreSQL + Prisma&#xa;组织、项目、鉴权、配置、关系型 CRUD" style="shape=cylinder3d;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#ffffff;strokeColor=#dc2626;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="95" y="995" width="210" height="90" as="geometry" />
        </mxCell>
        <mxCell id="clickhouse-legacy" value="ClickHouse legacy 表&#xa;traces、observations、scores&#xa;ReplacingMergeTree" style="shape=cylinder3d;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#ffffff;strokeColor=#dc2626;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="345" y="995" width="230" height="90" as="geometry" />
        </mxCell>
        <mxCell id="clickhouse-events" value="ClickHouse v4 events&#xa;events_full 写入/全量读取&#xa;events_core 快速查询投影" style="shape=cylinder3d;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#ffffff;strokeColor=#dc2626;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="615" y="995" width="250" height="90" as="geometry" />
        </mxCell>
        <mxCell id="redis" value="Redis / BullMQ&#xa;队列、限流、缓存、锁" style="shape=cylinder3d;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#ffffff;strokeColor=#dc2626;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="905" y="995" width="210" height="90" as="geometry" />
        </mxCell>
        <mxCell id="s3" value="S3 / Blob 存储&#xa;原始摄取事件、媒体、导出文件" style="shape=cylinder3d;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#ffffff;strokeColor=#dc2626;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="1155" y="995" width="210" height="90" as="geometry" />
        </mxCell>
        <mxCell id="outbound" value="外部系统&#xa;LLM 提供商、webhook 目标、Slack、Stripe、PostHog" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#dc2626;fontSize=12;fontStyle=1" vertex="1" parent="1">
          <mxGeometry x="1405" y="995" width="210" height="90" as="geometry" />
        </mxCell>

        <mxCell id="flow-ui" value="UI 查询/变更" style="endArrow=block;html=1;rounded=0;strokeColor=#4f46e5;fontSize=11" edge="1" parent="1" source="browser" target="next-ui">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-ui-trpc" value="类型安全调用" style="endArrow=block;html=1;rounded=0;strokeColor=#4f46e5;fontSize=11" edge="1" parent="1" source="next-ui" target="trpc">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-public" value="REST 请求" style="endArrow=block;html=1;rounded=0;strokeColor=#4f46e5;fontSize=11" edge="1" parent="1" source="sdk" target="public-api">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-ingest" value="批量摄取" style="endArrow=block;html=1;rounded=0;strokeColor=#4f46e5;fontSize=11" edge="1" parent="1" source="sdk" target="ingestion-api">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-otel" value="OTel 摄取" style="endArrow=block;html=1;rounded=0;strokeColor=#4f46e5;fontSize=11" edge="1" parent="1" source="otel" target="ingestion-api">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>

        <mxCell id="flow-trpc-shared" value="schema + 服务" style="endArrow=block;html=1;rounded=0;strokeColor=#d97706;fontSize=11" edge="1" parent="1" source="trpc" target="repos-services">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-public-shared" value="Zod schema + 服务" style="endArrow=block;html=1;rounded=0;strokeColor=#d97706;fontSize=11" edge="1" parent="1" source="public-api" target="domain-contracts">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-search-filter" value="URL FilterState" style="endArrow=block;html=1;rounded=0;strokeColor=#d97706;fontSize=11" edge="1" parent="1" source="next-ui" target="filter-contracts">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-query-builder" value="视图/查询契约" style="endArrow=block;html=1;rounded=0;strokeColor=#d97706;fontSize=11" edge="1" parent="1" source="trpc" target="query-contracts">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-ingest-shared" value="processEventBatch" style="endArrow=block;html=1;rounded=0;strokeColor=#d97706;fontSize=11" edge="1" parent="1" source="ingestion-api" target="queue-contracts">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>

        <mxCell id="flow-s3-write" value="原始 event JSON" style="endArrow=block;html=1;rounded=0;strokeColor=#dc2626;fontSize=11" edge="1" parent="1" source="queue-contracts" target="s3">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-queue-redis" value="BullMQ 作业" style="endArrow=block;html=1;rounded=0;strokeColor=#dc2626;fontSize=11" edge="1" parent="1" source="queue-contracts" target="redis">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-redis-worker" value="消费类型化作业" style="endArrow=block;html=1;rounded=0;strokeColor=#059669;fontSize=11" edge="1" parent="1" source="redis" target="worker-manager">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-worker-ingest" value="分发" style="endArrow=block;html=1;rounded=0;strokeColor=#059669;fontSize=11" edge="1" parent="1" source="worker-manager" target="ingestion-worker">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-worker-other" value="分发" style="endArrow=block;html=1;rounded=0;strokeColor=#059669;fontSize=11" edge="1" parent="1" source="worker-manager" target="eval-worker">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-s3-read" value="读取事件正文" style="endArrow=block;html=1;rounded=0;strokeColor=#059669;fontSize=11" edge="1" parent="1" source="s3" target="ingestion-worker">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-ingest-writer" value="记录" style="endArrow=block;html=1;rounded=0;strokeColor=#059669;fontSize=11" edge="1" parent="1" source="ingestion-worker" target="clickhouse-writer">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>

        <mxCell id="flow-writer-events" value="events_full JSONEachRow" style="endArrow=block;html=1;rounded=0;strokeColor=#dc2626;fontSize=11" edge="1" parent="1" source="clickhouse-writer" target="clickhouse-events">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-writer-legacy" value="legacy 双写" style="endArrow=block;html=1;rounded=0;strokeColor=#dc2626;fontSize=11;dashed=1" edge="1" parent="1" source="clickhouse-writer" target="clickhouse-legacy">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-services-postgres" value="事务型 CRUD" style="endArrow=block;html=1;rounded=0;strokeColor=#dc2626;fontSize=11" edge="1" parent="1" source="repos-services" target="postgres">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-services-ch" value="分析查询" style="endArrow=block;html=1;rounded=0;strokeColor=#dc2626;fontSize=11" edge="1" parent="1" source="repos-services" target="clickhouse-events">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-query-ch" value="安全 SQL 构建器" style="endArrow=block;html=1;rounded=0;strokeColor=#dc2626;fontSize=11" edge="1" parent="1" source="query-contracts" target="clickhouse-events">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-worker-postgres" value="元数据/配置查询" style="endArrow=block;html=1;rounded=0;strokeColor=#dc2626;fontSize=11" edge="1" parent="1" source="eval-worker" target="postgres">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-outbound" value="调用 / 回调" style="endArrow=block;html=1;rounded=0;strokeColor=#dc2626;fontSize=11" edge="1" parent="1" source="eval-worker" target="outbound">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="flow-web-outbound" value="公共集成" style="endArrow=block;html=1;rounded=0;strokeColor=#dc2626;fontSize=11;dashed=1" edge="1" parent="1" source="external-services" target="outbound">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>

        <mxCell id="legend" value="图例：实线 = 主运行链路；虚线 = 条件路径 / legacy 路径 / 双写路径。黄色层是让 web 与 worker 保持一致的契约中心。" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8fafc;strokeColor=#94a3b8;fontSize=12" vertex="1" parent="1">
          <mxGeometry x="95" y="1138" width="1490" height="34" as="geometry" />
        </mxCell>
      </root>
    </mxGraphModel>
  </diagram>
</mxfile>
