- Remove outdated development plan from `development-plan.md`. - Update `operations.md` to include details on authorization cache configuration. - Revise `quickstart.md` for clarity on local development setup and database initialization. - Delete redundant `redis-authorization-cache.md`. - Add new `tenant-provisioning.md` to document the process of setting up a tenant from an empty database.
7.7 KiB
空数据库到租户建站验收
本页记录 Development 环境从全新 PostgreSQL 数据库完成平台管理员、租户、Owner 激活、网站发布和学生端访问的真实流程。数据库迁移只由 Tiku.DbMigrator 执行,API 不会自动更新 Schema。
1. 准备环境
需要 .NET 10、Node.js 24+、npm 11+、PostgreSQL、Redis,以及 psql、createdb、dropdb。
dotnet --version
node --version
npm --version
pg_isready -h 127.0.0.1 -p 5432
redis-cli -h 127.0.0.1 -p 6379 ping
首次拉取代码后安装依赖:
dotnet restore TIKU-BACKEND.slnx
npm --prefix Tiku.PlatformAdmin.Web install
npm --prefix /path/to/tiku-saas-web install
2. 创建空数据库
以下操作只针对本地数据库 tiku。如果它已经包含需要保留的数据,请先备份,不要执行清理命令。
dropdb --if-exists -h 127.0.0.1 -U <数据库用户> tiku
createdb -h 127.0.0.1 -U <数据库用户> tiku
Development 未配置连接串时默认使用当前系统用户连接本机 tiku。其他用户或端口应显式设置:
export ConnectionStrings__Database='Host=127.0.0.1;Port=5432;Database=tiku;Username=<数据库用户>;Password=<本地密码>'
不要把连接串、密码或 Token 写入 appsettings*.json、README 或 Git。
3. 初始化目录、starter 套餐和首个平台账号
先设置一次性 Bootstrap 参数,再执行生产式空库初始化:
export ASPNETCORE_ENVIRONMENT=Development
export TIKU_BOOTSTRAP_PLATFORM_ADMIN_EMAIL='<平台管理员邮箱>'
export TIKU_BOOTSTRAP_PLATFORM_ADMIN_PASSWORD='<临时密码>'
export TIKU_BOOTSTRAP_PLATFORM_ADMIN_NAME='<显示名称>'
dotnet run --project Tiku.DbMigrator -- \
--skip-development-seed \
--bootstrap-platform-admin
该命令按固定顺序执行:
- EF Core Migration;
- Feature、Permission、菜单和额度目录;
- 内置
starter套餐及其已发布版本; - 可选的平台超级管理员 Bootstrap。
starter 是零元、CNY、已发布的建站基础套餐,包含 core.backoffice 和 marketing.site_content。首个平台账号使用临时密码,首次登录必须改密。
清除 Bootstrap 密码并再运行一次 Migrator,确认日常重复执行不会创建演示租户或重复目录:
unset TIKU_BOOTSTRAP_PLATFORM_ADMIN_PASSWORD
unset TIKU_BOOTSTRAP_PLATFORM_ADMIN_EMAIL
unset TIKU_BOOTSTRAP_PLATFORM_ADMIN_NAME
dotnet run --project Tiku.DbMigrator -- --skip-development-seed
Migration 需要 citext、ltree 和 pg_trgm 扩展。执行用户必须可以创建这些扩展,或由数据库管理员预先安装。
4. 启动真实服务
确保 Redis 已运行,然后从后端仓库启动 API:
export ASPNETCORE_ENVIRONMENT=Development
export ConnectionStrings__Redis='localhost:6379,abortConnect=false'
dotnet run --project Tiku.Api --launch-profile http
API 在 Development 会同时拉起平台管理端 Vite 服务:
- 平台管理端:http://localhost:5173
- API:http://localhost:5090
- Scalar:http://localhost:5090/scalar/v1
- OpenAPI:http://localhost:5090/openapi/v1.json
- Readiness:http://localhost:5090/api/health/ready
不要使用 http://localhost:5090/platform-admin/ 作为开发入口;该路径受 API 授权保护,未登录访问返回 401。
在 tiku-saas-web 仓库另开终端,使用真实 API 模式启动租户前端:
VITE_DATA_MODE=api \
VITE_DEV_API_TARGET='http://localhost:5090' \
npm run dev -- --host 0.0.0.0 --port 5180
浏览器始终请求同源 /api,Vite 只在服务端把它代理到 VITE_DEV_API_TARGET。代理保留原始 Host,因此 school.localhost 能由后端解析到正确租户。
5. 浏览器建站流程
5.1 平台首次登录
- 打开 http://localhost:5173;
- 使用 Bootstrap 邮箱和临时密码登录;
- 按页面要求设置新密码;
- 进入“租户管理”。
5.2 创建租户和本地域名
点击“新建租户”,至少填写:
- 租户短编码,例如
school; - 租户名称;
- 主域名
school.localhost; - Owner 姓名;
- Owner 邮箱或手机号。
不选择套餐时,后端自动使用 starter 和默认试用天数。Development 配置只对精确的 localhost 或 *.localhost 启用 DNS/TLS 旁路,通常数秒内显示“DNS 与 TLS 已激活”。其他域名仍走真实 DNS 和网关流程。
5.3 签发并消费 Owner 链接
- 域名 Active 后点击“领取激活链接”;
- 填写审计原因并确认;
- 立即保存弹窗中的一次性链接;
- 用完整链接打开
http://school.localhost:5180/activate/...#token=...; - Owner 设置密码后自动进入
/manage/onboarding。
Token 只在签发成功弹窗显示一次。租户前端读入 Fragment 后立即清除地址栏;后端消费后不能重放。平台管理员看不到 Owner 密码,也不需要审批 Owner 激活。
5.4 配置并发布
向导依次完成:品牌信息、模板、主题样式、页面模块、桌面/移动预览、发布上线。保存草稿不会影响学生端;发布成功后 Runtime 读取已发布配置。
打开或刷新 http://school.localhost:5180/,应看到新的品牌、导航、主题和首页模块。退出租户后台后,可在 http://school.localhost:5180/manage/login 使用 Owner 账号重新登录。
6. 预期状态
| 阶段 | 预期状态 |
|---|---|
| 刚创建域名 | pending |
| Development 后台任务处理完成 | 域名 active |
| Owner 尚未领取链接 | ready_to_issue |
| 链接签发 | issued |
| Owner 激活并登录 | 进入 /manage/onboarding |
| 草稿完成但未发布 | ready_to_launch |
| 发布完成 | 学生端显示已发布配置 |
7. 常见问题
.localhost 一直 Pending
确认 API 使用 ASPNETCORE_ENVIRONMENT=Development,并加载:
{
"TenantDomains": {
"PollSeconds": 2,
"EnableDevelopmentLocalhostBypass": true
}
}
API 日志应出现 Processed ... pending Development tenant domains。非 Development 环境启用该旁路会在启动时失败。
激活页只出现 OPTIONS,没有 POST
不要把 API 地址配置为浏览器请求 Base URL。租户前端真实模式必须使用同源 /api,开发代理目标使用:
VITE_DEV_API_TARGET=http://localhost:5090
确保旧的 VITE_API_BASE_URL 未注入进程,并重启 Vite。
激活失败后地址栏已没有 Token
如果后端尚未消费 Token,可重新打开平台最初交付的完整链接。已经消费、过期或丢失明文时,必须由平台撤销并重新签发,不能从数据库或日志恢复。
发布后旧标签仍显示筹备页
草稿与已发布配置相互隔离。确认向导显示发布成功后,刷新学生端标签,让它重新请求 Runtime Bootstrap。
Cookie 没有建立
必须通过 school.localhost:5180 访问激活和后台,不能改用 localhost:5180 或把 tenantId 填进请求。浏览器 Session 使用 Secure/HttpOnly Cookie,写请求使用 CSRF 双提交 Token,前端不得降级保存 JWT。
Readiness 返回 503
确认 PostgreSQL 和 Redis 均可访问。匿名 readiness 只返回总体状态;依赖详情需要具有 platform:operations:view 权限的平台账号。
8. 清理
先停止 API、平台 Vite 和租户 Vite,再只删除明确的本地数据库:
dropdb -h 127.0.0.1 -U <数据库用户> tiku
该操作不可恢复,会删除本轮创建的平台账号、租户、Session、草稿和发布配置。
日常开发启动见本地开发快速上手,更多配置见配置与后台任务,安全边界见认证、授权与租户隔离。