目的
目前 鲲 Galgame 这个项目有两个主要的网站,鲲 Galgame 论坛 和 鲲 Galgame 补丁,众所周知这两个网站的账户是不统一的,这在一些方面会对用户的使用以及网站维护造成很大的困扰
所以我们需要重构整个网站的账户系统,使得两个网站账户统一
这个方案有些过于大了,这一篇文章根本就写不完,后面等我们推出论坛的其他功能才可以写完文章
为什么要换后端是因为全栈 Node.js 框架的一些固有问题,后端写起来非常不顺手,没办法自由发挥
还有就是 Nitro 实在太垃圾了,性能太不好(主要是构建时和开发体验不好,虽然简洁但是如果需求过于复杂它撑不住,目前单论坛而言就有 200 个 api 了),如果再和目前使用的 Cloudflare Tunnel 一叠加,几乎人数一多就会出现 Error 1033 的错误,没办法解决
并且我们今年要上线 App 和桌面端,Node.js 的集成后端肯定是不行的,不方便暴露出 api 供第三方调用,不方便横向扩展
最初我想的是集成式的后端就足够了,现在发现虽然省了很多心,但是项目规模大了之后集成后端承载不起需求了
去年我发布过这样一篇文章: 基于大型 Web 服务集群的搭建以及维护设计研究
本次大重构只是产品技术迭代面临的一个正常挑战,并不是说集成后端不好,主要原因是集成后端已经跟不上现在的需求了,次要原因单纯是我喜欢折腾,或者说想要接触新的技术栈
初步的设计是:
鲲 Galgame 论坛一个后端
鲲 Galgame 补丁一个后端
游戏元信息的查询和编辑一个后端
鲲 Galgame OAuth 系统一个后端
App 和桌面端是对以上所有功能的统合,以上所有后端都具备 api endpoint,直接做一个 api getway 实现跨服务,App 和桌面端只需要一个独有的小后端即可,最后差不多类似于这样
┌─────────────┐
Web (kungal) ──> │ │ ──> kungal-api (Go Fiber)
Web (moyu) ──> │ API Gateway│ ──> moyu-api (Go Fiber)
App ──> │ (Nginx/ │ ──> gamewiki-api (Go Fiber)
Desktop ──> │ Traefik) │ ──> oauth-api (Go Fiber)
└─────────────┘
最终差不多六七个后端,六七个前端,若干数据库
注意,这个文章只是我自己当备忘录用户,现在还没有写完,之后代码写到哪里我就更新到哪里,如果文章停更说明目标已经实现
大家给我提的所有建议我都收到了,我把它们暂时加到网站的待办列表页面了,现在正在完全重构网站,技术上暂时没有办法修复任何 鲲 Galgame 论坛 和 鲲 Galgame 补丁 的问题和改进建议,如果重构完毕,我一定会第一时间修改这些问题,重构会让网站变得更加无敌,重构之后就可以加更多方便的功能了,请大家等待一段时间
路线图
迁移是需要路线图的,目前我们正在进行下面的工作
鲲 Galgame 论坛 Nuxt4 + Nitro 架构 -> Nuxt4 + GO Fiber (换后端)
鲲 Galgame 补丁 Next.js + Node.js Server -> Next.js / Nuxt + GO Fiber(换后端,为了统一可能换前端)
鲲 Galgame OAuth 系统 Nuxt4 + GO Fiber
gamewiki(现在还没开工)
具体的来说,这是路线图
- 编写基本的 OAuth 系统
- 迁移所有用户的账户到 鲲 Galgame OAuth 系统
- 重构编写基本的 鲲 Galgame 论坛 后端
- 对接 鲲 Galgame 论坛 账户到 鲲 Galgame OAuth 系统
- 重构编写基本的 鲲 Galgame 补丁 后端
- 对接 鲲 Galgame 补丁 账户到 鲲 Galgame OAuth 系统
- 重构所有 鲲 Galgame 论坛 后端(目前进度进行到这里)
- 重构所有 鲲 Galgame 补丁 后端
- 编写 game wiki 后端,供所有网站调用
- 联调 鲲 Galgame 论坛、鲲 Galgame 补丁、鲲 Galgame OAuth 系统、gamewiki
- 上线 6.0.0 版本论坛(目前论坛版本是 5.x,到这里为止论坛和补丁站账户会被统一,会上线,这样就能实现大家的各种新要求了)
- 给 鲲 Galgame 论坛 增加上传游戏文件等高级功能
- 优化 鲲 Galgame 补丁 的大补丁文件上传
- 优化一系列体验,上线 7.0.0 版本论坛
- 编写 鲲 Galgame / Kun Visual Novel App 应用 / 桌面端
值得注意的是,如果新的网站没有上线,所有用户都是感知不到的,如果上线了我会发布新的话题
下面可能是一些我自己的备忘录,因为太复杂了我自己写完代码可能都忘记操作步骤是什么了,需要记一下
迁移脚本执行顺序
要同步的项目有三个
-
kun-oauth-admin
-
kun-galgame-nuxt4
-
kun-galgame-patch-next
同时这三个项目需要三个数据库,迁移脚本有大量的耦合,因此迁移脚本的执行顺序是有必要的,并且必须按照这个顺序执行,任何一个错误都可能导致失败
创建 kun_oauth_admin 数据库
如果是第一次运行,需要创建针对于 kun-oauth-admin 的数据库,目前这个数据库的名称是 kun_oauth_admin
如果是第一次执行迁移脚本(新服务器),需要链接数据库后执行
create database kun_oauth_admin;
如果是重复运行脚本,则执行
drop database kun_oauth_admin;
create database kun_oauth_admin;
因为脚本十分复杂,编写可重复运行的脚本不如推倒重新运行所有内容,这也是我们需要停机更新网站的直接原因
去重 kungalgame 数据库中的邮箱重复用户
我们 Nuxt4 + Nitro 版本论坛(版本代号 5.1.0 以前)使用的是 kungalgame 这个数据库
但是这个版本的论坛存在一个 BUG,那就是没有对用户邮箱设置大小写不敏感的唯一约束
这个意思就是,如果有用户使用了 [email protected] 和 [email protected] ,那么这会被视为两个用户,理论上这就是一个用户,应该在用户注册或者更改邮箱的时候提示用户已存在
但是由于我的代码疏忽导致用户邮箱的大小写敏感,不同大小写邮箱的用户也被当作了若干个不同的用户
这在旧版本论坛中并不会产生任何问题,但是新版论坛我们放弃了 Nuxt 的集成后端 Nitro,选择了 GO Fiber + GORM 这个技术栈,为了之后的后端编写更加规范,我们选择移除部分重复的用户
这个邮箱去重脚本我们已经编写好,这一步直接在 kun-galgame-nuxt4 下运行
cd apps/api && go run check-dup-email
迁移 kungalgame 相关表
论坛的数据库表需要做一些更改才可以更好的兼容 kun-oauth-admin 以及 gorm
迁移脚本已经写好,继续在 kun-galgame-nuxt4 下运行这个命令即可
go run migrate
创建 kun_oauth_admin 的预制表
我们已经在项目中编写好了脚本,只需要在 kun-oauth-admin 根目录运行下面的命令即可
cd apps/api && go run migrate
迁移所有用户到 kun_oauth_admin 数据库
下一步是迁移所有用户,具体来说,在 kun-oauth-admin 中运行
go run ./cmd/migrate-users \
--kungal-dsn="host=127.0.0.1 port=5432 user=postgres password=kunloveren dbname=kungalgame" \
--moyu-dsn="host=127.0.0.1 port=5432 user=postgres password=renlovekun dbname=kungalgame_patch"
这个脚本运行的时间相当久,大概需要五分钟左右
迁移 kungalgame_patch 相关表
这是鲲 Galgame 补丁相关的数据库表,这些表也需要做调整来适应 oauth 和 gorm
我们已经编写好了脚本,直接在 kun-galgame-patch-next 下执行
psql -h localhost -U postgres -d kungalgame_patch -f prisma/migrations/20260409_oauth_integration/migration.sql
使用 pnpm prisma:push 校验迁移
按理来说迁移脚本中 SQL 迁移完,与 prisma db push 生成的数据表应该是兼容的
可以在 kun-galgame-nuxt4 和 kun-galgame-patch-next 中都运行一次
pnpm prisma:push
如果没有任何报错和警告,说明迁移成功
如果提示
⚠️ There might be data loss when applying the changes:
• The `alias` column on the `galgame_engine` table would be dropped and recreated. This will lead to data loss.
• The `galgame_type` column on the `galgame_rating` table would be dropped and recreated. This will lead to data loss.
• The `homepage` column on the `galgame_toolset` table would be dropped and recreated. This will lead to data loss.
• The `domain` column on the `galgame_website` table would be dropped and recreated. This will lead to data loss.
这说明 kungalgame 数据库迁移到时候因为各种原因导致没迁移完
这个时候在鲲 Galgame 论坛项目的根目录再执行一遍 kungalgame 的迁移命令即可
cd apps/api && go run migrate
创建 Galgame Wiki 数据库
我们将 Galgame 的元信息(介绍、人物、标题等等)做成了一个单独的 service,这个 service 独享一个数据库
新环境运行时肯定是没有这个数据库的,第一步需要创建这个数据库
create database kun_galgame_wiki;
初始化和迁移 Galgame Wiki 数据
需要运行下面的代码来初始化数据库表,然后迁移 鲲 Galgame 论坛的 Galgame 相关元数据到 kun_galgame_wiki 这个数据库
迁移 Galgame 数据,由于 Galgame 标签和会社比较多,可能会花费 5 分钟左右的时间
cd kun-oauth-admin
go run ./cmd/migrate-galgame
go run ./cmd/migrate-galgame-data --kungal-dsn="host=localhost port=5432 user=postgres password=kunloveren dbname=kungalgame"
重新运行
如果中途出现了任何错误,建议重置三个数据库,并且重新运行所有脚本
下面是一个统合的命令,方便我自己看
鲲 Galgame 论坛有个脚本比较特殊,具体来说
-
默认执行(跳过 005):go run cmd/migrate/main.go — 只跑 001-004
-
单独跑 005:go run cmd/migrate/main.go --only=005 — 只跑 005
-
跑所有(不排除):go run cmd/migrate/main.go --exclude="" — 跑全部
-
回滚 005:go run cmd/migrate/main.go --dir=down --only=005
因为这里的 005 会损害 kun_galgame_wiki 的迁移,所以需要单独最后跑一次
如果需要重新运行所有脚本,需要删除并重新创建 kun_oauth_admin, kun_galgame_wiki, kungalgame, kungalgame_patch 四个数据库,其中 kungalgame 和 kungalgame_patch 数据库有自己的重置脚本
# drop or recreate dbs
cd kun-oauth-admin
./scripts/reset_all.sh
# clear redis kv
redis-cli FLUSHALL
cd kun-galgame-nuxt4
cd apps/api && go run ./cmd/check-dup-email/main.go
# run 001-004 + 008-009 (008 is kungal-local, no deps)
go run ./cmd/migrate/main.go
cd kun-galgame-patch-next
# if db version mismatch, firstly replace it
psql -U postgres
\c kungalgame_patch;
REINDEX DATABASE kungalgame_patch;
ALTER DATABASE kungalgame_patch REFRESH COLLATION VERSION;
\q
# OAuth Integration + Schema Alignment
cd apps/api
go run ./cmd/migrate-oauth-prep -yes
cd kun-oauth-admin
cd apps/api && go run ./cmd/migrate/main.go
go run ./cmd/migrate-users --kungal-dsn="host=127.0.0.1 port=5432 user=postgres password=kunloveren dbname=kungalgame" --moyu-dsn="host=127.0.0.1 port=5432 user=postgres password=renlovekun dbname=kungalgame_patch"
go run ./cmd/migrate-galgame
go run ./cmd/migrate-galgame-data --kungal-dsn="host=localhost port=5432 user=postgres password=kunloveren dbname=kungalgame"
go run ./cmd/migrate-moyu-galgame --moyu-dsn="host=localhost port=5432 user=postgres password=renlovekun dbname=kungalgame_patch"
go run ./cmd/dedup-galgame-alias/
# drop kungalgame redundancy tables and fields
cd kun-galgame-nuxt4
cd apps/api
go run cmd/migrate/main.go --only=005
# apply new galgame resource provider scan mechanisms
go run ./cmd/migrate --only=006
# migeate provider histories
go run ./cmd/backfill-provider-names
go run ./cmd/migrate --only=007
# drop kungalgame_patch redundancy tables and fields
cd kun-galgame-patch-next
cd apps/api
go run ./cmd/migrate -dir=up -only=001
go run ./cmd/migrate -dir=up
# remap patch id to galgame id
# get orphan patches: go run ./cmd/remap-patch-ids -dry-run -orphans-out=orphans.txt
go run ./cmd/remap-patch-ids
# optional sync vndb data
cd kun-oauth-admin
cd apps/api
# firstly sync full vndb data
go run ./cmd/sync-vndb/ --full
# delete invalid vndb id
go run ./cmd/cleanup-bogus-vndb-id
go run ./cmd/cleanup-bogus-vndb-id --delete
# sync tags, officials, etc.
go run ./cmd/sync-vndb-relations
# daliy cron job, incremental reincarnation
go run ./cmd/sync-vndb/
# image service
cd kun-oauth-admin
cd apps/api
# setup image service
go run ./cmd/image-setup --seed-test-client
# start image service
go run ./cmd/image
# galgame banner migrations
go run ./cmd/migrate-galgame-banners-to-image-service --client-id=kungal-test --client-secret=test-secret-dev --batch=100 --rps=20
其他问题
还有一些各种杂七杂八的问题
某些包没有安装
如果是在服务器上操作,至少要保证服务器上有 cmake, go, psql 等等环境
database has a collation version mismatch
在实际操作的时候可能碰到这种数据库版本不一致的警告
❯ psql -U postgres
psql (18.3)
Type "help" for help.
postgres=# \c kungalgame_patch;
WARNING: database "kungalgame_patch" has a collation version mismatch
DETAIL: The database was created using collation version 2.42, but the operating system provides version 2.43.
HINT: Rebuild all objects in this database that use the default collation and run ALTER DATABASE kungalgame_patch REFRESH COLLATION VERSION, or build PostgreSQL with the right library version.
You are now connected to database "kungalgame_patch" as user "postgres".
解决方案是这样的
postgres=# \c kungalgame_patch;
WARNING: database "kungalgame_patch" has a collation version mismatch
DETAIL: The database was created using collation version 2.42, but the operating system provides version 2.43.
HINT: Rebuild all objects in this database that use the default collation and run ALTER DATABASE kungalgame_patch REFRESH COLLATION VERSION, or build PostgreSQL with the right library version.
You are now connected to database "kungalgame_patch" as user "postgres".
kungalgame_patch=# REINDEX DATABASE kungalgame_patch;
WARNING: database "kungalgame_patch" has a collation version mismatch
DETAIL: The database was created using collation version 2.42, but the operating system provides version 2.43.
HINT: Rebuild all objects in this database that use the default collation and run ALTER DATABASE kungalgame_patch REFRESH COLLATION VERSION, or build PostgreSQL with the right library version.
REINDEX
kungalgame_patch=# ALTER DATABASE kungalgame_patch REFRESH COLLATION VERSION;
NOTICE: changing version from 2.42 to 2.43
ALTER DATABASE
这样就可以解决版本不一致的问题了,不会丢数据
清除 Meilisearch 的缓存
新项目用到了 Meilisearch,有时候需要删除缓存重新索引,这时候需要
sudo systemctl stop meilisearch
sudo rm -rf /var/lib/meilisearch/data.ms
sudo systemctl start meilisearch
sudo systemctl status meilisearch
之后重新索引
cd kun-oauth-admin
cd apps/api
go run ./cmd/reindex-search
部署指南
部署的时候采用 Docker,重构之后的项目需要注意下面的问题
go-webp
原来的项目使用 Node.js,使用的是 sharp 这个库,现在后端改成 GO Fiber 之后改为了 github.com/kolesa-team/go-webp 这个库
image service 是新项目一个独立的 service,单独跑一个端口和地址
image service 构建必须带 CGO + libwebp,生产部署镜像需 apt install libwebp-dev 并 CGO_ENABLED=1,否则 image service 无法运行
KunUI
KunUI / 鲲 UI 是一套专门为 鲲 Galgame / Kun Visual Novel 项目集群设计的 UI 框架,官方的描述是
Kun UI for Vue, Nuxt, React, Next.js, SolidJS, SolidStart — the most advanced UI framework with ultimate SSR support, ultra-low latency, no external packages, production-ready, helping you ship web apps faster.
目前来说 KunUI 在不断的迭代中,KunUI 的诞生是 鲲 Galgame 论坛初版,它的理念是尽量不依赖任何 npm packages,所以它在一开始就自研了一套 UI 框架
随着技术的不断迭代,这套 UI 框架也在不断的升级,同时随着 鲲 Galgame / Kun Visual Novel 的不断扩展,需要的技术栈也越多,KunUI 越来越有必要被作为一个专门的 UI 框架发布了
安装细节
目前(Version 0.1.1)版本来说,需要注意下面的细节
KunUI 目前只支持 Nuxt Layer 的形式安装(因为目前仅打算兼容 鲲 Galgame 下的项目),同时需要在项目根目录执行下面的安装以获得更好的体验
pnpm add -wD vue-tsc eslint-plugin-vuejs-accessibility
OAuth 与 鲲 Galgame 账户
目前的设计中,有些账户信息为了安全和代码简便考虑,必须由 OAuth 系统完成,而不能在 鲲 Galgame 论坛 / 鲲 Galgame 补丁完成
已存在,必须 OAuth-only
| 操作 | 端点 | 为什么 |
|---|---|---|
| 改邮箱 | /auth/email/send-code + /auth/email |
验证码寄到旧邮箱,劫持防御;流程敏感必须集中审计 |
| 改密码 | /auth/password |
账号所有权;需要旧密码或重置 token |
| 忘记密码 | /auth/password/forgot + /auth/password/reset |
匿名 + 邮件 token,OAuth 自己掌控令牌生成 |
OAuth 授权同意页(/oauth/authorize) |
OAuth 协议本身 | 必须在 IDP 上跑,否则无法做 PKCE |
已存在,但目前允许下游代理
| 操作 | 端点 | 备注 |
|---|---|---|
改 name / avatar / bio |
PATCH /auth/me |
展示层,下游 UI 体验更好;OAuth 后端做唯一性 / 长度校验兜底 |
| 上传头像 | POST /auth/me/avatar |
同上 |
未来如果加,必须 OAuth-only
| 未来功能 | 为什么必须 OAuth |
|---|---|
| 2FA 启用 / 关闭 / 备份码 | 强身份验证,IDP 唯一职责 |
| TOTP / WebAuthn 注册 | 涉及私钥 / 设备指纹,绝对不能跨站 |
| 登录历史 / 安全日志 | 跨站点 session 数据,只有 OAuth 有完整视图 |
主动下线某台设备 / 全部设备(撤销 refresh_token) |
跨 client 的 session 管理,下游各自只能看见自己那份 |
| 管理已授权 OAuth Client(类似 Google "Apps with access") | 元操作;下游无权管理别的下游的授权关系 |
| 绑定 / 解绑第三方登录(GitHub / Google 等) | 身份联邦,IDP 决定 |
| 注销账号 | 不可逆,需要冷静期 + 二次确认 + GDPR 数据导出,必须集中处理 |
| 账号数据导出(GDPR) | 需要聚合所有下游的数据;OAuth 是聚合点 |
修改 username(如果将来 name 变成不可变 handle + 单独的 display_name) |
全局唯一性 + 历史记录归属转移 |
| 账号封禁申诉 / 解封 | 身份恢复,必须能跨站点统一处理 |


看不懂,直接喂给ai解释了
(提示词:用人话解释内容并分析对不对)


