# STORY STUDIO 0.4 静态部署

编辑器服务器仅发送 HTML、JS、CSS 和教程文件。工程、素材、草稿、试走状态、目录授权都在用户电脑或浏览器中；无工作流 API、登录会话、上传、服务器工程缓存与导出目录。HTTP 传输本身会有短暂缓冲，Nginx / NPM 仍可能产生访问日志，这与保存剧情内容不同。

## 构建与文件

在编辑器源码目录执行 `python tools/build.py`，得到两个独立包：

- `dist/story-studio-0.4.0.zip`：纯静态部署包。解压后目录根就是 index.html。
- `dist/story-studio-local-0.4.0.zip`：可选本地工具包，含静态启动器与 Python CLI，供本地 Codex / 终端使用。不要将本地工具包作为公网网站根目录。

静态版无需 Python、Node 或数据库。网站从域名根目录 `/` 提供，不支持直接双击 file:// 或部署到子路径。

## Nginx Proxy Manager + Nginx

将静态包内容放在服务器 `/opt/story-studio/site/`，确认存在 `/opt/story-studio/site/index.html`。以下示例假设 NPM 所在 Docker 网络叫 `npm_default`，实际名称以自己的部署为准。

```yaml
services:
  story-studio:
    image: nginx:stable-alpine
    restart: unless-stopped
    volumes:
      - /opt/story-studio/site:/usr/share/nginx/html:ro
      - /opt/story-studio/default.conf:/etc/nginx/conf.d/default.conf:ro
    networks:
      - npm
networks:
  npm:
    external: true
    name: npm_default
```

`default.conf`：

```nginx
server {
    listen 80;
    server_name _;
    root /usr/share/nginx/html;
    index index.html;
    access_log off;
    add_header X-Content-Type-Options nosniff always;
    add_header Referrer-Policy same-origin always;
    add_header Cache-Control "no-cache" always;
    location / {
        try_files $uri $uri/ =404;
        limit_except GET { deny all; }
    }
}
```

1. 执行 `docker compose up -d`。
2. NPM 新建 Proxy Host：域名填编辑器域名，Scheme 选 http，Forward Hostname 填 `story-studio`，Forward Port 填 `80`。
3. SSL 页申请证书并开启 Force SSL。目录授权 API 要求 HTTPS 或 localhost；公网 HTTP 不满足要求。
4. 如需限制谁能加载编辑器，使用 NPM Access List。编辑器自身不再有访问口令和登录 Cookie。
5. 浏览器访问域名，打开“章节库”选择本机仓库或使用浏览器章节库。这里的目录是访问者电脑上的目录，不是服务器目录。

Nginx 服务无须挂载章节仓库、开放上传接口或增加媒体上传体积限制。NPM 自己的访问日志配置独立于上面的 `access_log off`；如不需要请求日志，应另行在 NPM 的日志策略中处理。

## 本地运行

源码 / 本地工具包目录执行 `python server.py --port 8790`，或 Windows 执行 `./start.ps1`，Linux 执行 `sh start.sh`。打开 `http://127.0.0.1:8790/`。`server.py` 仅提供静态文件，默认监听本机；不再接受 `--workspace`、token 或 API 参数。

Python `studio.py --workspace REPO_PATH ...` 仍可直接操作本地目录，作为可选 CLI。它不是远程接口，会在该本机仓库产生 `.studio/` 历史与导出文件。浏览器与 CLI / Git 不应同时写同一章节；操作后重新打开章节。

## 从 0.3 升级

1. 先确认旧编辑器显示已保存，保留原 `story-chapters` 仓库与 Git 数据。
2. 停止旧 Python API 服务，部署新的纯静态包。不要继续通过 NPM 转发到旧服务端口。
3. 本机目录模式：章节库 → 打开 / 新建本机仓库 → 选择原 `story-chapters` 根目录。若内置浏览器不支持目录授权，使用 Chrome / Edge，或兼容模式。
4. 浏览器模式：逐章“导入工程目录”。主线与回忆录都要导入同一浏览器库，首次导入保持原章 ID，才能保留跨章跳转。
5. 原章节不会自动删除或迁移到服务器。旧服务的浏览器试走存档 key 保留，0.4 按工作空间建立新试走存档；主题与布局继续沿用。

浏览器存储以域名、协议、端口和浏览器配置文件隔离。更换域名 / 端口不会自动迁移章节。隐私模式、清站点数据或配额不足可能丢失浏览器副本，请导出完整工程包；本机模式优先用 Git 保存配置与素材。

## 导出与故障恢复

普通下载包上限 512 MiB；支持 File System Access 的浏览器可点“直接保存 ZIP”分块写入磁盘，避免完整包占用内存。当前 ZIP32 包必须小于 4 GiB；超限时明确拒绝，不生成截断文件。可分章节工程导出，客户端包可只导出配置，再按其引用路径人工复制素材。

目录多文件写入不是全局原子操作。每次写入前，在 IndexedDB 保留本次受影响文件的前后版本；中断后写入保护阻止继续覆盖。章节库 → 草稿与写入恢复 → 下载前后文件包，在工程副本中核对 RECOVERY.json 里的受影响 / 存在文件清单，再修复目录并解除保护。它们是恢复用的变更文件包，不是完整工程包。一般编辑另有自动草稿；仅基线版本一致时允许恢复到编辑区，否则先下载 JSON 手工合并。
