151 lines
11 KiB
Markdown
151 lines
11 KiB
Markdown
# Endor · Tabularium
|
||
|
||
Endor 的文档站与 AI 公司研究工作台,包含文档阅读、全文搜索、研究数据展示和制图工具。使用 Next.js Pages Router、React、TypeScript 与 Tailwind CSS;JavaScript workspace 使用 pnpm,制图 Python 项目使用 uv。
|
||
|
||
## 代码与内容放在哪里
|
||
|
||
文档正文、目录元数据和修订记录由站点 SQLite 数据库管理,日常写作直接更新数据库,无需提交代码、构建或部署。研究业务数据仍沿用版本化 JSON 导入机制,后续单独迁移。
|
||
|
||
| 内容 | 权威来源与维护方式 |
|
||
| --- | --- |
|
||
| 文档正文、分类、合集、分组、摘要、草案和推荐状态 | 数据库;通过服务器上的 `docs` 管理工具读写 |
|
||
| 文档旧地址与修订历史 | 数据库;改名保留别名,修改追加修订 |
|
||
| AI 公司、观测、证据、候选与核查记录 | `content/research` 中的版本化快照;服务端显式按版本导入同库后查询 |
|
||
| 页面、组件、管理工具和部署逻辑 | 本仓库,通过工作分支与 PR 评审 |
|
||
| 图形源码与静态资源 | `tools/figures` 与 `apps/docs/public`;生成步骤在远程 Runner 执行 |
|
||
|
||
以上数据库数据共用 `AUTH_CONFIG_FILE` 同目录下的 `login-state.sqlite`,该文件名沿用历史命名。生产环境挂载到容器 `/auth`,不随镜像替换。文档使用 `documents`、`document_aliases`、`document_revisions`、`document_imports` 表,研究数据使用 `research_*` 表,登录状态使用 `login_state` 表。
|
||
|
||
仓库不接收新的文档正文 Markdown、目录 JSON、数据库文件或日常正文快照。历史 Git 正文仅用于一次性迁移;运行时不读取 `content/docs` 或 `content/catalog.json`。README 维护程序使用与运维约定,研究个案、统计数量与内容更新日志在工作台和数据库文档中查看。
|
||
|
||
## 阅读与访问
|
||
|
||
首页、阅读页、目录及全文搜索按请求读取数据库,内容更新后刷新即可看到。旧文件式地址和改名前的语义地址继续跳转到当前地址,并保留查询参数。
|
||
|
||
- 文档原文:`GET /api/documents/source?slug=<文档地址>`。
|
||
- 全文搜索:`GET /api/search`。
|
||
- 研究工作台:`/docs/other-research/ai-company-research/overview`。
|
||
- 收入样本:`/docs/other-research/ai-company-research/income-snapshot`。
|
||
- 覆盖与缺项:`/docs/other-research/ai-company-research/coverage`。
|
||
|
||
正文、搜索、研究 API 与静态资料均经过站点登录认证,私有响应使用 `private, no-store`。Markdown 支持 GFM 表格,不解析原始 HTML;正文图片写入时检查压缩格式。草案标记用于展示状态,不构成单独的访问权限。
|
||
|
||
## 管理文档
|
||
|
||
部署后,管理员可在服务器上使用 `/opt/endorphin-tabularium-docs/docs`。该工具在当前容器中操作数据库,需要服务器运维权限;站点没有公开的文档写入 API。
|
||
|
||
```sh
|
||
sudo /opt/endorphin-tabularium-docs/docs list
|
||
sudo /opt/endorphin-tabularium-docs/docs get endor/endor-purpose-draft
|
||
sudo /opt/endorphin-tabularium-docs/docs history 04-endor-purpose-draft
|
||
```
|
||
|
||
`save` 从标准输入接收完整 JSON。必填字段如下:
|
||
|
||
| 字段 | 用途 |
|
||
| --- | --- |
|
||
| `slug` | 语义化公开地址,不含数字章节前缀 |
|
||
| `sourceSlug` | 稳定标识;修改公开地址时保持不变 |
|
||
| `title`、`content` | 标题与 Markdown 正文 |
|
||
| `category`、`collection`、`group` | 分类、合集与目录分组 |
|
||
| `description`、`draft`、`featured` | 摘要、草案状态与推荐状态 |
|
||
| `revision` | 新建传 `0`;修改传最近一次读取到的版本号 |
|
||
|
||
修改现有文档的流程:
|
||
|
||
```sh
|
||
umask 077
|
||
doc_work_dir=$(mktemp -d)
|
||
sudo /opt/endorphin-tabularium-docs/docs get endor/endor-purpose-draft > "$doc_work_dir/document.json"
|
||
# 编辑该私有 JSON 文件,保留读取到的 revision 和 sourceSlug。
|
||
sudo /opt/endorphin-tabularium-docs/docs save < "$doc_work_dir/document.json"
|
||
```
|
||
|
||
保存成功后,正文、目录和搜索通过后续请求读取新内容。发生版本冲突时重新读取并合并修改,不能仅改大 `revision` 覆盖并发编辑。调整分类或分组也走同一保存流程;`history` 使用稳定的 `sourceSlug` 查询修订。
|
||
|
||
## 研究数据与检查
|
||
|
||
研究工作台提供公司筛选、经营指标、原始证据、收费与交付模式、技术材料及核查记录。它区分公司披露、支付平台指标、第三方估算、融资和客户收益;未知收入不填零,材料可访问也不代表性能或商业效果已经验证。研究范围、样本限制和个案结论以工作台记录为准。
|
||
|
||
| 仓库资料 | 用途 |
|
||
| --- | --- |
|
||
| `content/research/ai-companies.seed.json` | 研究数据导入快照;更新必须更换 `version` |
|
||
| `content/research/ai-companies.sources.json` | 来源范围、用途、覆盖边界与后续缺项 |
|
||
| `content/research/ai-companies.coverage.json` | 候选池逐条筛选台账 |
|
||
| `content/research/ai-income-analysis.json` | 独立复算的统计参考快照 |
|
||
|
||
服务端以事务导入未载入的版本,保留旧研究版本与登录、文档数据;同一版本标识下内容变化会拒绝导入。页面和 `GET /api/research/ai-companies` 从数据库读取对应研究版本。回退程序可能选择旧研究版本,不能等同于撤销数据库中的正文编辑。
|
||
|
||
以下 Python 检查不触发编译或构建,可在工作分支执行:
|
||
|
||
```sh
|
||
PYTHONDONTWRITEBYTECODE=1 python3 scripts/audit-ai-research.py --check
|
||
PYTHONDONTWRITEBYTECODE=1 python3 scripts/summarize-ai-income.py --check
|
||
```
|
||
|
||
若需对照研究数据检查报告正文,先用 `docs export` 导出当前文档,再给对应脚本传入 `--document-export <导出文件>`。默认 `--check` 核对研究数据的统计与审计不变量,不将历史迁移快照当作当前正文。脚本不带参数时仅在 `.artifacts/reports` 生成候选正文,需审阅后通过 `docs save` 写入数据库。
|
||
|
||
## 备份与首次迁移
|
||
|
||
```sh
|
||
sudo /opt/endorphin-tabularium-docs/docs backup /auth/manual-backup.sqlite
|
||
sudo /opt/endorphin-tabularium-docs/docs export /auth/current-documents.json
|
||
```
|
||
|
||
路径在容器内,输出文件已存在时拒绝覆盖。`backup` 是整个共享 SQLite 数据库的一致性备份,包含登录状态、研究数据、正文、别名和修订;`export` 只保存当前正文与目录,供空库初始化或外部迁移使用,不包含完整修订历史。认证配置单独保存在 `/auth/config.json`,整库备份不包含该配置文件。备份与导出应保存在私有挂载或受控备份位置。
|
||
|
||
首次迁移由 `scripts/export-legacy-documents.py` 从固定历史版本导出正文和目录,基线与研究正文覆盖版本在脚本中明确记录。导出写入 Git 忽略目录,权限为 `0600`,不进入生产镜像:
|
||
|
||
```sh
|
||
python3 scripts/export-legacy-documents.py --output .artifacts/documents-migration.json
|
||
```
|
||
|
||
该命令用于迁移准备,不是日常写作入口;目标文件存在时拒绝覆盖。部署先备份共享数据库,再用 `import --if-empty` 向空文档表事务导入。已有文档时跳过,不覆盖后续编辑;导入失败整体回滚并中止部署。`--ref` 仅用于明确选择历史导出版本。
|
||
|
||
程序回退不会撤销数据库编辑;回退到旧文件式站点则会显示旧正文。完整数据库恢复会同时影响登录、研究和文档状态,需先停止写入、保留当前备份,再明确选择恢复点。部署脚本只回退镜像,不自动恢复数据库。
|
||
|
||
## 登录管理
|
||
|
||
站点使用共享验证器的 6 位 TOTP 动态码,每 30 秒更新。会话使用 HttpOnly、SameSite=Lax Cookie,有效期 7 天;共享尝试上限为每 5 分钟 20 次,重放与限流状态在数据库中持久保存。缺少或损坏认证配置时拒绝私有访问。
|
||
|
||
```sh
|
||
sudo /opt/endorphin-tabularium-docs/auth qr
|
||
sudo /opt/endorphin-tabularium-docs/auth verify
|
||
```
|
||
|
||
认证配置和数据库位于服务器 `/opt/endorphin-tabularium-docs/private-auth`。正常部署保留验证器与会话签名密钥。`qr` 只在交互终端显示,`qr-png` 可导出到私有文件;只有 `auth rotate --confirm` 会轮换密钥并使旧会话失效。二维码和令牌不进入仓库、网页或 CI 日志。
|
||
|
||
当前 Compose 配置默认 `AUTH_COOKIE_SECURE=false`;实际采用 HTTPS 时,应在独立的生产配置中设置为 `true`。HTTP 不加密动态码与会话传输。生产部署使用无副作用的 `verify`,不执行会消耗动态码和触发限流的 `exercise`。
|
||
|
||
## 开发、验证与发布
|
||
|
||
代码依赖要求见 `package.json` 和锁文件;当前要求 Node.js 22.13+、pnpm 11.25.0,制图使用 Python 与 uv。构建、打包、制图及会隐式编译的检查只在已确认的 `ces-control` Runner 执行,本机不执行这些步骤。
|
||
|
||
工作分支完成轻量检查后推送并创建 PR,由用户手动合并。**CI 仅在 main 推送或针对 main 的手动运行时执行,工作分支和 PR 不运行 CI。** 不自动合并,也不因确认 Runner 而扩大触发范围。
|
||
|
||
主线通过 `.gitea/workflows/ci-deploy.yml` 执行 `scripts/ci.py`:
|
||
|
||
1. 检查研究统计、审计与 Python 测试,生成首次迁移所需的历史导出。
|
||
2. 根据程序、研究快照、图形、锁文件和构建脚本计算内容指纹。命中 verified 镜像时复用,否则安装依赖并执行 lint、类型检查、数据库测试、图形检查与构建。
|
||
3. 使用隔离数据库卷核对完整迁移、认证、全部文档与资源,以及不重建内容更新和重启持久化;通过后标记镜像为 verified。
|
||
4. `scripts/deploy.py` 确认仍为最新 main,备份并初始化文档数据,使用 `--no-build` 部署;失败时回退上一版镜像。
|
||
|
||
`pnpm check`、`pnpm typecheck`、`pnpm test:auth`、`pnpm test:research`、`pnpm test:docs`、`pnpm figures`、`pnpm build` 和 `pnpm dev` 等命令涉及编译、构建或产物生成,不在本机运行。图形源码与生成资源保持可复现,前端继续使用 Pages Router。
|
||
|
||
根 README 等非构建输入变更不要求重新构建;数据库正文和目录更新也不触发构建。保留 pnpm、uv、Next.js 与 SWC 缓存,不清理共享 Docker 缓存或卷,不修改共享 Runner 或其他项目。
|
||
|
||
## 部署位置与仓库
|
||
|
||
| 项目 | 位置或默认值 |
|
||
| --- | --- |
|
||
| Compose 项目 | `endorphin-tabularium-docs` |
|
||
| 容器监听 | `0.0.0.0:3000` |
|
||
| 服务器入口 | 默认端口 `18135`,由生产配置决定 |
|
||
| 生产配置 | `/etc/endorphin-tabularium-docs/production.env` |
|
||
| 发布记录与当前版本 | `/opt/endorphin-tabularium-docs/releases/<commit>` 与 `current` |
|
||
| 健康检查 | `/api/health` |
|
||
|
||
服务入口使用 `TABULARIUM_BIND`、`TABULARIUM_PORT` 配置。部署前检查端口是否空闲或属于本服务,不停止其他服务抢占端口;本项目不自动修改防火墙、域名或反向代理。
|
||
|
||
仓库:[endorphin-tabularium-docs](https://gitea.entroia.com/Zayden-Jung/endorphin-tabularium-docs)。Git 操作仅使用 `codex-bot` 专用 SSH 身份与仓库级提交配置;Actions 检出使用 Gitea 内置任务令牌且不保存凭据。
|