Merge remote-tracking branch 'origin/master' into editor-agent-refactored

This commit is contained in:
2026-07-17 16:26:57 +08:00
23 changed files with 106 additions and 69 deletions
+2 -1
View File
@@ -78,7 +78,7 @@ Best practices:
- Avoid overlapping queries that duplicate row delivery.
- Use indexes for subscribed filters.
## 2.2.0 to 2.6.0 Delta
## 2.2.0 to 2.6.1 Delta
Genarrative introduced SpacetimeDB around 2.2.0. Important changes since then:
@@ -88,6 +88,7 @@ Genarrative introduced SpacetimeDB around 2.2.0. Important changes since then:
- **2.4.1**: Rust and TypeScript procedural views can declare primary keys, enabling `OnUpdate` events for subscribed views; fixed index schema from ST tables.
- **2.5.0**: procedures are stable, C# procedural views gain primary keys, event tables allow broader layout-altering automigrations, BTreeSet storage makes row insertion deterministic and avoids accidentally quadratic bulk insert behavior, `wasm_memory_bytes` billing metric semantics changed, template version constraints unified, `publish --delete-data` config fallback fixed, CLI `call` accepts hex Identity arguments.
- **2.6.0**: procedural-view primary keys are available across Rust, TypeScript, and C#, commitlog gains `max_segment_size` / `write_buffer_size` / `preallocate_segments`, the default write buffer increases for throughput, event-table automigrations improve, and CLI binary distribution expands.
- **2.6.1**: procedure contexts again receive the caller `Identity` and `ConnectionId`; generated TypeScript `Option<T>` fields use optional keys; `spacetime init --template` lists available templates when no template argument is supplied.
## Debugging Checklist
+2 -2
View File
@@ -57,7 +57,7 @@ Linux Docker Engine 若要从宿主机 CLI 连到容器内服务,直接用 `ht
## 构建工具链
`api-server` 容器镜像只构建 Linux release API 二进制,不构建 `spacetime-module`。当前 `api-server -> spacetime-client -> spacetimedb-sdk 2.6.0` 依赖链要求 Rust 1.93,因此 `deploy/container/api-server.Dockerfile` 的 Rust builder 固定为 `rust:1.93-bookworm`。镜像构建阶段会同时复制 `public/`,用于满足 API 二进制里 `include_bytes!` 引用的内置素材;不要把 `public/generated-*` 放入镜像上下文。如果本机 Docker Hub 拉取失败,可以先在本机准备同名本地 builder 镜像,但不要把临时 bootstrap 容器或私有 registry 凭据写入仓库。
`api-server` 容器镜像只构建 Linux release API 二进制,不构建 `spacetime-module`。当前 `api-server -> spacetime-client -> spacetimedb-sdk 2.6.1` 依赖链要求 Rust 1.93,因此 `deploy/container/api-server.Dockerfile` 的 Rust builder 固定为 `rust:1.93-bookworm`。镜像构建阶段会同时复制 `public/`,用于满足 API 二进制里 `include_bytes!` 引用的内置素材;不要把 `public/generated-*` 放入镜像上下文。如果本机 Docker Hub 拉取失败,可以先在本机准备同名本地 builder 镜像,但不要把临时 bootstrap 容器或私有 registry 凭据写入仓库。
## 启动与验证
@@ -127,7 +127,7 @@ npm run container:worker-smoke -- status
npm run container:worker-smoke -- smoke --force
```
`container:worker-smoke` 默认会把本机 `spacetime` 2.6.0 CLI 打成轻量 SpacetimeDB 镜像,避免首次 smoke 必须拉取官方大镜像;普通 `npm run container:*` 压测默认使用 `clockworklabs/spacetime:v2.6.0`。如果 Docker build 阶段在容器内拉取 crates.io 依赖不稳定,可让容器内 Cargo 复用本机 Cargo 缓存构建当前二进制,再打入临时 smoke 镜像。该模式默认使用 `rust:1.93-bookworm` 作为 builder、Debian bookworm smoke runtime 承载构建产物;需要换 builder 镜像时设置 `GENARRATIVE_WORKER_SMOKE_CARGO_IMAGE`,需要换运行时基础镜像时设置 `GENARRATIVE_WORKER_SMOKE_LOCAL_BASE_IMAGE`
`container:worker-smoke` 默认会把本机 `spacetime` 2.6.1 CLI 打成轻量 SpacetimeDB 镜像,避免首次 smoke 必须拉取官方大镜像;普通 `npm run container:*` 压测默认使用 `clockworklabs/spacetime:v2.6.1`。如果 Docker build 阶段在容器内拉取 crates.io 依赖不稳定,可让容器内 Cargo 复用本机 Cargo 缓存构建当前二进制,再打入临时 smoke 镜像。该模式默认使用 `rust:1.93-bookworm` 作为 builder、Debian bookworm smoke runtime 承载构建产物;需要换 builder 镜像时设置 `GENARRATIVE_WORKER_SMOKE_CARGO_IMAGE`,需要换运行时基础镜像时设置 `GENARRATIVE_WORKER_SMOKE_LOCAL_BASE_IMAGE`
```bash
npm run container:worker-smoke -- smoke --local-binary
+1 -1
View File
@@ -2,7 +2,7 @@ name: genarrative-container-loadtest
services:
spacetimedb:
image: ${GENARRATIVE_CONTAINER_SPACETIME_IMAGE:-clockworklabs/spacetime:v2.6.0}
image: ${GENARRATIVE_CONTAINER_SPACETIME_IMAGE:-clockworklabs/spacetime:v2.6.1}
user: root
command:
[
@@ -149,6 +149,14 @@
- 验证方式:核对 `spacetime --version`,运行 `npm run spacetime:generate``npm run check:spacetime-schema``cargo check` / 定向测试、`npm run test -- scripts/dev.test.ts`、server provision 工具测试、production ops / encoding / diff 门禁。
- 关联文档:`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md``docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`
## 2026-07-17 SpacetimeDB 工具链统一升级到 2.6.1
- 背景:SpacetimeDB 2.6.1 修复 procedure context 中调用者 `Identity` / `ConnectionId` 丢失问题,并修正 TypeScript 生成代码中 `Option<T>` 字段的可选键语义;继续运行 2.6.0 会保留已知 procedure 身份回归。
- 决策:`server-rs/Cargo.toml``spacetimedb``spacetimedb-sdk``spacetimedb-lib` 精确锁定 2.6.1;本地 CLI / standalone、Rust bindings、worker smoke、容器压测镜像和生产 provision 下载根同步对齐 2.6.1。
- 影响范围:Rust workspace lockfile、SpacetimeDB bindings、本地 dev 版本门禁、容器 smoke / loadtest、server provision Jenkins 与项目 SpacetimeDB skills / 文档。
- 验证方式:核对 `spacetime --version`,运行 `npm run spacetime:generate``npm run check:spacetime-schema``cargo check` / 定向测试、server provision 工具测试、encoding / diff 门禁。
- 关联文档:`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md``docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`
## 2026-07-10 外部生成任务只持久化轻量媒体引用并独立维护摘要投影
- 背景:编辑器 worker 化后直接把同步接口 payload 序列化进 `external_generation_job.request_payload_json`;前端又把已有 OSS `objectKey` 下载成 Data URL 再提交,导致单个任务 JSON 膨胀到数 MB,正式任务列表读取 20 条任务时同时搬运约 65 MB payload,并放大为 SpacetimeDB 与 api-server 的瞬时内存峰值。此前“禁止 Data URL 持久化”只覆盖工程、素材、图层和元数据,遗漏了正式生成任务表。
@@ -3149,3 +3149,11 @@
- 处理:latest snapshot 必须是未锁定且存在同 offset `.snapshot_bsatn` 的完整目录,空目录或同名 `.lock` 存在时忽略。每个 replica 独立保留 `max(segment_start <= latest_snapshot)` 及全部后缀,只处理更早 segment 对;旧 snapshot 只保留最新一个。`--storage-format files` 必须先发布完整 full cataloghistory 对每个候选文件 CAS 对象、history catalog 和 full catalog 执行 HEAD 长度/SHA 验真,再复算边界与 stat fingerprint,最后发布并验真固定 `latest.json`pointer 失败时不得推进 state 或删除源文件。不要把在线逐文件 full 扫描当成跨文件一致备份,基线必须来自停库目录或已验证冻结副本。SSH 或工具超时后先检查 work-dir PID lock 与原进程,不要直接并发重跑;不要在 history 模式传 `--stop-service`。定时任务通过 Server-Provision 的显式 profile 和仓库 drop-in 管理,启用前 dry-run 验证 baseline,切回 archive 时同时移除托管与现场遗留 drop-in;不要在 `/etc/systemd/system` 长期保留手写覆盖,release 必须建立和验证自己的 full baseline 与 work-dir,不能直接复用 dev 的本地 state。
- 验证:dry-run 输出 replica 的 `latestSnapshot``boundarySegment` 和候选清单;从另一台机器仅凭 OSS `latest.json` 自动定位 full catalog,创建目录、下载文件并逐项校验长度/SHA,启动隔离 data-dir 验证 `/v1/ping`、snapshot restore、commitlog replay、module launch、代表性 SQL 与 reducer。
- 关联:`scripts/database-backup-to-oss.mjs``scripts/check-database-backup-to-oss.mjs``docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`
## Procedure 事务鉴权要兼容 SpacetimeDB 2.6.0 的匿名 TxContext
- 现象:api-server 的 SpacetimeDB token identity 与 `editor_generation_pricing_config.writer_identity` 完全一致,服务启动门禁也通过,但手动拆分图集调用 `find_editor_asset_group_source_and_return` 仍返回“当前 identity 无权调用模型生成运行时服务”。
- 原因:SpacetimeDB 2.6.0 的 `ProcedureContext::try_with_tx` 使用内部匿名事务上下文,闭包参数 `TxContext` 解引用得到的 `ReducerContext::sender()` 固定为 `Identity::ZERO`,不是 procedure 外层调用者。把 runtime writer 鉴权写成 `require_*(tx, tx.sender())` 会稳定误拒绝合法服务 identity。SpacetimeDB 2.6.1 已修复为向事务透传 procedure caller,但尚未升级的 dev / release 模块仍受 2.6.0 行为影响。
- 处理:在调用 `try_with_tx` 前通过 `let caller = ctx.sender()` 捕获真实调用者,再把 `caller` 显式传入事务函数;迁移、后台账号、runtime profile、外部生成等现有 procedure 已采用这一模式。`npm run check:spacetime-runtime-access` 禁止编辑器 runtime writer 鉴权重新直接读取事务 `ctx.sender()`。运行环境升级到 2.6.1 后继续保留显式 caller,避免鉴权依赖 SDK 版本细节。
- 验证:运行 `npm run check:spacetime-runtime-access``cargo test -p spacetime-module --manifest-path server-rs/Cargo.toml``npm run check:spacetime-schema`;发布使用 SpacetimeDB 2.6.1 构建的新模块后,以 runtime writer identity 重试 `POST /api/editor/icon-spritesheets/slices`,确认来源查询、分片素材写入与 cohort 完成不再返回 identity 403。
- 关联:`server-rs/crates/spacetime-module/src/editor_project_storage.rs``scripts/check-spacetime-runtime-access.mjs``docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`
@@ -1,6 +1,6 @@
# Genarrative 项目共享概览
更新时间:`2026-06-23`
更新时间:`2026-07-17`
## 一句话定位
@@ -36,7 +36,7 @@ Genarrative / 陶泥儿是一个 AI 原生互动内容与小游戏平台,把 A
server-rs + Axum + SpacetimeDB
```
当前 SpacetimeDB crate、SDK、CLI / standalone、生成 bindings 和容器压测镜像统一按 `2.6.0` 对齐;遇到版本不匹配时先升级到 `server-rs/Cargo.toml` 锁定版本,升级后重启对应 SpacetimeDB 进程再重试。
当前 SpacetimeDB crate、SDK、CLI / standalone、生成 bindings 和容器压测镜像统一按 `2.6.1` 对齐;遇到版本不匹配时先升级到 `server-rs/Cargo.toml` 锁定版本,升级后重启对应 SpacetimeDB 进程再重试。
职责边界:
@@ -1,6 +1,6 @@
# server-rs 与 SpacetimeDB 数据契约
更新时间:`2026-07-03`
更新时间:`2026-07-17`
## 后端主线
@@ -16,7 +16,7 @@ server-rs + Axum + SpacetimeDB
`server-rs/Cargo.toml` 是 workspace 事实源。默认构建成员为 `crates/api-server`;第三方依赖版本和 workspace 内 crate path 统一放在 `[workspace.dependencies]`
SpacetimeDB 版本口径:当前 Rust crate `spacetimedb``spacetimedb-sdk``spacetimedb-lib` 统一锁定 `2.6.0`;本地 `spacetime` CLI / standalone、生成的 `spacetime-client` bindings 和容器压测镜像也必须与 `server-rs/Cargo.toml` 锁定版本对齐,避免 BSATN / procedure result 反序列化错配。遇到版本不匹配时,不继续沿着业务超时排查,先把 CLI / standalone 直接升级到锁定版本并重启后再重试。
SpacetimeDB 版本口径:当前 Rust crate `spacetimedb``spacetimedb-sdk``spacetimedb-lib` 统一锁定 `2.6.1`;本地 `spacetime` CLI / standalone、生成的 `spacetime-client` bindings 和容器压测镜像也必须与 `server-rs/Cargo.toml` 锁定版本对齐,避免 BSATN / procedure result 反序列化错配。遇到版本不匹配时,不继续沿着业务超时排查,先把 CLI / standalone 直接升级到锁定版本并重启后再重试。2.6.1 还修复了 procedure context 中调用者 `Identity` / `ConnectionId` 丢失问题,因此依赖调用者身份的 procedure 不得继续运行在 2.6.0 standalone 上。
当前主要 crate
@@ -178,7 +178,8 @@ npm run check:server-rs-ddd
7. 面向公开列表的只读投影优先做成 public view / public 读模型表,并由 `api-server``spacetime-client` 长期订阅后读本地 cache。跨玩法公开作品统一主读模型是 `public_work_gallery_entry``public_work_detail_entry`;公开作品资产读取授权投影是 `public_work_asset_read_grant`;各玩法既有 `*_gallery_card_view` / `*_gallery_view` / `custom_world_gallery_entry` 保留为 source view 和兼容路径。短期不把作品列表整体交给浏览器前端直接订阅;不要让 HTTP 列表接口每次请求都调用 procedure 重新组装全量列表。需要请求时间窗口的轻量统计可订阅 `public_work_play_daily_stat` 后在 `api-server` 本地聚合,需要写入副作用的详情、点赞、游玩记录仍走玩法 procedure / reducer。前端不得直接订阅 `puzzle_work_profile``custom_world_profile` 等领域源表,也不得自己做 join、聚合或权限逻辑。首屏、排序、字段归一、权限降级和 HTTP fallback 由 `api-server` BFF 维持。
8. 多列索引按 SpacetimeDB 绑定生成的元组参数直接传入,例如 `.filter((source_type, profile_id, played_day))`;前缀查询只传前缀元组,例如 `.filter((scope_kind, scope_id.as_str()))`。不要为了绕过类型问题退回整表遍历。
9. procedure result 必须返回 typed snapshot / typed value。`spacetime-client` mapper 不得再通过 `row_json/session_json/work_json/items_json/run_json/event_json/feedback_json: Option<String>` 做跨层 JSON 字符串传输,也不得在 mapper 里反序列化旧 `*JsonRecord` 兼容结构。业务内部持久化字段如 `profile_payload_json``levels_json` 等不属于 procedure result 载荷例外,仍按各自表契约处理。
10. 修改后运行:
10. procedure 需要按调用者 identity 鉴权时,必须先从外层 `ProcedureContext::sender()` 捕获 caller,再把 caller 显式传入 `try_with_tx` 闭包内的事务函数。SpacetimeDB 2.6.0 的 `TxContext` 使用内部匿名事务身份,`tx.sender()` 固定为 `Identity::ZERO`2.6.1 已向事务透传 procedure caller,但项目仍保持显式 caller 参数,兼容尚未升级的运行环境并让鉴权边界不依赖 SDK 隐式语义。
11. 修改后运行:
```bash
npm run spacetime:generate
@@ -563,14 +564,14 @@ npm run check:server-rs-ddd
- Rust 结构体:`EditorAssetGroupSourceProvenance`
- 源码:`server-rs/crates/spacetime-module/src/editor_project_storage.rs`
- 说明:手动图集拆分的私有可信来源索引。仅当账号素材由后端生成链路写入且具有正式 `source_resource_id` 时,按 owner + source resource、asset object 和 Object Key 记录真实来源 `task_id`;普通素材 / 资源创建请求不能直接写该表。跨项目复用素材后可通过稳定媒体引用找回原任务,历史行首次扫描命中后补写索引。
- 说明:手动图集拆分的私有可信来源索引。仅当账号素材由后端生成链路写入且具有正式 `source_resource_id` 时,按 owner + source resource、asset object 和 Object Key 记录真实来源 `task_id`;普通素材 / 资源创建请求不能直接写该表。跨项目复用素材后可通过稳定媒体引用找回原任务,历史行首次扫描命中后补写索引。该持久表纳入 `migration_tables!` 导入导出清单,数据库迁移与恢复不得遗漏来源归组事实。
- 主键:`lookup_key`
### `editor_asset_group_cohort`
- Rust 结构体:`EditorAssetGroupCohort`
- 源码:`server-rs/crates/spacetime-module/src/editor_project_storage.rs`
- 说明:手动拆分批次的私有完成事实。api-server 只有在预期的全部 asset ID 已成功落库并由 runtime service identity 逐行校验 owner、真实 task、归组 task 和预期数量一致后才能插入;事实写入后不随用户删除单片素材而撤销。没有完成事实的现代批次不能并入来源根任务。
- 说明:手动拆分批次的私有完成事实。api-server 只有在预期的全部 asset ID 已成功落库并由 runtime service identity 逐行校验 owner、真实 task、归组 task 和预期数量一致后才能插入;事实写入后不随用户删除单片素材而撤销。没有完成事实的现代批次不能并入来源根任务。该持久表纳入 `migration_tables!` 导入导出清单,数据库迁移与恢复必须保留不可逆批次完成事实。
- 主键:`cohort_id`
### `editor_showcase_asset`
@@ -1,6 +1,6 @@
# 本地开发验证与生产运维
更新时间:`2026-07-15`
更新时间:`2026-07-17`
## 标准开发流程
@@ -147,7 +147,7 @@ spacetime sql <database> "SELECT * FROM puzzle_gallery_card_view LIMIT 1" --serv
本地 `npm run dev:spacetime` 发布模块时必须显式忽略仓库根目录的 `spacetime.json`,由脚本固定追加 `--no-config` 并使用命令参数里传入的数据库名和 `--server http://127.0.0.1:3101`。否则 CLI 可能把发布目标改写到配置文件里的其他数据库,导致 `dev:spacetime` 启动后又因发布失败自动退出,浏览器随后会在 `ws://127.0.0.1:3101/v1/database/.../subscribe` 看到连接拒绝。
本地 `spacetime` CLI / standalone 版本必须和 `server-rs/Cargo.toml` 里锁定的 `spacetimedb` 版本一致;当前统一版本为 `2.6.0`。若版本错配,procedure 返回值可能在宿主侧触发 `Failed to BSATN deserialize procedure return value`api-server 最终表现为敲木鱼等创作动作的 `SpacetimeDB procedure 调用超时`。排障时先运行 `spacetime --version`,再对照 `server-rs/Cargo.toml``spacetimedb = "..."`;遇到版本不匹配时不要继续深挖业务超时,直接执行 `spacetime version install <version> && spacetime version use <version>`,或在目标就是最新版本时执行 `spacetime version upgrade`,升级后重启 `npm run dev:spacetime` 再重试。当前 `scripts/dev.mjs` 会在启动和复用本地 SpacetimeDB 前写入并校验 `dev-spacetime-tool-version`,避免把旧 standalone 继续带进新一轮创作。
本地 `spacetime` CLI / standalone 版本必须和 `server-rs/Cargo.toml` 里锁定的 `spacetimedb` 版本一致;当前统一版本为 `2.6.1`。若版本错配,procedure 返回值可能在宿主侧触发 `Failed to BSATN deserialize procedure return value`api-server 最终表现为敲木鱼等创作动作的 `SpacetimeDB procedure 调用超时`。排障时先运行 `spacetime --version`,再对照 `server-rs/Cargo.toml``spacetimedb = "..."`;遇到版本不匹配时不要继续深挖业务超时,直接执行 `spacetime version install <version> && spacetime version use <version>`,或在目标就是最新版本时执行 `spacetime version upgrade`,升级后重启 `npm run dev:spacetime` 再重试。当前 `scripts/dev.mjs` 会在启动和复用本地 SpacetimeDB 前写入并校验 `dev-spacetime-tool-version`,避免把旧 standalone 继续带进新一轮创作。2.6.1 修复了 procedure context 中调用者 `Identity` / `ConnectionId` 始终为空的回归,依赖 `ctx.sender` 鉴权时必须同时确认宿主已升级。
本地 `.env``.env.local``.env.secrets.local` 修改后必须重启 `api-server` 才会生效;若已经通过 `npm run dev` 启动完整联调,可在该终端输入 `rs api-server`。排查 RPG / 拼图 / 抓大鹅等 VectorEngine 生图链路时,确认 `VECTOR_ENGINE_BASE_URL``VECTOR_ENGINE_API_KEY``VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS` 只在本地或服务器密钥文件中配置,不能写入 Git。VectorEngine `gpt-image-2` 图片协议、URL / base64 响应解析、远端图片下载和 provider 侧结构化日志在 `server-rs/crates/platform-image``api-server` 只做配置、玩法编排、OSS / asset 持久化、计费和失败审计落库。`platform-image` 会在 JSON 生成和 multipart 编辑请求发送前,按原比例尽量收敛 `gpt-image-2` 的显式像素尺寸:最大边长不超过 `3840`、宽高均为 `16` 的倍数、长短边比不超过 `3:1`,总像素范围为 `655360``8294400`。无法满足全部条件时回退为 `1024x1024`;其他模型保留其传入尺寸。开局 CG 故事板、首图、背景和图集都属于长耗时图片请求;后端默认会把 `VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS` 下限收口到 `1000000`,旧进程仍可能沿用重启前的短超时。若 VectorEngine 在 `send()` 阶段失败且日志显示 `SendRequest`,先看同一 `request_id` 的 provider 日志字段 `source``source_chain``source_chain_depth`,再查 `external_api_call_failure.metadata_json.errorSource`;当前 multipart `/v1/images/edits` 单独强制 HTTP/1.1。拼图关卡资产按 `level_scene -> ui_spritesheet -> level_background` 顺序生成,日志会带 `slot``asset_kind``elapsed_ms`
@@ -563,7 +563,7 @@ worker 被硬杀或断电后,lease 过期任务只有尚未耗尽 `max_attempt
- `api-server` 正常运行时 `/healthz` 只返回进程存活状态,`/readyz` 会同时检查进程是否仍接收新流量和 SpacetimeDB 连接租约是否健康;收到 `SIGINT` / `SIGTERM` 后会先把 readiness 标记为不可用,再让 Axum 停止接新连接并等待已有 HTTP 请求排空。systemd 仍以 `KillSignal=SIGINT` 停服务,`TimeoutStopSec=90` 作为长请求排空上限。
- SpacetimeDB 健康检查默认使用 `GENARRATIVE_SPACETIME_HEALTH_CHECK_TIMEOUT_SECONDS=2` 的短等待窗口,和业务 procedure 的 `GENARRATIVE_SPACETIME_PROCEDURE_TIMEOUT_SECONDS` 分开。`/readyz` 失败时 `details.spacetime.stage` 会标出当前卡住阶段:`pool_acquire``connect_build``connect_handshake``read_model_subscribe``procedure_result``reducer_result``read_cache``elapsedMs` / `timeoutMs` 用于确认是否命中健康检查窗口。业务请求日志也会写入 `operation_kind``operation_name``spacetime_stage``elapsed_ms`,后续 45 秒超时不再只靠 Nginx `request_time=45s` 推断。
- `genarrative-api.service` 设置 `LimitNOFILE=65535``TasksMax=2048`;上线后用 `systemctl show genarrative-api.service -p LimitNOFILE -p TasksMax -p TimeoutStopUSec``cat /proc/$(pidof api-server)/limits` 核对。
- Server provision 不再通过 Windows helper 下载,也不再通过 Linux build 节点中转 SpacetimeDB / otelcol 工具包;Linux build 节点只负责从内网 Git 源准备 provision 脚本和配置并上传给目标 agent。`Prepare Provision Tools` 在目标 dev / release agent 工作区内先检查 `/usr/local/bin/otelcol-contrib``${SPACETIME_ROOT}/bin/current`:版本已满足时直接复用目标机现有文件生成 `provision-tools/`,只有缺失或版本不匹配时才使用 `PROVISION_DOWNLOADS_DIR` 里的本地包或从配置的下载源准备 SpacetimeDB `2.6.0` / `otelcol-contrib 0.151.0`;如果目标服务器下载需要代理,在 `PROVISION_DOWNLOAD_PROXY` 配置目标机可访问的 HTTP 代理。
- Server provision 不再通过 Windows helper 下载,也不再通过 Linux build 节点中转 SpacetimeDB / otelcol 工具包;Linux build 节点只负责从内网 Git 源准备 provision 脚本和配置并上传给目标 agent。`Prepare Provision Tools` 在目标 dev / release agent 工作区内先检查 `/usr/local/bin/otelcol-contrib``${SPACETIME_ROOT}/bin/current`:版本已满足时直接复用目标机现有文件生成 `provision-tools/`,只有缺失或版本不匹配时才使用 `PROVISION_DOWNLOADS_DIR` 里的本地包或从配置的下载源准备 SpacetimeDB `2.6.1` / `otelcol-contrib 0.151.0`;如果目标服务器下载需要代理,在 `PROVISION_DOWNLOAD_PROXY` 配置目标机可访问的 HTTP 代理。
-`Genarrative-Server-Provision` 外,`Genarrative-Stdb-Module-Build``Genarrative-Web-Build``Genarrative-Api-Build``Genarrative-*Deploy``Genarrative-Database-Import/Export``Genarrative-Full-Build-And-Deploy``Genarrative-Notify-Email` 的生产流水线现都以 Linux agent 为主,仍按各自 Jenkinsfile 的 checkout 口径执行。Server provision 不使用公网备用 Git 源,目标部署 agent 也不再需要访问源码 Git remote。
- `otelcol-contrib.service` 作为可选系统服务加入 provision,默认监听 `127.0.0.1:4317/4318` 并使用 `deploy/otelcol/genarrative-debug.yaml`。api-server 是否发送 OTLP 仍由 `GENARRATIVE_OTEL_ENABLED` 控制,服务 unit 见 `deploy/systemd/otelcol-contrib.service`。该服务必须存在系统用户 / 组 `otelcol`,并且 `/etc/otelcol/genarrative-debug.yaml` 已安装到目标机;若看到 `status=217/USER``Failed to determine user credentials`,优先检查 `getent passwd otelcol`,再补齐 `/etc/otelcol` 配置目录并重启服务。
- Nginx `/api/``/admin/api/` 通过 `genarrative_api` upstream 代理到 `127.0.0.1:8082`upstream keepalive 为 64`limit_conn` 负责连接 / 并发保护,`limit_req` 负责入口 RPS 快拒绝。当前模板把公开 gallery list 单独放到 `genarrative_gallery_rps`,默认 `rate=5000r/s``burst=4096``limit_conn=320`;公开详情和普通 API 放到 `genarrative_api_rps`,后台 API 放到 `genarrative_admin_rps`。通用 `/api` location 设置 `client_max_body_size 64m` 是反代兜底,防止拼图入口页 / 新增关卡本地参考图 Data URL 或旧兼容请求在到达 `api-server` 前被默认 1 MiB 上限拦截;拼图本地参考图前后端统一限制 6MB,历史图片仍提交 `referenceImageAssetObjectId(s)`。若线上出现 `413 Request Entity Too Large` 且 access log 中 `request_time=0.000``upstream_status=-`,说明请求在 Nginx 层被拦截,先用 `nginx -T | grep client_max_body_size` 检查 release 模板是否已渲染并 reload,同时检查前端是否超出 6MB 或错误提交了未压缩大图。`limit_conn_status 429``limit_req_status 429` 必须在 HTTP 与 HTTPS server 中同时生效;若线上压测看到 `limiting connections by zone "genarrative_api_conn"` 却返回 503,优先检查 `nginx -T` 里 HTTPS server 是否缺少这些状态码,以及 `/api/runtime/puzzle/gallery` 是否误落到通用 `location ~ ^/api``limit_conn=64`。压测时看 `/var/log/nginx/genarrative.access.log` 中的 `request_time``upstream_connect_time``upstream_header_time``upstream_response_time``upstream_status``request_id`
@@ -25,7 +25,7 @@ pipeline {
string(name: 'PROVISION_DOWNLOADS_DIR', defaultValue: 'provision-tool-downloads', description: '目标服务器工作区内暂存 SpacetimeDB/otelcol 安装包的相对目录')
string(name: 'PROVISION_TOOLS_DIR', defaultValue: 'provision-tools', description: '目标机工作区内由已下载安装包生成的工具包目录')
string(name: 'PROVISION_DOWNLOAD_PROXY', defaultValue: '', description: '可选,目标服务器下载 SpacetimeDB 和 otelcol-contrib 时使用的代理地址,例如 http://127.0.0.1:7890;留空不设置代理')
string(name: 'SPACETIME_DOWNLOAD_ROOT', defaultValue: 'https://github.com/clockworklabs/SpacetimeDB/releases/download/v2.6.0', description: '目标服务器使用的 SpacetimeDB Linux release tarball 根地址;默认固定到项目锁定版本')
string(name: 'SPACETIME_DOWNLOAD_ROOT', defaultValue: 'https://github.com/clockworklabs/SpacetimeDB/releases/download/v2.6.1', description: '目标服务器使用的 SpacetimeDB Linux release tarball 根地址;默认固定到项目锁定版本')
string(name: 'SPACETIME_TARGET_HOST', defaultValue: 'x86_64-unknown-linux-gnu', description: 'SpacetimeDB 预编译包 host tripledevelopment/release Linux amd64 使用默认值')
string(name: 'SPACETIME_ROOT', defaultValue: '/stdb', description: 'SpacetimeDB root-dir')
string(name: 'RELEASE_ROOT', defaultValue: '/opt/genarrative/releases', description: 'release 根目录')
@@ -209,7 +209,7 @@ BASH
OTELCOL_VERSION="${OTELCOL_VERSION:-0.151.0}" \
PREPARE_OTELCOL="${ENABLE_OTELCOL:-true}" \
PROVISION_DOWNLOAD_PROXY="${PROVISION_DOWNLOAD_PROXY:-}" \
SPACETIME_DOWNLOAD_ROOT="${SPACETIME_DOWNLOAD_ROOT:-https://github.com/clockworklabs/SpacetimeDB/releases/download/v2.6.0}" \
SPACETIME_DOWNLOAD_ROOT="${SPACETIME_DOWNLOAD_ROOT:-https://github.com/clockworklabs/SpacetimeDB/releases/download/v2.6.1}" \
SPACETIME_TARGET_HOST="${SPACETIME_TARGET_HOST:-x86_64-unknown-linux-gnu}" \
SPACETIME_ROOT="${SPACETIME_ROOT:-/stdb}" \
scripts/prepare-server-provision-tools.sh
+1 -1
View File
@@ -20,7 +20,7 @@ const repoRoot = path.resolve(
'..',
);
const database = 'admin-account-smoke';
const expectedSpacetimeVersion = '2.6.0';
const expectedSpacetimeVersion = '2.6.1';
const commandTimeoutMs = 5 * 60 * 1000;
function assert(condition, message) {
+3 -3
View File
@@ -37,11 +37,11 @@ chmod +x "${TARGET_BIN_DIR}/otelcol-contrib"
cat >"${SPACETIME_ROOT_DIR}/bin/current/spacetimedb-cli" <<'EOF'
#!/usr/bin/env bash
echo "spacetimedb-cli 2.6.0"
echo "spacetimedb-cli 2.6.1"
EOF
cat >"${SPACETIME_ROOT_DIR}/bin/current/spacetimedb-standalone" <<'EOF'
#!/usr/bin/env bash
echo "spacetimedb-standalone 2.6.0"
echo "spacetimedb-standalone 2.6.1"
EOF
chmod +x \
"${SPACETIME_ROOT_DIR}/bin/current/spacetimedb-cli" \
@@ -58,7 +58,7 @@ if ! (
OTELCOL_TARGET_BIN="${TARGET_BIN_DIR}/otelcol-contrib" \
OTELCOL_VERSION="0.151.0" \
SPACETIME_ROOT="${SPACETIME_ROOT_DIR}" \
SPACETIME_EXPECTED_VERSION="2.6.0" \
SPACETIME_EXPECTED_VERSION="2.6.1" \
"${REPO_ROOT}/scripts/prepare-server-provision-tools.sh" \
>"${OUTPUT_LOG}" 2>&1
); then
+4 -1
View File
@@ -146,8 +146,11 @@ function collectMigrationTables() {
return new Set();
}
const migrationTableBody = macroMatch[1]
.replace(/\/\*[\s\S]*?\*\//gu, ' ')
.replace(/\/\/[^\r\n]*/gu, ' ');
return new Set(
[...macroMatch[1].matchAll(/\b([a-z][a-z0-9_]*)\b/gu)]
[...migrationTableBody.matchAll(/\b([a-z][a-z0-9_]*)\b/gu)]
.map((match) => match[1])
.filter((name) => !['arg'].includes(name)),
);
@@ -108,6 +108,12 @@ const forbiddenSnippets = [
snippet: '.custom_world_profile()\n .iter()\n .filter(|profile| {',
reason: 'custom_world_profile Published 同步已有 by_custom_world_profile_publication_status 索引',
},
{
file: 'server-rs/crates/spacetime-module/src/editor_project_storage.rs',
snippet: 'require_editor_generation_runtime_service_identity(ctx, ctx.sender())',
reason:
'procedure runtime writer 鉴权必须显式传 caller,兼容 TxContext sender 为 Identity::ZERO 的 SpacetimeDB 2.6.0',
},
];
const procedureResultFiles = [
+1 -1
View File
@@ -761,7 +761,7 @@ function composeEnv() {
}
function localSpacetimeImageName() {
return `${projectName}-spacetimedb:2.6.0`;
return `${projectName}-spacetimedb:2.6.1`;
}
function spacetimeServerUrl(state) {
+1 -1
View File
@@ -9,7 +9,7 @@ OTELCOL_DOWNLOAD_ROOT="${OTELCOL_DOWNLOAD_ROOT:-https://github.com/open-telemetr
OTELCOL_ARCHIVE_PATH="${OTELCOL_ARCHIVE_PATH:-}"
OTELCOL_TARGET_BIN="${OTELCOL_TARGET_BIN:-/usr/local/bin/otelcol-contrib}"
SPACETIME_INSTALLER_URL="${SPACETIME_INSTALLER_URL:-https://install.spacetimedb.com}"
SPACETIME_DOWNLOAD_ROOT="${SPACETIME_DOWNLOAD_ROOT:-https://github.com/clockworklabs/SpacetimeDB/releases/download/v2.6.0}"
SPACETIME_DOWNLOAD_ROOT="${SPACETIME_DOWNLOAD_ROOT:-https://github.com/clockworklabs/SpacetimeDB/releases/download/v2.6.1}"
SPACETIME_TARGET_HOST="${SPACETIME_TARGET_HOST:-x86_64-unknown-linux-gnu}"
SPACETIME_ROOT="${SPACETIME_ROOT:-/stdb}"
SPACETIME_EXPECTED_VERSION="${SPACETIME_EXPECTED_VERSION:-}"
+28 -28
View File
@@ -5888,9 +5888,9 @@ dependencies = [
[[package]]
name = "spacetimedb"
version = "2.6.0"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8037ee5a6fa7348bf0392c728e4de4a0ba6f89c967eff80b666ac3e1e8f2b612"
checksum = "b6eff5017248ff2e35e03564df947fdf3e963f7198be6ae1d9e894c2efb2ea15"
dependencies = [
"anyhow",
"bytemuck",
@@ -5911,9 +5911,9 @@ dependencies = [
[[package]]
name = "spacetimedb-bindings-macro"
version = "2.6.0"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "202fb591c7d18fbbd4aec24a34ad6f03e3accc41580aee0fd2f9ad0514681917"
checksum = "fce86c7657dcb42a33ce55f0100f98964dc15b64e79f06803a478676b74d6c82"
dependencies = [
"heck 0.4.1",
"humantime",
@@ -5925,18 +5925,18 @@ dependencies = [
[[package]]
name = "spacetimedb-bindings-sys"
version = "2.6.0"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60869317019bbc8fa571e5c8ff21fe72abf9e5bcb579531efdded4e93a76e827"
checksum = "dbe5f9d71d59bdb93d81a7a61eee75ac2f1f88f91e139a7e263261f9dbf316de"
dependencies = [
"spacetimedb-primitives",
]
[[package]]
name = "spacetimedb-client-api-messages"
version = "2.6.0"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad481e05f959aa646e36e3e2e8b7581da58ca8f8a1b5e643122fc2bd4a4ff0df"
checksum = "1642404553853b56e521a12aa9849807d8e003433934c73eeebbc8671f1254f8"
dependencies = [
"bytes",
"bytestring",
@@ -5956,9 +5956,9 @@ dependencies = [
[[package]]
name = "spacetimedb-data-structures"
version = "2.6.0"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ec3aa387bfa45691c11b57e9072522dde3bbb554f7e017b57025b591556dbfb"
checksum = "3407c90a3da48b1c421bbad6a2ee6de3855a77d73fae98773bcc058426f1318f"
dependencies = [
"ahash",
"crossbeam-queue",
@@ -5971,9 +5971,9 @@ dependencies = [
[[package]]
name = "spacetimedb-lib"
version = "2.6.0"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d05a4bef4619afe949f7eac9c3a31f06f21c5139c89920a8f4c7dd7b09c24a8"
checksum = "bceaf72bdbf1a624d55d17ebaa38f8cf78a4972e43641c6cbf94f82318b5581d"
dependencies = [
"anyhow",
"bitflags 2.13.0",
@@ -5996,9 +5996,9 @@ dependencies = [
[[package]]
name = "spacetimedb-memory-usage"
version = "2.6.0"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "064ae4130ddc47e1b87b59252d041cf929ffbdc53686af80dff290f819e523ef"
checksum = "6cc1e19f664b47f4b3b82fb69b2fc096c3d82dc659ea705d62bbbec2fa9c2e83"
dependencies = [
"decorum",
"ethnum",
@@ -6006,9 +6006,9 @@ dependencies = [
[[package]]
name = "spacetimedb-metrics"
version = "2.6.0"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65b36210b2cdde2784e22e7182717bf1ab06a431f54bf9662e38bd1bcb8681c5"
checksum = "0c794455ed96245d52d837c8bbc3493d1c17d9f6382e6c5fee1c88926c9aa04a"
dependencies = [
"arrayvec",
"itertools 0.12.1",
@@ -6018,9 +6018,9 @@ dependencies = [
[[package]]
name = "spacetimedb-primitives"
version = "2.6.0"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c1e4745d32aacb71d29050f1ff6fa24fa149d939b8787f90ec28d2cac3c107b"
checksum = "b7525fda46b21fffdc62805099dee853a79000e0673ff6df4b8355cb0b8dabe8"
dependencies = [
"bitflags 2.13.0",
"either",
@@ -6032,18 +6032,18 @@ dependencies = [
[[package]]
name = "spacetimedb-query-builder"
version = "2.6.0"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79849bd28750b3351d54f3df4b37c5454cae3c62d0184bc9855650048a80c032"
checksum = "1f283c4797961d9a94f623ee4c66e6a94d30861b6380a49a27ac2d9568e17125"
dependencies = [
"spacetimedb-lib",
]
[[package]]
name = "spacetimedb-sats"
version = "2.6.0"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ca3327e8cd735f347ef5ff08a61b9806418acdcc0394ddd35a212c0849e4295"
checksum = "6cefb87b7d5e760d43cb65855591e25af772bdcca19562e5796ae797240d1998"
dependencies = [
"anyhow",
"arrayvec",
@@ -6074,9 +6074,9 @@ dependencies = [
[[package]]
name = "spacetimedb-schema"
version = "2.6.0"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb81b65cfa1da17f5f032f9566086670fb68a27f14f194a4dad76a21cc79f490"
checksum = "775cfdeb406e5628bf78b2221b0e0fd2fcba583f691bb89ba1c9338790ecaf7d"
dependencies = [
"anyhow",
"convert_case 0.6.0",
@@ -6105,9 +6105,9 @@ dependencies = [
[[package]]
name = "spacetimedb-sdk"
version = "2.6.0"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ceb50bcefcb70ae517c672a7ac21cbaf7affd44f0d9991968869eff566d83ba5"
checksum = "074a6d8828638176eb8e9bba7a3e6fb75dc659b260717306eb966c7e10575cd7"
dependencies = [
"anymap3",
"base64 0.21.7",
@@ -6137,9 +6137,9 @@ dependencies = [
[[package]]
name = "spacetimedb-sql-parser"
version = "2.6.0"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86cbda18ee77e497b698b22377750228b1e88ead4dcb79fc3fddb78cccab0a77"
checksum = "3b978b6d76cfbe5782a7f0dae7e25f6be4e7e13cfad26c9211d4eb4cdf8c22da"
dependencies = [
"derive_more",
"spacetimedb-lib",
+3 -3
View File
@@ -135,9 +135,9 @@ serde_urlencoded = "0.7"
sha1 = "0.10"
sha2 = "0.10"
socket2 = "0.6"
spacetimedb = "=2.6.0"
spacetimedb-sdk = "=2.6.0"
spacetimedb-lib = { version = "=2.6.0", default-features = false }
spacetimedb = "=2.6.1"
spacetimedb-sdk = "=2.6.1"
spacetimedb-lib = { version = "=2.6.1", default-features = false }
time = "0.3"
tokio = "1"
tokio-stream = "0.1"
@@ -0,0 +1 @@
//! 编辑器 Agent 领域事件预留落位,当前不导出独立事件类型。
@@ -2,6 +2,7 @@ mod application;
mod commands;
mod domain;
mod errors;
mod events;
pub use application::*;
pub use commands::*;
@@ -1,7 +1,7 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
// This was generated using spacetimedb cli version 2.6.0 (commit 31fd1c8c3346dfec38dfcc2e89c2ecf457cf26ff).
// This was generated using spacetimedb cli version 2.6.1 (commit 052c83fe984a4c4eb7bb4f9afa5c6b1903891d87).
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
@@ -34,10 +34,10 @@ pub trait update_external_generation_job_phase_and_return {
input: ExternalGenerationJobPhaseUpdateInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<ExternalGenerationJobPhaseUpdateProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
&super::ProcedureEventContext,
Result<ExternalGenerationJobPhaseUpdateProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
);
}
@@ -47,10 +47,10 @@ impl update_external_generation_job_phase_and_return for super::RemoteProcedures
input: ExternalGenerationJobPhaseUpdateInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<ExternalGenerationJobPhaseUpdateProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
&super::ProcedureEventContext,
Result<ExternalGenerationJobPhaseUpdateProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
) {
self.imp
.invoke_procedure_with_callback::<_, ExternalGenerationJobPhaseUpdateProcedureResult>(
@@ -1095,7 +1095,8 @@ pub fn find_editor_asset_group_source_and_return(
ctx: &mut ProcedureContext,
input: EditorAssetGroupSourceLookupInput,
) -> EditorAssetProcedureResult {
match ctx.try_with_tx(|tx| find_editor_asset_group_source(tx, input.clone())) {
let caller = ctx.sender();
match ctx.try_with_tx(|tx| find_editor_asset_group_source(tx, caller, input.clone())) {
Ok(asset) => editor_asset_ok(asset),
Err(message) => editor_asset_error(message),
}
@@ -1139,7 +1140,8 @@ pub fn create_editor_asset_and_return(
ctx: &mut ProcedureContext,
input: EditorAssetCreateInput,
) -> EditorAssetProcedureResult {
match ctx.try_with_tx(|tx| create_editor_asset(tx, input.clone())) {
let caller = ctx.sender();
match ctx.try_with_tx(|tx| create_editor_asset(tx, caller, input.clone())) {
Ok(asset) => editor_asset_ok(Some(asset)),
Err(message) => editor_asset_error(message),
}
@@ -1150,7 +1152,8 @@ pub fn complete_editor_asset_group_cohort_and_return(
ctx: &mut ProcedureContext,
input: EditorAssetGroupCohortCompleteInput,
) -> EditorAssetProcedureResult {
match ctx.try_with_tx(|tx| complete_editor_asset_group_cohort(tx, input.clone())) {
let caller = ctx.sender();
match ctx.try_with_tx(|tx| complete_editor_asset_group_cohort(tx, caller, input.clone())) {
Ok(asset) => editor_asset_ok(Some(asset)),
Err(message) => editor_asset_error(message),
}
@@ -1855,9 +1858,10 @@ fn admin_list_editor_assets(
fn find_editor_asset_group_source(
ctx: &ReducerContext,
caller: Identity,
input: EditorAssetGroupSourceLookupInput,
) -> Result<Option<EditorAssetSnapshot>, String> {
require_editor_generation_runtime_service_identity(ctx, ctx.sender())?;
require_editor_generation_runtime_service_identity(ctx, caller)?;
let owner_user_id = normalize_required(&input.owner_user_id, "owner_user_id")?;
let source_resource_ids = input
.source_resource_ids
@@ -1924,9 +1928,10 @@ fn find_editor_asset_group_source(
fn complete_editor_asset_group_cohort(
ctx: &ReducerContext,
caller: Identity,
input: EditorAssetGroupCohortCompleteInput,
) -> Result<EditorAssetSnapshot, String> {
require_editor_generation_runtime_service_identity(ctx, ctx.sender())?;
require_editor_generation_runtime_service_identity(ctx, caller)?;
let owner_user_id = normalize_required(&input.owner_user_id, "owner_user_id")?;
let task_id = normalize_required(&input.task_id, "task_id")?;
let group_task_id = normalize_required(&input.group_task_id, "group_task_id")?;
@@ -2101,6 +2106,7 @@ fn delete_editor_asset_folder(
fn create_editor_asset(
ctx: &ReducerContext,
caller: Identity,
input: EditorAssetCreateInput,
) -> Result<EditorAssetSnapshot, String> {
let asset_id = normalize_required(&input.asset_id, "editor_asset.asset_id")?;
@@ -2131,7 +2137,7 @@ fn create_editor_asset(
return Err("素材任务预期产物数量必须与归组 Task ID 一起提供".to_string());
}
if group_task_id.is_some() {
require_editor_generation_runtime_service_identity(ctx, ctx.sender())?;
require_editor_generation_runtime_service_identity(ctx, caller)?;
}
ctx.db.editor_asset().insert(EditorAsset {
asset_id: asset_id.clone(),
@@ -254,6 +254,8 @@ macro_rules! migration_tables {
editor_project_resource,
editor_asset_folder,
editor_asset,
editor_asset_group_source_provenance,
editor_asset_group_cohort,
editor_showcase_asset,
editor_showcase_asset_like,
editor_showcase_campaign_config,