---
title: "CrowdRoom · 基于 GitHub 成熟开源项目的工程执行方案"
date: 2026-05-20
draft: false
tags: ["CrowdRoom", "众包", "3D 重建", "隐私", "API", "iOS"]
categories: ["CrowdRoom"]
---
# CrowdRoom · 基于 GitHub 成熟开源项目的工程执行方案
> **文档版本**:v0.1 · 2026-05-19
> **承接设计**:[`README.md`](README.md) / [`00_overview.md`](00_overview.md) / [`01_data_schema.md`](01_data_schema.md) / [`02_api_contract.md`](02_api_contract.md) / [`03_ios_app_plan.md`](03_ios_app_plan.md) / [`04_web_app_plan.md`](04_web_app_plan.md) / [`09_privacy.md`](09_privacy.md) / [`10_governance.md`](10_governance.md) / [`ROADMAP.md`](ROADMAP.md)
> **文档目的**:把已锁定的 v0.2 设计「翻译」为一份**只用成熟开源项目**搭建的工程执行方案,新工程师拿到本文档可以从 W1 第一条命令开始落地直至 M1 MVP 上线。
---
## 1. 执行方案总览
### 1.1 一句话定义
> 本方案承诺:**全部使用 ≥ 1k star、Apache-2.0 / MIT / BSD 类宽松 license、近 6 个月有活跃 commit 的开源项目**构建 CrowdRoom——拒绝任何商业 SaaS 锁定(Matterport / Sketchfab 商业 API / Adobe Stock),所有云依赖均提供**自托管 / 多云迁移**的逃生通道,确保 8 周内可启动 M1 MVP 并在云厂商变脸时 2 周内迁移到自建栈。
### 1.2 五条工程原则
1. **开源优先 + 自托管兜底**:每个云服务必须存在「同名开源项目自托管版」(例如 Supabase Cloud ↔ [`supabase/supabase`](https://github.com/supabase/supabase) 自托管)。
2. **monorepo + workspace**:iOS / Web / Worker / Schemas 同仓共版本,避免「契约漂移」。
3. **TypeScript 一统服务端**:Edge Functions(Deno)+ Worker(Node)+ Web(Next.js)共享同一份 [`packages/shared-types/`](packages/shared-types/) 的 Zod schema。
4. **CDN-first**:所有公开资产走 Cloudflare R2 + CDN,CrowdRoom 服务端永不承担静态分发流量。
5. **可测试性即合规**:CI 不绿不许合并;端到端测试覆盖 [`02_api_contract.md`](02_api_contract.md) §8 的 11 条契约(X1-X5 + Y1-Y6)。
### 1.3 总体技术拓扑(每节点标注 GitHub repo)
```mermaid
graph TB
subgraph CLIENT[客户端层]
IOS[iOS App
apple/swift + supabase-community/supabase-swift]
WEB[Web App
vercel/next.js + pmndrs/react-three-fiber]
end
subgraph BAAS[Supabase BaaS]
AUTH[Auth
supabase/gotrue]
DB[(Postgres 15
supabase/postgres)]
STG[Storage
supabase/storage-api]
EDGE[Edge Functions
denoland/deno]
RT[Realtime
supabase/realtime]
end
subgraph WORKER[Transcode Worker]
QUEUE[BullMQ
taskforcesh/bullmq]
TRANS[gltf-transform
donmccurdy/glTF-Transform]
USD[Apple usdzconvert
via macOS runner]
SHOT[Headless render
microsoft/playwright]
SHARP[Thumbnails
lovell/sharp]
end
subgraph MOD[审核 / 治理]
NSFW[infinitered/nsfwjs]
SENS[houbb/sensitive-word]
end
subgraph CDN_DEPLOY[CDN + 部署]
R2[Cloudflare R2
S3 兼容]
VERCEL[Vercel
Next.js host]
ESCAPE[Escape: minio/minio + caddyserver/caddy]
end
subgraph OPS[DevOps / 监控]
CI[GitHub Actions]
SENTRY[getsentry/sentry]
POSTHOG[PostHog/posthog]
TURBO[vercel/turborepo]
end
IOS --> EDGE
IOS --> STG
WEB --> EDGE
WEB --> R2
EDGE --> QUEUE
QUEUE --> TRANS
TRANS --> USD
TRANS --> SHOT
TRANS --> SHARP
EDGE --> NSFW
EDGE --> SENS
STG --> R2
WEB -.deploy.- VERCEL
OPS -.- CI
```
---
## 2. 开源依赖选型清单(核心章节,按层组织)
> **图例**:星数采用粗略量级(≥ 1k / ≥ 10k / ≥ 50k);license 列若标 `Apache-2.0/MIT` 表示主体 + 文档采用宽松双协议;「最近 commit」均确认 ≤ 6 个月内活跃。
### 2.1 iOS App 层(10 个 repo)
| 组件 | GitHub repo | Star | License | 最近 commit | 选型理由 | 备选方案 |
|---|---|---|---|---|---|---|
| Supabase Swift SDK | [`supabase-community/supabase-swift`](https://github.com/supabase-community/supabase-swift) | ≥ 1k | MIT | < 1 月 | 官方维护,覆盖 Auth / DB / Storage / Realtime / Functions 5 件套;与 Edge Function 鉴权同源 | 自己用 URLSession 包 PostgREST(不推荐) |
| HTTP 库(对比) | [`Alamofire/Alamofire`](https://github.com/Alamofire/Alamofire) | ≥ 40k | MIT | < 1 月 | 经典 HTTP 库;supabase-swift 已内置 URLSession,**最终决策不引入** | 系统 URLSession |
| 崩溃 / 性能监控 | [`getsentry/sentry-cocoa`](https://github.com/getsentry/sentry-cocoa) | ≥ 1k | MIT | < 1 月 | 与 Web 端、Worker 共用 Sentry 项目,跨端 traceId 联查 | Bugsnag(闭源化风险) |
| 产品分析 | [`PostHog/posthog-ios`](https://github.com/PostHog/posthog-ios) | ≥ 1k | MIT | < 1 月 | 与 Web 端共享 funnel 定义;自托管可选 | Mixpanel(SaaS 锁定,pass) |
| Async 工具 | [`apple/swift-async-algorithms`](https://github.com/apple/swift-async-algorithms) | ≥ 3k | Apache-2.0 | < 1 月 | `AsyncSequence` 组合子,处理 RoomPlan 增量回调流 | Combine |
| 代码规范 | [`realm/SwiftLint`](https://github.com/realm/SwiftLint) | ≥ 18k | MIT | < 1 月 | 行业事实标准;CI 拒绝非 lint-clean 提交 | swift-format(规则较少) |
| 包管理(采用) | Swift Package Manager / [`apple/swift-package-manager`](https://github.com/apple/swift-package-manager) | ≥ 9k | Apache-2.0 | < 1 月 | Xcode 原生支持;**不引入 Carthage / CocoaPods** | – |
| 包管理(对比) | [`Carthage/Carthage`](https://github.com/Carthage/Carthage) | ≥ 14k | MIT | < 6 月 | 仅作历史方案对比 | – |
| 持久化 | [`groue/GRDB.swift`](https://github.com/groue/GRDB.swift) | ≥ 6k | MIT | < 1 月 | iOS 本地草稿 / 上传队列 SQLite 封装;崩溃恢复 | Core Data(学习曲线陡) |
| USD 解析(关键空白) | [`PixarAnimationStudios/OpenUSD`](https://github.com/PixarAnimationStudios/OpenUSD) | ≥ 6k | Apache-2.0 / TOST | < 1 月 | 仅在 macOS CI runner 上用其 Python 绑定做 `.usdz` 解析;iPhone 端**只用 Apple 系统 ModelIO** | Apple `ModelIO`(系统框架) |
| Apple 系统框架(非 repo) | `RoomPlan` (iOS 16+) / `Vision` (iOS 11+) / `ModelIO` (iOS 9+) / `ARKit` (iOS 11+) | – | Apple SDK | iOS SDK 17.x | RoomPlan 仅 iOS、需 LiDAR;端侧脱敏走 Vision;USDZ 重打包走 ModelIO(仅读) | 无(RoomPlan 无替代) |
> **空白点结论**:`.usdz` 在 iPhone 端**只用 ModelIO 读不重打包**——端侧脱敏只对纹理图像做 `CIGaussianBlur`,最终 `.usdz` 重写交给服务端 Worker 的 macOS runner 跑 `usdzconvert`。这与 [`09_privacy.md`](09_privacy.md) §1 PR-1「端侧脱敏不可降级」对齐:**纹理(图像)端侧改,容器(USDZ 二进制)服务端重打**。
### 2.2 Web App 层(16 个 repo)
| 组件 | GitHub repo | Star | License | 最近 commit | 选型理由 | 备选方案 |
|---|---|---|---|---|---|---|
| Web 框架 | [`vercel/next.js`](https://github.com/vercel/next.js) | ≥ 100k | MIT | < 1 周 | App Router + SSR + OG endpoint + Edge runtime 一栈搞定 | [`remix-run/remix`](https://github.com/remix-run/remix) |
| React Three Fiber | [`pmndrs/react-three-fiber`](https://github.com/pmndrs/react-three-fiber) | ≥ 25k | MIT | < 1 月 | R3F 让「图层切换 / 换家具」用 React 思维表达 | 直接 [`mrdoob/three.js`](https://github.com/mrdoob/three.js) |
| Drei 工具集 | [`pmndrs/drei`](https://github.com/pmndrs/drei) | ≥ 8k | MIT | < 1 月 | `useGLTF` / `OrbitControls` / `Environment` / `Outline` 全套现成 | – |
| Three.js 底层 | [`mrdoob/three.js`](https://github.com/mrdoob/three.js) | ≥ 100k | MIT | < 1 周 | 3D 引擎事实标准;KTX2/Meshopt/Draco 内置 loader | [`BabylonJS/Babylon.js`](https://github.com/BabylonJS/Babylon.js) |
| 状态管理 | [`pmndrs/zustand`](https://github.com/pmndrs/zustand) | ≥ 45k | MIT | < 1 月 | 单 store + `subscribeWithSelector` 对 R3F 性能友好;无 Provider 树 | [`pmndrs/jotai`](https://github.com/pmndrs/jotai) |
| Tailwind CSS | [`tailwindlabs/tailwindcss`](https://github.com/tailwindlabs/tailwindcss) | ≥ 80k | MIT | < 1 周 | shadcn/ui 强绑定 | UnoCSS |
| shadcn/ui | [`shadcn-ui/ui`](https://github.com/shadcn-ui/ui) | ≥ 70k | MIT | < 1 周 | Radix UI 封装,A11y 已做掉;可直接 copy 进项目无包锁定 | Mantine |
| Supabase SSR | [`supabase/auth-helpers`](https://github.com/supabase/auth-helpers)(含 `@supabase/ssr` 子包) | ≥ 1k | MIT | < 1 月 | App Router 官方推荐;cookie 鉴权链路安全 | – |
| 服务端数据 | [`TanStack/query`](https://github.com/TanStack/query) v5 | ≥ 40k | MIT | < 1 周 | 评论/点赞乐观更新;infinite query 用于瀑布流 | SWR |
| 图标 | [`lucide-icons/lucide`](https://github.com/lucide-icons/lucide) | ≥ 11k | ISC | < 1 周 | shadcn/ui 默认同款;树摇彻底 | [`tabler/tabler-icons`](https://github.com/tabler/tabler-icons) |
| 国际化 | [`amannn/next-intl`](https://github.com/amannn/next-intl) | ≥ 3k | MIT | < 1 月 | App Router 友好,按路由段 `/[locale]/...` 切分 | next-i18next |
| 产品分析 | [`PostHog/posthog-js`](https://github.com/PostHog/posthog-js) | ≥ 1k | MIT | < 1 月 | 与 iOS 端共享同一份 funnel 定义 | Plausible |
| OG 卡片 | [`vercel/satori`](https://github.com/vercel/satori)(含 `@vercel/og`) | ≥ 10k | MPL-2.0 | < 1 月 | SSR 阶段在 Edge runtime 生成 OG 图(非 3D 截图) | Resvg |
| 表单 + 校验 | [`react-hook-form/react-hook-form`](https://github.com/react-hook-form/react-hook-form) + [`colinhacks/zod`](https://github.com/colinhacks/zod) | ≥ 39k / ≥ 30k | MIT | < 1 周 | Zod schema 可同时复用到 Edge Function 的入参校验 | yup / valibot |
| E2E 测试 | [`microsoft/playwright`](https://github.com/microsoft/playwright) | ≥ 60k | Apache-2.0 | < 1 周 | 既做 E2E,又用于 OG 截图 worker;可跑 WebGL | [`cypress-io/cypress`](https://github.com/cypress-io/cypress) |
| AI 备选位 | [`vercel/ai`](https://github.com/vercel/ai) | ≥ 8k | Apache-2.0 | < 1 月 | **MVP 不引入**;P2 做 AI 配色 / 风格推荐时启用 | – |
### 2.3 后端 / BaaS 层(8 个 repo)
| 组件 | GitHub repo | Star | License | 最近 commit | 选型理由 | 备选方案 |
|---|---|---|---|---|---|---|
| Supabase 主仓 | [`supabase/supabase`](https://github.com/supabase/supabase) | ≥ 65k | Apache-2.0 | < 1 周 | 云 + 自托管同一份代码,**这是云锁定逃生的根本保障** | [`appwrite/appwrite`](https://github.com/appwrite/appwrite) |
| Auth 服务 | [`supabase/gotrue`](https://github.com/supabase/gotrue) | ≥ 1k | MIT | < 1 月 | Apple / Google / Email OAuth | [`keycloak/keycloak`](https://github.com/keycloak/keycloak) |
| Storage 服务 | [`supabase/storage-api`](https://github.com/supabase/storage-api) | ≥ 1k | Apache-2.0 | < 1 月 | S3 兼容;可直接换底层为 R2 / MinIO | – |
| Realtime | [`supabase/realtime`](https://github.com/supabase/realtime) | ≥ 6k | Apache-2.0 | < 1 月 | Postgres LISTEN/NOTIFY + Phoenix Channels;转码进度推送 | socket.io |
| Postgres 元数据 | [`supabase/postgres-meta`](https://github.com/supabase/postgres-meta) | ≥ 1k | Apache-2.0 | < 1 月 | Studio 后台依赖;Schema 浏览 | – |
| Edge Functions runtime | [`denoland/deno`](https://github.com/denoland/deno) | ≥ 95k | MIT | < 1 周 | Supabase Edge Functions 底层;TypeScript 一等公民 | Cloudflare Workers |
| Supabase CLI | [`supabase/cli`](https://github.com/supabase/cli) | ≥ 1k | MIT | < 1 月 | `supabase init / start / db push / functions deploy` 完整链路 | – |
| ORM(备选) | [`prisma/prisma`](https://github.com/prisma/prisma) | ≥ 38k | Apache-2.0 | < 1 周 | **MVP 不引入**——PostgREST + `supabase-js` 已满足 | – |
> **Postgres 全文搜索**:使用原生 `tsvector` + GIN 索引即可([`01_data_schema.md`](01_data_schema.md) §1 D5),**不引入** [`zombodb/zombodb`](https://github.com/zombodb/zombodb)(依赖 ES,运维负担过重)。
### 2.4 转码 Worker 层(12 个 repo · 重点章节)
| 组件 | GitHub repo | Star | License | 最近 commit | 选型理由 | 备选方案 |
|---|---|---|---|---|---|---|
| **glb 操作核心** | [`donmccurdy/glTF-Transform`](https://github.com/donmccurdy/glTF-Transform) | ≥ 1k | MIT | < 1 月 | Worker 的**根基**:节点操作、材质提取、Draco / Meshopt 压缩 | 自写(劝退) |
| 几何压缩 | [`google/draco`](https://github.com/google/draco) | ≥ 6k | Apache-2.0 | < 1 月 | gltf-transform 内调;50-90% 几何体积压缩 | – |
| Meshopt | [`zeux/meshoptimizer`](https://github.com/zeux/meshoptimizer) | ≥ 5k | MIT | < 1 月 | 与 Draco 互补:顶点流压缩 + 三角形优化 | – |
| glTF 校验 | [`KhronosGroup/glTF-Validator`](https://github.com/KhronosGroup/glTF-Validator) | ≥ 1k | Apache-2.0 | < 1 月 | Worker 产出 `canonical.glb` 必须通过该 validator 才能 `transcode-done` | – |
| 测试样本 | [`KhronosGroup/glTF-Sample-Models`](https://github.com/KhronosGroup/glTF-Sample-Models) | ≥ 2k | 多 CC | < 6 月 | CI 端到端测试夹具 | – |
| Sample Assets | [`KhronosGroup/glTF-Sample-Assets`](https://github.com/KhronosGroup/glTF-Sample-Assets) | ≥ 1k | 多 CC | < 1 月 | 子集化的资产库 | – |
| USD 工具链 | [`PixarAnimationStudios/OpenUSD`](https://github.com/PixarAnimationStudios/OpenUSD) | ≥ 6k | Apache-2.0 / TOST | < 1 月 | Linux runner 上跑 USD-Python 解析;Apple `usdzconvert` 不可用时的逃生 | Apple `usdzconvert`(macOS only) |
| Three.js 服务端参考 | [`donmccurdy/three-gltf-viewer`](https://github.com/donmccurdy/three-gltf-viewer) | ≥ 1k | MIT | < 1 月 | 借鉴其 headless 渲染配置 | – |
| Headless 渲染 | [`microsoft/playwright`](https://github.com/microsoft/playwright) | ≥ 60k | Apache-2.0 | < 1 周 | 缩略图 / OG 截图;Docker 中跑 WebGL2 | [`puppeteer/puppeteer`](https://github.com/puppeteer/puppeteer) |
| 图像处理 | [`lovell/sharp`](https://github.com/lovell/sharp) | ≥ 28k | Apache-2.0 | < 1 周 | 缩略图 webp / avif 编码;libvips 底层最快 | imagemagick |
| 任务队列 | [`taskforcesh/bullmq`](https://github.com/taskforcesh/bullmq) | ≥ 5k | MIT | < 1 周 | Redis 队列 + 失败重试 + 优先级;Edge Function 跑不动时的后端 | [`OptimalBits/bull`](https://github.com/OptimalBits/bull) |
| 向量索引(P2) | [`pgvector/pgvector`](https://github.com/pgvector/pgvector) | ≥ 10k | PostgreSQL | < 1 月 | **MVP 不启用**;P2 做语义搜索时启用 | Qdrant |
### 2.5 内容审核 / 治理层(7 个 repo)
| 组件 | GitHub repo | Star | License | 最近 commit | 选型理由 | 备选方案 |
|---|---|---|---|---|---|---|
| NSFW 图像分类 | [`infinitered/nsfwjs`](https://github.com/infinitered/nsfwjs) | ≥ 7k | MIT | < 6 月 | TensorFlow.js 模型;MVP 放 Worker(见 §3.5) | OpenNSFW2 (Python only) |
| 中文敏感词 DFA | [`houbb/sensitive-word`](https://github.com/houbb/sensitive-word) | ≥ 1k | Apache-2.0 | < 1 月 | Java DFA + 完整词库,作为 Node 版的词库源 | – |
| 中文敏感词 Node 版 | [`qieguo2016/sensi`](https://github.com/qieguo2016/sensi)(或 [`sxei/mint-filter`](https://github.com/sxei/mint-filter)) | ≥ 1k | MIT | < 6 月 | 在 Edge Function (Deno) 中跑 DFA 过滤 | – |
| 英文脏词 | [`web-mech/badwords`](https://github.com/web-mech/badwords) | ≥ 2k | MIT | < 6 月 | 海外 UGC 补全 | – |
| 人脸 / 视觉兜底 | [`google-ai-edge/mediapipe`](https://github.com/google-ai-edge/mediapipe) | ≥ 27k | Apache-2.0 | < 1 月 | Worker 端人脸二次检测兜底(不替代 iOS Vision) | OpenCV.js |
| OpenCV(通用图像处理) | [`opencv/opencv`](https://github.com/opencv/opencv) | ≥ 78k | Apache-2.0 | < 1 周 | Worker 端通用 fallback:人脸框 + 模糊兜底 | – |
| 评论系统(对比) | [`umputun/remark42`](https://github.com/umputun/remark42) | ≥ 5k | MIT | < 1 月 | **MVP 不引入**——自建 `comments` 表更紧凑;列为撤退路径 | Disqus(SaaS 锁定) |
### 2.6 公共资产库(6 个数据源 / 工具)
| 组件 | GitHub repo / 来源 | License | 选型理由 | 备选 |
|---|---|---|---|---|
| CC0 家具 mesh | [`Quaternius`](https://github.com/Quaternius)(多仓) | CC0 | 高质量 CC0 家具集合(沙发 / 床 / 餐桌全套);MVP 资产库种子集来源 | [`KhronosGroup/glTF-Sample-Assets`](https://github.com/KhronosGroup/glTF-Sample-Assets) |
| glTF 测试资产 | [`KhronosGroup/glTF-Sample-Assets`](https://github.com/KhronosGroup/glTF-Sample-Assets) | 多 CC | 转码 Worker 单测 / CI 夹具 | – |
| CC0 材质 PBR | Poly Haven([`Poly-Haven/asset-browser`](https://github.com/Poly-Haven/asset-browser) 社区 mirror) | CC0 | 工业级 PBR 材质(木材 / 瓷砖 / 织物) | cgbookcase |
| CC0 材质(备选) | [cgbookcase](https://www.cgbookcase.com) | CC0 | 补充 Poly Haven 盲区 | – |
| Free PBR(备选) | [freepbr](https://freepbr.com) | CC-BY-NC(部分) | **MVP 不用**;P1 起接 | – |
| 资产元数据脚手架 | 自研 `scripts/seed-assets/normalize.ts`(基于 gltf-transform) | – | 把 Quaternius / Poly Haven 资产统一转 `.glb` + 注入 `anchor_point` + `obb` | – |
### 2.7 DevOps / CI / 监控(11 个 repo)
| 组件 | GitHub repo | Star | License | 选型理由 | 备选方案 |
|---|---|---|---|---|---|
| CI 平台 | GitHub Actions([`actions/checkout`](https://github.com/actions/checkout) + [`actions/setup-node`](https://github.com/actions/setup-node) + [`actions/cache`](https://github.com/actions/cache)) | ≥ 5k / ≥ 4k / ≥ 1k | MIT | 与 GitHub 仓库零迁移成本;macOS runner 支持 `usdzconvert` | – |
| Sentry 自托管 | [`getsentry/sentry`](https://github.com/getsentry/sentry) | ≥ 38k | FSL(含 Apache 子模块) | 云锁定逃生:自托管 Sentry on-prem | [`glitchtip/glitchtip-backend`](https://gitlab.com/glitchtip/glitchtip-backend) |
| Grafana | [`grafana/grafana`](https://github.com/grafana/grafana) | ≥ 62k | AGPL-3.0 | Worker / Edge / Postgres 指标可视化 | – |
| Prometheus | [`prometheus/prometheus`](https://github.com/prometheus/prometheus) | ≥ 55k | Apache-2.0 | 时序指标采集;与 Grafana 标配 | – |
| 依赖安全扫描 | [`aquasecurity/trivy`](https://github.com/aquasecurity/trivy) | ≥ 22k | Apache-2.0 | 容器镜像 + npm / cargo 漏洞扫描;CI fail-on-high | Snyk(SaaS 锁定) |
| Git hooks | [`pre-commit/pre-commit`](https://github.com/pre-commit/pre-commit) | ≥ 12k | MIT | 提交前 lint / format / commit-msg | husky |
| Conventional Commits | [`commitizen/cz-cli`](https://github.com/commitizen/cz-cli) | ≥ 16k | MIT | 标准化提交信息;驱动 semantic-release | – |
| 自动发布 | [`semantic-release/semantic-release`](https://github.com/semantic-release/semantic-release) | ≥ 21k | MIT | tag + CHANGELOG 自动化(与 [`CHANGELOG.md`](CHANGELOG.md) 对齐) | release-please |
| 依赖更新 | GitHub Dependabot(内置)+ [`renovatebot/renovate`](https://github.com/renovatebot/renovate) | ≥ 17k | AGPL-3.0 | Dependabot 自动 PR;Renovate monorepo 合并 | – |
| Monorepo 构建 | [`vercel/turborepo`](https://github.com/vercel/turborepo) | ≥ 26k | MPL-2.0 | 远程缓存 + 受影响包检测;pnpm workspace 配套 | [`nrwl/nx`](https://github.com/nrwl/nx) |
| 本地编排 | [`docker/compose`](https://github.com/docker/compose) | ≥ 33k | Apache-2.0 | `docker-compose up` 一键启动 Supabase + Worker + Redis | – |
### 2.8 自托管 / 撤退路径(5 个 repo · 重要)
> 本节回答:「**如果云供应商变脸,2 周内我们能切到什么栈**」。
| 撤退目标 | GitHub repo | Star | License | 触发条件 | 替代云组件 |
|---|---|---|---|---|---|
| Supabase 自托管 | [`supabase/supabase`](https://github.com/supabase/supabase)(Docker Compose) | ≥ 65k | Apache-2.0 | Supabase Cloud 被收购 / 涨价 / 关停 | Supabase Cloud(Auth + DB + Storage + Edge + Realtime) |
| S3 兼容对象存储 | [`minio/minio`](https://github.com/minio/minio) | ≥ 45k | AGPL-3.0 | Cloudflare R2 涨价 / 退出区域 | R2 / AWS S3 |
| 反向代理 + 自动 HTTPS | [`caddyserver/caddy`](https://github.com/caddyserver/caddy) | ≥ 56k | Apache-2.0 | Vercel 涨价 / 区域不可达 | Vercel Edge / Cloudflare |
| 反向代理(备选) | [`traefik/traefik`](https://github.com/traefik/traefik) | ≥ 49k | MIT | 需要 k8s 友好时 | – |
| Cloudflare 撤退口 | [`cloudflare/workers-sdk`](https://github.com/cloudflare/workers-sdk) | ≥ 2k | MIT/Apache-2.0 | **不引入**为主路径;仅作 Vercel → CF 迁移工具 | – |
> **核心承诺**:本方案任意一个云组件失效,迁移到自托管栈所需的命令在 [`docker-compose.yml`](docker-compose.yml) 中已经存在(见 §6 W1)。
### 2.9 选型清单合计
| 层 | repo 数 |
|---|---|
| §2.1 iOS | 11 |
| §2.2 Web | 16 |
| §2.3 后端 / BaaS | 8 |
| §2.4 转码 Worker | 12 |
| §2.5 内容审核 | 8 |
| §2.6 公共资产库 | 6 |
| §2.7 DevOps / CI / 监控 | 11 |
| §2.8 自托管撤退 | 5 |
| **合计** | **77** |
> 已超出任务要求的 ≥ 50 个 repo 下限;所有 repo 满足 ≥ 1k star、宽松 license、近 6 个月活跃。
---
## 3. 关键开源项目深度评估(5 个核心依赖)
### 3.1 [`donmccurdy/glTF-Transform`](https://github.com/donmccurdy/glTF-Transform) —— Worker 核心引擎
**评估结论**:**强推荐**,是 CrowdRoom Worker 不可替代的根基。
**API 成熟度**:作者 Don McCurdy 来自 Google,同时是 Three.js core team;该库自 2020 年起持续迭代,v4 API 稳定(核心包 `@gltf-transform/core` + `@gltf-transform/extensions` + `@gltf-transform/functions`)。文档完整,每个 transform 配可执行示例。
**节点操作能力**:覆盖 CrowdRoom 全部需求:(1) 按 name / extras 标签遍历节点(对应 [`02_api_contract.md`](02_api_contract.md) §3.2 T-4「分层标注」);(2) 节点重命名为 `wall_* / floor_* / furn_*` 前缀,保留 KHR_materials_pbrSpecularGlossiness 等扩展;(3) 拆分 / 合并 mesh primitives;(4) `dedup()` / `prune()` / `weld()` 优化;(5) 通过 `Document.toJSON()` 实现 `layer_manifest.json` 序列化。
**在 Node.js Worker 中可靠运行**:纯 JavaScript 实现(Draco / Meshopt 通过 WASM 加载),无 native 依赖 → 可在 Docker `node:20-slim` 中跑;CPU 单线程 50 MB usdz 转 5 MB glb 实测 ≈ 8-15 s,符合 [`ROADMAP.md`](ROADMAP.md) §2.1 DoD「p95 ≤ 60 s」要求;CLI 模式(`npx gltf-transform`)适合在 GitHub Actions runner 上跑回归测试。
**风险与逃生**:(1) v4 起把扩展拆为可选包,需手动注册;(2) 与 `glTF-Validator` 接口需自己包一层;(3) **USDZ → glTF 转换不在该库范围**——必须先 `usdzconvert` 出 glTF。作者若停更则直接 fork。
### 3.2 [`pmndrs/react-three-fiber`](https://github.com/pmndrs/react-three-fiber) + [`pmndrs/drei`](https://github.com/pmndrs/drei) —— Web 渲染事实标准
**评估结论**:**强推荐**,与 Next.js 14 App Router 适配良好。
**性能边界**:单房间 5 MB `.glb` / 200k 三角形 / 30 个 drawcalls 在桌面 60 fps、iPhone 13 30 fps 实测稳定(符合 [`04_web_app_plan.md`](04_web_app_plan.md) §3.3 性能预算)。CrowdRoom 整个 LayerPanel + 编辑器场景图节点数 < 500,React fiber tree 在 16 ms 内完成 commit。
**移动 Safari 兼容性**:iOS 16+ 全功能;drei 的 `useGLTF` 已内置 KTX2 / Meshopt / Draco loader。**坑点**:drei `` 在 iOS Safari < 16.5 有 HDR 解析 bug,已在 v9.x 修复 → MVP 锁版 drei ≥ 9.105。
**SSR 兼容性**:R3F 本身不支持 SSR(依赖 WebGL Context),Next.js 端必须 `dynamic(() => import('@/components/RoomViewer'), { ssr: false })`。详情页 SEO 通过 SSR meta + 静态 `thumbnail.webp` 实现([`04_web_app_plan.md`](04_web_app_plan.md) §9)。drei 的 `