DoulorCloud README

The project's README from github.com/Doulor/DoulorCloud. As one markdown file: README.md.

Doulor Cloud

Doulor Cloud

一站式云端资源分发平台 —— 二级域名、域名邮箱、直链网盘、个人名片(Bento 空间)与 AI API 中转站

cloud.doulor.cn · GitHub Doulor/DoulorCloud

纯静态前端 + Serverless 后端:前端是构建产物直出的 SPA,后端全部跑在 Cloudflare Workers 上,数据库用 D1(SQLite)、对象存储用 R2,不依赖任何常驻服务器。


目录


界面预览

控制台 AI 中转站
控制台 AI 中转站
积分与商城 私信
积分与商城 私信

截图来自线上实例(cloud.doulor.cn),界面为深色主题,全站中英双语可切换。


功能概览

模块 说明
账号体系 邀请码 / 限时开放注册、邮箱验证、会话(D1 存储 + 多 Cookie 容错)、管理员 / 站长分级、可注销
二级域名 用户自助申请 *.doulor.cn 子域名,走 Cloudflare DNS API 创建与回收;支持自定义域名的自定义记录
域名邮箱 基于 Cloudflare Email Routing:每个用户按用户名获得 用户名@doulor.cn 邮箱,支持转发规则、临时分享箱、网页端收发
直链网盘 R2 对象存储(S3 兼容 API,跨账号),多桶架构 + 每用户配额,支持自定义直链域名与预签名直传
个人名片 / 空间 Bento 网格个人主页(/space/<用户名>、/profile/<slug>),音乐、歌词、图库、链接卡片、自定义配色与自动缩放
社区 帖子 / 评论 / 图片(走 R2)、楼中楼回复、通知与邮件提醒
聊天室 频道式实时聊天(轮询实现,不引常驻连接)、在线状态、未读角标
AI 中转站 自建 NewAPI 网关的账号打通:开通、密码绑定、API Key 代建、额度同步、订阅套餐、渠道捐献自动化
捐献体系 用户捐献上游 AI 渠道 / 反代账号(WorkBuddy、CLI2API 等)换取权限;自动审核 + 人工兜底
积分与成就 注册 / 捐献 / 活动获得积分;成就点独立体系、成就徽章与自定义称号
活动与抽奖 活动报名(认证码 / 抽奖)、奖池分配、到点自动开奖、活动分享页
积分商城 官方与用户商品、5 种交付方式(自动发码 / 人工 / 订阅 / 权限 / 积分)、订单状态机与消息中心联动
内网穿透(frp) frp 节点申请与开通,按节点鉴权方式决定是否需账号密码
代理订阅 订阅链接解析、节点测速与展示
工具箱 20+ 纯浏览器端工具(图片压缩、格式转换、文本处理…),零服务端请求
管理面板 用户 / 权限 / 捐献审核 / 商品订单 / 活动 / 公告 / 邮件通道 / 站点设置 / 额度看板(Cloudflare 用量与费用估算)

国际化:全站中英双语(自研零依赖 i18n,键值点分命名、类型安全)。


架构

                    ┌──────────────────────────────┐
   浏览器  ────────► │  Cloudflare 边缘(WAF / CDN) │
                    └──────────────┬───────────────┘
                                   │
        ┌──────────────────────────┼──────────────────────────┐
        ▼                          ▼                          ▼
┌────────────────┐        ┌────────────────┐        ┌──────────────────┐
│ 前端静态资产    │        │  API Worker    │        │  Email Worker    │
│ (Workers 静态  │        │ (鉴权/权限/业务 │        │ (收信路由 → 入库  │
│  资产 + SPA)   │        │  + CF API 调用) │        │  / 转发 / 回复)   │
└────────────────┘        └───────┬────────┘        └────────┬─────────┘
                                  │                          │
                 ┌────────────────┼────────────────┬─────────┘
                 ▼                ▼                ▼
           ┌──────────┐     ┌──────────┐    ┌────────────────┐
           │   D1     │     │   R2     │    │ Cloudflare API │
           │ (SQLite) │     │ (对象存储)│    │ (DNS/邮件路由)  │
           └──────────┘     └──────────┘    └────────────────┘
                 │
                 ▼
         ┌────────────────┐
         │ 外部 AI 中转站  │  ← 自建 NewAPI 网关(LLM API 聚合与分发)
         │  (NewAPI 集群) │
         └────────────────┘

技术栈

层 选型
前端 Vite(Rolldown)、React、TypeScript、Tailwind CSS、Radix UI / shadcn 风格组件
后端 Cloudflare Workers(ES Modules)、D1、R2(S3 API)、Workers 静态资产
测试 Vitest + @cloudflare/vitest-plugin(miniflare 内跑真实 Worker + D1)、Playwright(真浏览器走查)
质量护栏 自研静态检查:路由↔实现一致性、设置项是否真被服务端读取、死代码、i18n 键完整性
邮件 Cloudflare Email Routing(收)、Brevo / Posta / Cloudflare Send Email(发)
AI 网关 自建 NewAPI(集群部署,多节点共享库)

目录结构

src/                     前端
  components/            业务组件 + ui/(基础组件)
  layouts/               Landing / Dashboard 布局
  pages/                 路由页面(含管理面板各标签页)
  lib/                   工具(i18n、颜色、格式化、工具箱注册表…)
  services/api.ts        统一请求层(自动带 Cookie、错误归一化)
  types/                 共享类型
worker/                  后端(独立 npm 包)
  src/
    index.ts             路由表 + fetch/email/scheduled 三个入口
    handlers/            按业务域拆分的处理器(auth/community/chat/email/storage/newapi/…)
    auth.ts              会话与鉴权(requireUser / 权限解析)
    permissions.ts       权限模型(功能开关 + 角色)
    settings.ts          站点设置(默认值 + 读写;护栏要求每个键都有服务端读取点)
    r2.ts                R2 的 S3 / REST 两种模式与多桶分配
    newapi-client.ts     自建 AI 网关的 API 客户端(含缓存与令牌复用)
    mailer.ts            三级发信通道与模板
  migrations/            D1 迁移(按序执行)
  schema.sql             D1 基线表结构
  test/                  Vitest 用例(在 miniflare 里跑真实 Worker)
  scripts/               一致性护栏脚本(npm run check:*)
site-worker.js           前端站点的 Worker 入口(HTTPS 跳转 + 安全响应头 + 缓存策略)

核心设计

1. 单一 API Worker + 声明式路由

所有接口集中在一张路由表里声明(kind: "exact" | "regex" | "branch"),配合 npm run check:handlers 静态校验「前端调用的路径是否真的存在」「handler 是否真的导出」, 避免「前端在调、后端没有」这类静默失效。

2. 权限模型

3. 会话

4. 直链网盘与 R2

5. AI 中转站集成

自建 NewAPI 网关(LLM API 聚合分发)与本项目深度打通:

6. 准实时一律用轮询

项目刻意不引入 Durable Object / WebSocket:聊天室、收件箱、通知角标都是轮询, 但做了三件事:只在页面可见时轮询(切回标签页立即刷一次)、不同模块用不同间隔、 轮询走独立的「静默路径」并用 ref 校验「结果回来时选中的还是不是同一个对象」。

7. 邮箱

8. 质量护栏(npm run check)

本项目由多个 AI 并行开发同一工作区,因此把「容易静默失效」的约定都变成了静态检查:

护栏 防的是什么
check-handlers 路由声明与 handler 实现/导出不一致
check-settings 管理面板能改、服务端从不读的「假开关」
check-api-paths 前端调用的 API 路径不存在(被 SPA 兜底成 HTML,静默失效)
check-unused-exports 写好了却从未接线的死代码
check:i18n 中文加了 key、英文没加(i18n 键是类型安全的,缺了会编译失败)

另有一条项目特有的 SQL 约束被写成代码规范:D1 的 LIKE 模式最长 50 字符(标准 SQLite 是 50000), 超长直接报错且本地 miniflare 复现不了 —— 因此所有用户输入进 LIKE 都必须走 src/sql-like.ts 的截断封装。


数据模型

单库 70+ 张表,按域划分(worker/schema.sql 为基线,worker/migrations/ 为增量):

域 代表表
账号 users sessions invites
邮箱 mailboxes messages forward_rules tempbox
域名 domains dns_records subdomain_requests
网盘 storage_accounts r2_buckets storage_prefixes storage_shares
社区 posts comments feedback
聊天 chat_messages chat_presence
名片 profiles profile_assets
积分商城 user_points point_transactions point_products point_orders
活动 events event_claims
成就 / 称号 achievements user_achievements custom_titles user_titles
中转站 newapi_accounts newapi_admin_credentials
捐献 donations wb2api_bindings cli2api_bindings
运维 app_settings audit_logs rate_limits

安全模型


本地开发

# 前端
npm install
npm run dev          # Vite 开发服务器

# 后端
cd worker
npm install
cp .dev.vars.example .dev.vars   # 填入本地用值(不要提交)
npm run dev                      # wrangler dev

# 质量护栏 + 类型 + 测试
npm run check                    # 全部静态护栏 + tsc
npm test                         # Vitest(在 miniflare 里跑真实 Worker + D1)

本仓库只包含源码。线上环境配置、部署方式与运维脚本不在开源范围内。


发展历程

项目从 2026 年 9 月下旬起,以「每天一个可用增量」的节奏快速演进:

期间项目一直由多个 AI 并行开发,因此形成了「静态护栏 + 真浏览器走查 + 临时会话读线上库验证」这套 工程实践 —— 见上文「质量护栏」。


Star History

Star History Chart

点一个 star 就是对这个项目最好的支持,也会让更多需要的人看到它。


许可

暂未指定开源许可证。在补充 LICENSE 之前,默认保留所有权利(All rights reserved)。

DoulorCloud (Doulor/DoulorCloud)

domain
Searching Database…

What is this?Doulor Cloud is a self-hosted, all-in-one cloud resource distribution platform: each user gets a subdomain, a domain email address, R2-backed direct-link file storage, a personal Bento-style profile page, and access to a shared AI API relay, all running on a static frontend plus Cloudflare Workers with no persistent server.
Is this a library I import, or a platform I deploy myself?It is a full self-hosted web platform, not a library or CLI tool: a Vite/React static frontend served as Workers static assets, with all backend logic in a single Cloudflare Worker backed by D1 (SQLite) and R2 storage.
How do I get this running myself?The repo only contains source code; the README explicitly says live deployment configuration, hosting setup and ops scripts are not part of the open-source release, so you need to wire up your own Cloudflare Workers project, D1 database, and R2 buckets from scratch.
What Cloudflare services do I need before running it?You need Cloudflare Workers (API + static hosting), D1 for the 70+ table schema, R2 buckets (accessed via a self-implemented S3 SigV4 signature, so they can even live on a different Cloudflare account), and Email Routing for the mailbox feature; the AI relay feature additionally needs a self-hosted NewAPI gateway.
Any catches before relying on this?Chat, inbox and notifications are all done with polling instead of WebSockets/Durable Objects by design, and D1 caps the LIKE pattern length at 50 characters (versus SQLite's normal 50000), so every user-input search must go through a dedicated truncation wrapper.
What exactly is the AI relay station (AI 中转站)?It integrates with a self-hosted NewAPI gateway: a user can one-click activate a gateway account, get an auto-generated API key, sync quota and subscriptions, and even donate upstream AI channels or proxy accounts (e.g. WorkBuddy, CLI2API) to unlock extra privileges.
Why does chat use polling instead of WebSockets?The author deliberately avoided Durable Objects/WebSockets; chat, inbox and notification badges all poll on different intervals, only while the tab is visible, through a 'silent path' that discards stale responses.
What built-in tools does the platform include?A toolbox of 20+ pure browser-side utilities (image compression, format conversion, text processing, etc.) that run entirely client-side with zero server requests.
How does the project keep quality consistent when built by multiple AIs in parallel?It ships a set of custom static checks (check-handlers, check-settings, check-api-paths, check-unused-exports, check:i18n) that verify route-to-handler consistency, catch settings the backend never actually reads, find dead code, and enforce complete bilingual i18n keys.
Creator
Doulor
Size
12.5 MB
Stars
238
Updated
CommitOct 17
Age
26d
Commits · 90 Days