- lock profile task tracking scope to user - add analytics date dimension module support and tests - regenerate SpacetimeDB Rust bindings with private APIs
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
||||
# AdminTaskConfigPage 埋点范围收口记录(2026-05-04)
|
||||
|
||||
## 变更目标
|
||||
- 前端隐藏「埋点范围」选择项。
|
||||
- 保存任务配置时固定传递 `scopeKind=user`,避免运营在后台选择其他范围。
|
||||
|
||||
## 落地结果
|
||||
- `apps/admin-web/src/pages/AdminTaskConfigPage.tsx`
|
||||
- 移除了「埋点范围」下拉选择 UI。
|
||||
- 保存时改为固定提交 `scopeKind: 'user'`。
|
||||
- 回填表单时不再读取或维护 `scopeKind` 的可编辑状态。
|
||||
|
||||
## 验证结果
|
||||
- 已检查页面源码,确认不再存在「埋点范围」字段与可编辑逻辑。
|
||||
- 已执行 `npm run admin-web:typecheck`。
|
||||
- 当前验证失败原因为环境缺少 `node_modules/typescript/bin/tsc`,属于依赖安装状态问题,不是本次前端改动引入的代码错误。
|
||||
|
||||
## 遗留说明
|
||||
- `apps/admin-web/src/api/adminApiTypes.ts` 中仍保留 `TrackingScopeKind` 类型,供接口契约与其他前端模块兼容使用。
|
||||
- `apps/admin-web/src/config/trackingEventDefinitions.ts` 仍保留事件定义中的 `scopeKind` 元数据,但页面不再允许运营修改。
|
||||
@@ -0,0 +1,288 @@
|
||||
# Analytics Date Dimension 与个人任务埋点范围收口记录(2026-05-04)
|
||||
|
||||
## 背景
|
||||
|
||||
本记录用于收口 `.hermes/plans/2026-05-04_022223-analytics-time-dimension-mapping.md` 中当前阶段已经落地的内容,并明确尚未执行的后续范围。
|
||||
|
||||
本阶段目标不是完整上线运营统计查询,而是先完成两件基础工作:
|
||||
|
||||
1. 收紧个人任务系统的埋点范围,避免运营或接口把个人任务错误配置为 `site`、`module`、`work` 等非用户维度。
|
||||
2. 新增统一日期维表 `analytics_date_dimension`,为后续按周、月、季、年聚合埋点数据提供稳定的日期 bucket 映射。
|
||||
|
||||
## 当前已完成范围
|
||||
|
||||
### 1. 个人任务埋点范围锁定为 User
|
||||
|
||||
当前个人任务系统首版只支持用户维度埋点。
|
||||
|
||||
已完成:
|
||||
|
||||
- Admin 任务配置页不再展示“埋点范围”选择。
|
||||
- Admin 保存任务配置时固定传 `scopeKind: 'user'`。
|
||||
- API 层拒绝非 `user` 的个人任务配置。
|
||||
- 领域输入构造层拒绝非 `User` 的个人任务配置。
|
||||
- `Work => user_id` 的错误映射已移除。
|
||||
- 任务进度刷新、任务中心快照、领奖链路遇到非 `User` 的异常个人任务配置时显式报错,不再静默按 0 进度处理。
|
||||
|
||||
相关文件:
|
||||
|
||||
```text
|
||||
apps/admin-web/src/pages/AdminTaskConfigPage.tsx
|
||||
apps/admin-web/src/api/adminApiTypes.ts
|
||||
server-rs/crates/api-server/src/runtime_profile.rs
|
||||
server-rs/crates/module-runtime/src/commands.rs
|
||||
server-rs/crates/module-runtime/src/errors.rs
|
||||
server-rs/crates/spacetime-module/src/runtime/profile.rs
|
||||
```
|
||||
|
||||
### 2. 日期维表领域模型与纯函数
|
||||
|
||||
已在 `module-runtime` 中补充日期维表快照和纯函数。
|
||||
|
||||
日期维表使用现有北京时间业务日 `day_key` 语义:
|
||||
|
||||
```text
|
||||
date_key = floor((occurred_at_micros + 8h) / 1d)
|
||||
```
|
||||
|
||||
已完成能力:
|
||||
|
||||
- 从 `YYYY-MM-DD` 解析业务日 `date_key`。
|
||||
- 从 `date_key` 构造日期维表快照。
|
||||
- 生成 ISO weekday:周一=1,周日=7。
|
||||
- 生成 ISO week key:`YYYYWW`,跨年周按 ISO week-year。
|
||||
- 生成 week/month/quarter/year 的 key 和起止 `date_key`。
|
||||
- 限制日期维表支持范围为:
|
||||
- `2000-01-01`
|
||||
- 到 `2100-12-31`
|
||||
|
||||
相关文件:
|
||||
|
||||
```text
|
||||
server-rs/crates/module-runtime/src/domain.rs
|
||||
server-rs/crates/module-runtime/src/application.rs
|
||||
server-rs/crates/module-runtime/src/lib.rs
|
||||
```
|
||||
|
||||
### 3. SpacetimeDB 日期维表与 reducer
|
||||
|
||||
已新增 SpacetimeDB 表:
|
||||
|
||||
```text
|
||||
analytics_date_dimension
|
||||
```
|
||||
|
||||
表字段包括:
|
||||
|
||||
```text
|
||||
date_key
|
||||
calendar_date
|
||||
weekday
|
||||
iso_week_key
|
||||
week_start_date_key
|
||||
week_end_date_key
|
||||
month_key
|
||||
month_start_date_key
|
||||
month_end_date_key
|
||||
quarter_key
|
||||
quarter_start_date_key
|
||||
quarter_end_date_key
|
||||
year_key
|
||||
year_start_date_key
|
||||
year_end_date_key
|
||||
created_at
|
||||
updated_at
|
||||
```
|
||||
|
||||
已新增索引:
|
||||
|
||||
```text
|
||||
iso_week_key
|
||||
month_key
|
||||
quarter_key
|
||||
year_key
|
||||
```
|
||||
|
||||
已新增 reducer:
|
||||
|
||||
```text
|
||||
ensure_analytics_date_dimension_for_date
|
||||
seed_analytics_date_dimensions
|
||||
```
|
||||
|
||||
当前 reducer 行为:
|
||||
|
||||
- `ensure` 单日幂等补齐。
|
||||
- `seed` 按日期范围幂等补齐。
|
||||
- `seed` 拒绝 `start_date > end_date`。
|
||||
- `seed` 单次最多允许 `ANALYTICS_DATE_DIMENSION_MAX_SEED_DAYS = 3660` 天。
|
||||
- 裸 `date_key` 进入 ensure 前先做支持范围校验,避免极端整数进入日历算法。
|
||||
|
||||
相关文件:
|
||||
|
||||
```text
|
||||
server-rs/crates/spacetime-module/src/runtime/analytics_date_dimension.rs
|
||||
server-rs/crates/spacetime-module/src/runtime/mod.rs
|
||||
server-rs/crates/spacetime-module/src/migration.rs
|
||||
docs/technical/SPACETIMEDB_TABLE_CATALOG.md
|
||||
```
|
||||
|
||||
### 4. SpacetimeDB Rust client bindings
|
||||
|
||||
已按项目脚本生成 Rust bindings,并在生成参数中显式包含 private tables/functions:
|
||||
|
||||
```bash
|
||||
PATH="/tmp/spacetime-bin:$PATH" npm run spacetime:generate -- --rust-only
|
||||
```
|
||||
|
||||
本次已修改生成脚本:
|
||||
|
||||
```text
|
||||
scripts/generate-spacetime-bindings.mjs
|
||||
```
|
||||
|
||||
在 `spacetime generate` 参数中加入:
|
||||
|
||||
```text
|
||||
--include-private
|
||||
```
|
||||
|
||||
说明:SpacetimeDB CLI 2.1.0 的参数名是 `--include-private`,不是 `--non-private`。该参数含义是将 private tables/functions 也包含进生成代码,满足 api-server 通过 Rust bindings 访问 module private table/reducer 的需求。
|
||||
|
||||
```text
|
||||
spacetimedb tool version 2.1.0; spacetimedb-lib version 2.1.0
|
||||
```
|
||||
|
||||
生成脚本:
|
||||
|
||||
```text
|
||||
scripts/generate-spacetime-bindings.mjs
|
||||
```
|
||||
|
||||
已新增 analytics date dimension 相关 bindings:
|
||||
|
||||
```text
|
||||
server-rs/crates/spacetime-client/src/module_bindings/analytics_date_dimension_ensure_input_type.rs
|
||||
server-rs/crates/spacetime-client/src/module_bindings/analytics_date_dimension_seed_input_type.rs
|
||||
server-rs/crates/spacetime-client/src/module_bindings/analytics_date_dimension_type.rs
|
||||
server-rs/crates/spacetime-client/src/module_bindings/analytics_date_dimension_table.rs
|
||||
server-rs/crates/spacetime-client/src/module_bindings/ensure_analytics_date_dimension_for_date_reducer.rs
|
||||
server-rs/crates/spacetime-client/src/module_bindings/seed_analytics_date_dimensions_reducer.rs
|
||||
```
|
||||
|
||||
并更新了:
|
||||
|
||||
```text
|
||||
server-rs/crates/spacetime-client/src/module_bindings/mod.rs
|
||||
```
|
||||
|
||||
注意:
|
||||
|
||||
- `analytics_date_dimension` 表当前是 private table;由于生成脚本已加 `--include-private`,本次 codegen 已生成 `analytics_date_dimension_table.rs`,可通过 `ctx.db.analytics_date_dimension()` 访问 client cache / query builder。
|
||||
- bindings 目录是自动生成产物,本次以项目脚本整体刷新,除新增 analytics 文件外,也带来了大量已存在 table/reducer/procedure 文件的格式化/生成器输出差异。
|
||||
|
||||
### 5. 测试覆盖
|
||||
|
||||
已新增测试:
|
||||
|
||||
```text
|
||||
server-rs/crates/module-runtime/tests/analytics_date_dimension.rs
|
||||
server-rs/crates/module-runtime/tests/profile_task_scope.rs
|
||||
server-rs/crates/shared-contracts/tests/profile_task_contract.rs
|
||||
```
|
||||
|
||||
覆盖重点:
|
||||
|
||||
- `2024-02-29` 闰年。
|
||||
- `2025-12-29` ISO week 跨年。
|
||||
- `2026-01-01` 跨年周。
|
||||
- `2026-03-31` Q1 结束。
|
||||
- `2026-04-01` Q2 开始。
|
||||
- `2026-12-31` 年末。
|
||||
- 非法日期解析失败。
|
||||
- 超出日期维表支持范围失败。
|
||||
- 个人任务 `scopeKind=user` 成功。
|
||||
- 个人任务 `scopeKind=site/module/work` 失败。
|
||||
- `work` scope 不会静默映射到 `user_id`。
|
||||
- Admin 个人任务配置 contract 保持 `scopeKind: user`。
|
||||
|
||||
## 已验证命令
|
||||
|
||||
从 `server-rs/` 执行:
|
||||
|
||||
```bash
|
||||
cargo fmt -p module-runtime -p spacetime-module -p spacetime-client
|
||||
cargo test -p spacetime-client --no-run
|
||||
cargo test -p spacetime-module --no-run
|
||||
cargo test -p module-runtime --test analytics_date_dimension
|
||||
cargo test -p module-runtime --test profile_task_scope
|
||||
cargo test -p shared-contracts --test profile_task_contract
|
||||
```
|
||||
|
||||
从项目根目录执行:
|
||||
|
||||
```bash
|
||||
npm run admin-web:typecheck
|
||||
```
|
||||
|
||||
当前结果:
|
||||
|
||||
- `spacetime-client --no-run` 编译通过。
|
||||
- `spacetime-module --no-run` 编译通过。
|
||||
- `analytics_date_dimension` 测试通过:8 passed。
|
||||
- `profile_task_scope` 测试通过:3 passed。
|
||||
- `profile_task_contract` 测试通过:2 passed。
|
||||
- `admin-web:typecheck` 通过。
|
||||
|
||||
已知非本阶段阻塞:
|
||||
|
||||
- 完整运行 `cargo test -p spacetime-module` 时,曾出现既有 puzzle 测试失败:
|
||||
|
||||
```text
|
||||
puzzle::tests::puzzle_preview_is_publishable_with_complete_draft FAILED
|
||||
assertion failed: preview.publish_ready
|
||||
```
|
||||
|
||||
该失败与当前埋点范围和日期维表改动无直接关系,本阶段以 `cargo test -p spacetime-module --no-run` 作为编译门禁。
|
||||
|
||||
## 当前未完成 / 暂缓项
|
||||
|
||||
### 1. 暂未新增 spacetime-client facade
|
||||
|
||||
当前没有新增:
|
||||
|
||||
```text
|
||||
SpacetimeClient::ensure_analytics_date_dimension_for_date
|
||||
SpacetimeClient::seed_analytics_date_dimensions
|
||||
```
|
||||
|
||||
原因:
|
||||
|
||||
- 生成脚本已加入 `--include-private`,private reducer/type/table bindings 已可用于后续 facade 实现。
|
||||
- 但 Step 7/8/9 暂缓,尚未由 `api-server` 或统计查询链路调用该能力。
|
||||
- 如后续只是 SpacetimeDB module 内部写入统计时 ensure,可以直接复用 module 内部 helper,不一定需要远程 client facade。
|
||||
- 若后续需要由 API 或运维接口触发 seed/ensure,可基于本次已生成的 reducer bindings 再补 facade。
|
||||
|
||||
### 2. Step 7/8/9 暂缓
|
||||
|
||||
本阶段未接入:
|
||||
|
||||
- 事件写入链路自动 ensure 日期维表。
|
||||
- 聚合查询 API 的 `granularity = day | week | month | quarter | year`。
|
||||
- shared contracts / 前端 analytics contracts。
|
||||
- 历史事件回填。
|
||||
|
||||
这些应作为后续阶段单独设计和落地。
|
||||
|
||||
## 后续建议顺序
|
||||
|
||||
1. 如需提交本阶段改动,确认是否接受 `module_bindings` 整体刷新带来的大量生成文件 diff。
|
||||
2. 如希望 diff 更小,可评估仅提交 analytics date dimension 相关生成文件与 `mod.rs`;但需要非常谨慎,因为 `module_bindings` 是自动生成产物。
|
||||
3. 如需要由 `api-server` 触发 seed/ensure,再补 `spacetime-client` facade。
|
||||
4. 进入 Step 7/8/9:事件写入链路、聚合查询 API、前端 contracts。
|
||||
|
||||
## 阶段结论
|
||||
|
||||
当前阶段已经完成“个人任务埋点范围收紧”和“日期维表 module 侧能力”的核心落地,并已生成 SpacetimeDB Rust client bindings。
|
||||
|
||||
剩余工作不再是 bindings 环境阻塞,而是后续业务接入范围:是否增加 `spacetime-client` facade,以及是否继续推进事件写入链路、聚合查询 API 和前端 analytics contracts。
|
||||
@@ -0,0 +1,18 @@
|
||||
# 个人任务 scope 限制说明(2026-05-04)
|
||||
|
||||
## 背景
|
||||
|
||||
个人任务配置首版只支持按用户维度统计进度,即 `RuntimeTrackingScopeKind::User` / API `scopeKind: "user"`。`site`、`module`、`work` 未来可作为全站、模块或作品维度任务扩展,但当前不应被个人任务配置接受。
|
||||
|
||||
## 后端约束
|
||||
|
||||
- HTTP 管理接口 `admin_upsert_profile_task_config` 在解析 `scopeKind` 后立即校验:非 `user` 返回 400,并提示“个人任务 scopeKind 首版仅支持 user”。
|
||||
- 领域构造函数 `build_runtime_profile_task_config_admin_upsert_input` 兜底校验:非 `RuntimeTrackingScopeKind::User` 返回 `RuntimeProfileFieldError::UnsupportedProfileTaskScopeKind`。
|
||||
- SpacetimeDB 模块内 `profile_task_tracking_scope_id` 不再把 `Work` 静默映射到 `user_id`;非 User scope 返回 `None`,个人任务进度读取按 0 处理,避免错误串桶。
|
||||
|
||||
## 测试覆盖
|
||||
|
||||
`module-runtime` 单元测试覆盖:
|
||||
|
||||
- `User` scope 可成功构造个人任务配置输入。
|
||||
- `Site` / `Module` / `Work` scope 均被拒绝,错误为 `UnsupportedProfileTaskScopeKind`。
|
||||
@@ -142,6 +142,7 @@ function buildGenerateArgs(target, outDir) {
|
||||
outDir,
|
||||
'--module-path',
|
||||
MODULE_PATH,
|
||||
'--include-private',
|
||||
'--yes',
|
||||
];
|
||||
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
use module_runtime::{
|
||||
AnalyticsDateDimensionSnapshot, RuntimeProfileFieldError,
|
||||
build_analytics_date_dimension_from_date_key, parse_analytics_calendar_date_key,
|
||||
validate_analytics_date_dimension_date_key,
|
||||
};
|
||||
|
||||
fn dimension(calendar_date: &str) -> AnalyticsDateDimensionSnapshot {
|
||||
let date_key = parse_analytics_calendar_date_key(calendar_date).expect("日期应可解析");
|
||||
build_analytics_date_dimension_from_date_key(date_key)
|
||||
}
|
||||
|
||||
fn date_key(calendar_date: &str) -> i64 {
|
||||
parse_analytics_calendar_date_key(calendar_date).expect("日期应可解析")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn analytics_date_dimension_handles_leap_day() {
|
||||
// 中文注释:2024 是闰年,2 月应包含 29 日且属于 ISO 第 9 周。
|
||||
let snapshot = dimension("2024-02-29");
|
||||
|
||||
assert_eq!(snapshot.calendar_date, "2024-02-29");
|
||||
assert_eq!(snapshot.weekday, 4);
|
||||
assert_eq!(snapshot.iso_week_key, 202409);
|
||||
assert_eq!(snapshot.week_start_date_key, date_key("2024-02-26"));
|
||||
assert_eq!(snapshot.week_end_date_key, date_key("2024-03-03"));
|
||||
assert_eq!(snapshot.month_key, 202402);
|
||||
assert_eq!(snapshot.month_start_date_key, date_key("2024-02-01"));
|
||||
assert_eq!(snapshot.month_end_date_key, date_key("2024-02-29"));
|
||||
assert_eq!(snapshot.quarter_key, 20241);
|
||||
assert_eq!(snapshot.year_key, 2024);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn analytics_date_dimension_uses_iso_week_year_across_year_boundary() {
|
||||
// 中文注释:2025-12-29 是周一,但 ISO week-year 已经进入 2026-W01。
|
||||
let snapshot = dimension("2025-12-29");
|
||||
|
||||
assert_eq!(snapshot.calendar_date, "2025-12-29");
|
||||
assert_eq!(snapshot.weekday, 1);
|
||||
assert_eq!(snapshot.iso_week_key, 202601);
|
||||
assert_eq!(snapshot.week_start_date_key, date_key("2025-12-29"));
|
||||
assert_eq!(snapshot.week_end_date_key, date_key("2026-01-04"));
|
||||
assert_eq!(snapshot.month_key, 202512);
|
||||
assert_eq!(snapshot.quarter_key, 20254);
|
||||
assert_eq!(snapshot.year_key, 2025);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn analytics_date_dimension_handles_new_year_inside_iso_week() {
|
||||
// 中文注释:2026-01-01 仍落在 2026-W01,周范围跨自然年。
|
||||
let snapshot = dimension("2026-01-01");
|
||||
|
||||
assert_eq!(snapshot.calendar_date, "2026-01-01");
|
||||
assert_eq!(snapshot.weekday, 4);
|
||||
assert_eq!(snapshot.iso_week_key, 202601);
|
||||
assert_eq!(snapshot.week_start_date_key, date_key("2025-12-29"));
|
||||
assert_eq!(snapshot.week_end_date_key, date_key("2026-01-04"));
|
||||
assert_eq!(snapshot.month_key, 202601);
|
||||
assert_eq!(snapshot.month_start_date_key, date_key("2026-01-01"));
|
||||
assert_eq!(snapshot.month_end_date_key, date_key("2026-01-31"));
|
||||
assert_eq!(snapshot.quarter_key, 20261);
|
||||
assert_eq!(snapshot.year_key, 2026);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn analytics_date_dimension_handles_q1_end() {
|
||||
// 中文注释:Q1 结束日应映射到 2026Q1,季度边界为 1 月 1 日到 3 月 31 日。
|
||||
let snapshot = dimension("2026-03-31");
|
||||
|
||||
assert_eq!(snapshot.calendar_date, "2026-03-31");
|
||||
assert_eq!(snapshot.weekday, 2);
|
||||
assert_eq!(snapshot.iso_week_key, 202614);
|
||||
assert_eq!(snapshot.month_key, 202603);
|
||||
assert_eq!(snapshot.month_start_date_key, date_key("2026-03-01"));
|
||||
assert_eq!(snapshot.month_end_date_key, date_key("2026-03-31"));
|
||||
assert_eq!(snapshot.quarter_key, 20261);
|
||||
assert_eq!(snapshot.quarter_start_date_key, date_key("2026-01-01"));
|
||||
assert_eq!(snapshot.quarter_end_date_key, date_key("2026-03-31"));
|
||||
assert_eq!(snapshot.year_key, 2026);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn analytics_date_dimension_handles_q2_start() {
|
||||
// 中文注释:Q2 开始日应映射到 2026Q2,季度边界为 4 月 1 日到 6 月 30 日。
|
||||
let snapshot = dimension("2026-04-01");
|
||||
|
||||
assert_eq!(snapshot.calendar_date, "2026-04-01");
|
||||
assert_eq!(snapshot.weekday, 3);
|
||||
assert_eq!(snapshot.iso_week_key, 202614);
|
||||
assert_eq!(snapshot.month_key, 202604);
|
||||
assert_eq!(snapshot.month_start_date_key, date_key("2026-04-01"));
|
||||
assert_eq!(snapshot.month_end_date_key, date_key("2026-04-30"));
|
||||
assert_eq!(snapshot.quarter_key, 20262);
|
||||
assert_eq!(snapshot.quarter_start_date_key, date_key("2026-04-01"));
|
||||
assert_eq!(snapshot.quarter_end_date_key, date_key("2026-06-30"));
|
||||
assert_eq!(snapshot.year_key, 2026);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn analytics_date_dimension_handles_year_end() {
|
||||
// 中文注释:2026 年末属于 2026-W53,且所有自然年边界应保持在 2026 年内。
|
||||
let snapshot = dimension("2026-12-31");
|
||||
|
||||
assert_eq!(snapshot.calendar_date, "2026-12-31");
|
||||
assert_eq!(snapshot.weekday, 4);
|
||||
assert_eq!(snapshot.iso_week_key, 202653);
|
||||
assert_eq!(snapshot.week_start_date_key, date_key("2026-12-28"));
|
||||
assert_eq!(snapshot.week_end_date_key, date_key("2027-01-03"));
|
||||
assert_eq!(snapshot.month_key, 202612);
|
||||
assert_eq!(snapshot.month_start_date_key, date_key("2026-12-01"));
|
||||
assert_eq!(snapshot.month_end_date_key, date_key("2026-12-31"));
|
||||
assert_eq!(snapshot.quarter_key, 20264);
|
||||
assert_eq!(snapshot.quarter_start_date_key, date_key("2026-10-01"));
|
||||
assert_eq!(snapshot.quarter_end_date_key, date_key("2026-12-31"));
|
||||
assert_eq!(snapshot.year_key, 2026);
|
||||
assert_eq!(snapshot.year_start_date_key, date_key("2026-01-01"));
|
||||
assert_eq!(snapshot.year_end_date_key, date_key("2026-12-31"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn analytics_date_key_parser_rejects_invalid_calendar_dates() {
|
||||
// 中文注释:非法日期和非 YYYY-MM-DD 字符串都必须解析失败,避免写入脏维表。
|
||||
assert_eq!(
|
||||
parse_analytics_calendar_date_key("2026-02-30"),
|
||||
Err(RuntimeProfileFieldError::InvalidAnalyticsCalendarDate)
|
||||
);
|
||||
assert_eq!(
|
||||
parse_analytics_calendar_date_key("bad"),
|
||||
Err(RuntimeProfileFieldError::InvalidAnalyticsCalendarDate)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn analytics_date_dimension_rejects_out_of_supported_range() {
|
||||
// 中文注释:维表只允许受控业务日期范围,避免裸 date_key 极值进入 reducer 日历算法。
|
||||
assert_eq!(
|
||||
parse_analytics_calendar_date_key("1999-12-31"),
|
||||
Err(RuntimeProfileFieldError::InvalidAnalyticsCalendarDate)
|
||||
);
|
||||
assert_eq!(
|
||||
parse_analytics_calendar_date_key("2101-01-01"),
|
||||
Err(RuntimeProfileFieldError::InvalidAnalyticsCalendarDate)
|
||||
);
|
||||
assert_eq!(
|
||||
validate_analytics_date_dimension_date_key(i64::MAX),
|
||||
Err(RuntimeProfileFieldError::InvalidAnalyticsCalendarDate)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
use module_runtime::{
|
||||
RuntimeProfileFieldError, RuntimeProfileTaskCycle, RuntimeTrackingScopeKind,
|
||||
build_runtime_profile_task_config_admin_upsert_input, build_runtime_tracking_daily_stat_id,
|
||||
};
|
||||
|
||||
fn build_task_scope_input(
|
||||
scope_kind: RuntimeTrackingScopeKind,
|
||||
) -> Result<module_runtime::RuntimeProfileTaskConfigAdminUpsertInput, RuntimeProfileFieldError> {
|
||||
build_runtime_profile_task_config_admin_upsert_input(
|
||||
"admin-1".to_string(),
|
||||
"daily-login".to_string(),
|
||||
"每日登录".to_string(),
|
||||
"".to_string(),
|
||||
"daily_login".to_string(),
|
||||
RuntimeProfileTaskCycle::Daily,
|
||||
scope_kind,
|
||||
1,
|
||||
10,
|
||||
true,
|
||||
10,
|
||||
1_000,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn admin_upsert_build_input_accepts_user_scope() {
|
||||
let input = build_task_scope_input(RuntimeTrackingScopeKind::User)
|
||||
.expect("个人任务 user scope 应允许保存");
|
||||
|
||||
assert_eq!(input.scope_kind, RuntimeTrackingScopeKind::User);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn admin_upsert_build_input_rejects_non_user_scope_with_clear_message() {
|
||||
for scope_kind in [
|
||||
RuntimeTrackingScopeKind::Site,
|
||||
RuntimeTrackingScopeKind::Module,
|
||||
RuntimeTrackingScopeKind::Work,
|
||||
] {
|
||||
let error = build_task_scope_input(scope_kind).expect_err("非 user scope 应拒绝保存");
|
||||
|
||||
assert_eq!(
|
||||
error,
|
||||
RuntimeProfileFieldError::UnsupportedProfileTaskScopeKind
|
||||
);
|
||||
assert!(
|
||||
error.to_string().contains("仅支持 user"),
|
||||
"错误信息应明确说明个人任务仅支持 user,实际为:{}",
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tracking_daily_stat_id_keeps_work_scope_separate_from_user_scope() {
|
||||
let user_id = "user-1";
|
||||
let work_id = "work-1";
|
||||
let day_key = 20_000;
|
||||
|
||||
let user_stat_id = build_runtime_tracking_daily_stat_id(
|
||||
"daily_login",
|
||||
RuntimeTrackingScopeKind::User,
|
||||
user_id,
|
||||
day_key,
|
||||
);
|
||||
let work_stat_id = build_runtime_tracking_daily_stat_id(
|
||||
"daily_login",
|
||||
RuntimeTrackingScopeKind::Work,
|
||||
work_id,
|
||||
day_key,
|
||||
);
|
||||
let invalid_work_with_user_id_stat_id = build_runtime_tracking_daily_stat_id(
|
||||
"daily_login",
|
||||
RuntimeTrackingScopeKind::Work,
|
||||
user_id,
|
||||
day_key,
|
||||
);
|
||||
|
||||
// 中文注释:Work 维度必须保留独立 scope_kind,不允许被静默当作 user_id 查询用户桶。
|
||||
assert!(user_stat_id.contains(":user:user-1:"));
|
||||
assert!(work_stat_id.contains(":work:work-1:"));
|
||||
assert_ne!(user_stat_id, invalid_work_with_user_id_stat_id);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
use serde_json::json;
|
||||
use shared_contracts::runtime::{
|
||||
AdminUpsertProfileTaskConfigRequest, ProfileTaskConfigAdminResponse, TRACKING_SCOPE_KIND_USER,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn admin_upsert_profile_task_config_keeps_personal_task_scope_user() {
|
||||
let request: AdminUpsertProfileTaskConfigRequest = serde_json::from_value(json!({
|
||||
"taskId": "daily_login",
|
||||
"title": "每日登录",
|
||||
"description": "",
|
||||
"eventKey": "daily_login",
|
||||
"cycle": "daily",
|
||||
"scopeKind": "user",
|
||||
"threshold": 1,
|
||||
"rewardPoints": 10,
|
||||
"enabled": true,
|
||||
"sortOrder": 10
|
||||
}))
|
||||
.expect("个人任务配置请求应接受 user scope");
|
||||
|
||||
assert_eq!(request.scope_kind, TRACKING_SCOPE_KIND_USER);
|
||||
|
||||
let value = serde_json::to_value(request).expect("个人任务配置请求应可序列化");
|
||||
assert_eq!(value["scopeKind"], json!(TRACKING_SCOPE_KIND_USER));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profile_task_config_admin_response_serializes_scope_kind_as_user() {
|
||||
let response = ProfileTaskConfigAdminResponse {
|
||||
task_id: "daily_login".to_string(),
|
||||
title: "每日登录".to_string(),
|
||||
description: "".to_string(),
|
||||
event_key: "daily_login".to_string(),
|
||||
cycle: "daily".to_string(),
|
||||
scope_kind: TRACKING_SCOPE_KIND_USER.to_string(),
|
||||
threshold: 1,
|
||||
reward_points: 10,
|
||||
enabled: true,
|
||||
sort_order: 10,
|
||||
created_by: "admin".to_string(),
|
||||
created_at: "2026-05-04T00:00:00Z".to_string(),
|
||||
updated_by: "admin".to_string(),
|
||||
updated_at: "2026-05-04T00:00:00Z".to_string(),
|
||||
};
|
||||
|
||||
let value = serde_json::to_value(response).expect("个人任务配置响应应可序列化");
|
||||
assert_eq!(value["scopeKind"], json!(TRACKING_SCOPE_KIND_USER));
|
||||
assert_eq!(value["taskId"], json!("daily_login"));
|
||||
assert_eq!(value["rewardPoints"], json!(10));
|
||||
}
|
||||
@@ -47,11 +47,9 @@ pub trait accept_quest {
|
||||
&self,
|
||||
input: QuestRecordInput,
|
||||
|
||||
callback: impl FnOnce(
|
||||
&super::ReducerEventContext,
|
||||
Result<Result<(), String>, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
||||
+ Send
|
||||
+ 'static,
|
||||
) -> __sdk::Result<()>;
|
||||
}
|
||||
|
||||
@@ -60,11 +58,9 @@ impl accept_quest for super::RemoteReducers {
|
||||
&self,
|
||||
input: QuestRecordInput,
|
||||
|
||||
callback: impl FnOnce(
|
||||
&super::ReducerEventContext,
|
||||
Result<Result<(), String>, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
||||
+ Send
|
||||
+ 'static,
|
||||
) -> __sdk::Result<()> {
|
||||
self.imp
|
||||
.invoke_reducer_with_callback(AcceptQuestArgs { input }, callback)
|
||||
|
||||
+6
-10
@@ -47,11 +47,9 @@ pub trait acknowledge_quest_completion {
|
||||
&self,
|
||||
input: QuestCompletionAckInput,
|
||||
|
||||
callback: impl FnOnce(
|
||||
&super::ReducerEventContext,
|
||||
Result<Result<(), String>, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
||||
+ Send
|
||||
+ 'static,
|
||||
) -> __sdk::Result<()>;
|
||||
}
|
||||
|
||||
@@ -60,11 +58,9 @@ impl acknowledge_quest_completion for super::RemoteReducers {
|
||||
&self,
|
||||
input: QuestCompletionAckInput,
|
||||
|
||||
callback: impl FnOnce(
|
||||
&super::ReducerEventContext,
|
||||
Result<Result<(), String>, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
||||
+ Send
|
||||
+ 'static,
|
||||
) -> __sdk::Result<()> {
|
||||
self.imp
|
||||
.invoke_reducer_with_callback(AcknowledgeQuestCompletionArgs { input }, callback)
|
||||
|
||||
+8
-8
@@ -31,10 +31,10 @@ pub trait admin_disable_profile_redeem_code {
|
||||
input: RuntimeProfileRedeemCodeAdminDisableInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileRedeemCodeAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileRedeemCodeAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,10 +44,10 @@ impl admin_disable_profile_redeem_code for super::RemoteProcedures {
|
||||
input: RuntimeProfileRedeemCodeAdminDisableInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileRedeemCodeAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileRedeemCodeAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, RuntimeProfileRedeemCodeAdminProcedureResult>(
|
||||
|
||||
+8
-8
@@ -31,10 +31,10 @@ pub trait admin_disable_profile_task_config {
|
||||
input: RuntimeProfileTaskConfigAdminDisableInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileTaskConfigAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileTaskConfigAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,10 +44,10 @@ impl admin_disable_profile_task_config for super::RemoteProcedures {
|
||||
input: RuntimeProfileTaskConfigAdminDisableInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileTaskConfigAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileTaskConfigAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, RuntimeProfileTaskConfigAdminProcedureResult>(
|
||||
|
||||
+8
-8
@@ -31,10 +31,10 @@ pub trait admin_list_profile_invite_codes {
|
||||
input: RuntimeProfileInviteCodeAdminListInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileInviteCodeAdminListProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileInviteCodeAdminListProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,10 +44,10 @@ impl admin_list_profile_invite_codes for super::RemoteProcedures {
|
||||
input: RuntimeProfileInviteCodeAdminListInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileInviteCodeAdminListProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileInviteCodeAdminListProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, RuntimeProfileInviteCodeAdminListProcedureResult>(
|
||||
|
||||
+8
-8
@@ -31,10 +31,10 @@ pub trait admin_list_profile_redeem_codes {
|
||||
input: RuntimeProfileRedeemCodeAdminListInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileRedeemCodeAdminListProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileRedeemCodeAdminListProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,10 +44,10 @@ impl admin_list_profile_redeem_codes for super::RemoteProcedures {
|
||||
input: RuntimeProfileRedeemCodeAdminListInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileRedeemCodeAdminListProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileRedeemCodeAdminListProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, RuntimeProfileRedeemCodeAdminListProcedureResult>(
|
||||
|
||||
+8
-8
@@ -31,10 +31,10 @@ pub trait admin_list_profile_task_configs {
|
||||
input: RuntimeProfileTaskConfigAdminListInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileTaskConfigAdminListProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileTaskConfigAdminListProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,10 +44,10 @@ impl admin_list_profile_task_configs for super::RemoteProcedures {
|
||||
input: RuntimeProfileTaskConfigAdminListInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileTaskConfigAdminListProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileTaskConfigAdminListProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, RuntimeProfileTaskConfigAdminListProcedureResult>(
|
||||
|
||||
+8
-8
@@ -31,10 +31,10 @@ pub trait admin_upsert_profile_invite_code {
|
||||
input: RuntimeProfileInviteCodeAdminUpsertInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileInviteCodeAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileInviteCodeAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,10 +44,10 @@ impl admin_upsert_profile_invite_code for super::RemoteProcedures {
|
||||
input: RuntimeProfileInviteCodeAdminUpsertInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileInviteCodeAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileInviteCodeAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, RuntimeProfileInviteCodeAdminProcedureResult>(
|
||||
|
||||
+8
-8
@@ -31,10 +31,10 @@ pub trait admin_upsert_profile_redeem_code {
|
||||
input: RuntimeProfileRedeemCodeAdminUpsertInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileRedeemCodeAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileRedeemCodeAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,10 +44,10 @@ impl admin_upsert_profile_redeem_code for super::RemoteProcedures {
|
||||
input: RuntimeProfileRedeemCodeAdminUpsertInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileRedeemCodeAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileRedeemCodeAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, RuntimeProfileRedeemCodeAdminProcedureResult>(
|
||||
|
||||
+8
-8
@@ -31,10 +31,10 @@ pub trait admin_upsert_profile_task_config {
|
||||
input: RuntimeProfileTaskConfigAdminUpsertInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileTaskConfigAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileTaskConfigAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,10 +44,10 @@ impl admin_upsert_profile_task_config for super::RemoteProcedures {
|
||||
input: RuntimeProfileTaskConfigAdminUpsertInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileTaskConfigAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileTaskConfigAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, RuntimeProfileTaskConfigAdminProcedureResult>(
|
||||
|
||||
+8
-8
@@ -31,10 +31,10 @@ pub trait advance_puzzle_next_level {
|
||||
input: PuzzleRunNextLevelInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<PuzzleRunProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
&super::ProcedureEventContext,
|
||||
Result<PuzzleRunProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,10 +44,10 @@ impl advance_puzzle_next_level for super::RemoteProcedures {
|
||||
input: PuzzleRunNextLevelInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<PuzzleRunProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
&super::ProcedureEventContext,
|
||||
Result<PuzzleRunProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, PuzzleRunProcedureResult>(
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use super::ai_result_reference_kind_type::AiResultReferenceKind;
|
||||
use super::ai_result_reference_type::AiResultReference;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `ai_result_reference`.
|
||||
///
|
||||
/// Obtain a handle from the [`AiResultReferenceTableAccess::ai_result_reference`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.ai_result_reference()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.ai_result_reference().on_insert(...)`.
|
||||
pub struct AiResultReferenceTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<AiResultReference>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `ai_result_reference`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait AiResultReferenceTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`AiResultReferenceTableHandle`], which mediates access to the table `ai_result_reference`.
|
||||
fn ai_result_reference(&self) -> AiResultReferenceTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl AiResultReferenceTableAccess for super::RemoteTables {
|
||||
fn ai_result_reference(&self) -> AiResultReferenceTableHandle<'_> {
|
||||
AiResultReferenceTableHandle {
|
||||
imp: self
|
||||
.imp
|
||||
.get_table::<AiResultReference>("ai_result_reference"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AiResultReferenceInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct AiResultReferenceDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for AiResultReferenceTableHandle<'ctx> {
|
||||
type Row = AiResultReference;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = AiResultReference> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = AiResultReferenceInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> AiResultReferenceInsertCallbackId {
|
||||
AiResultReferenceInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: AiResultReferenceInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = AiResultReferenceDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> AiResultReferenceDeleteCallbackId {
|
||||
AiResultReferenceDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: AiResultReferenceDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AiResultReferenceUpdateCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::TableWithPrimaryKey for AiResultReferenceTableHandle<'ctx> {
|
||||
type UpdateCallbackId = AiResultReferenceUpdateCallbackId;
|
||||
|
||||
fn on_update(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||
) -> AiResultReferenceUpdateCallbackId {
|
||||
AiResultReferenceUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_update(&self, callback: AiResultReferenceUpdateCallbackId) {
|
||||
self.imp.remove_on_update(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Access to the `result_reference_row_id` unique index on the table `ai_result_reference`,
|
||||
/// which allows point queries on the field of the same name
|
||||
/// via the [`AiResultReferenceResultReferenceRowIdUnique::find`] method.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.ai_result_reference().result_reference_row_id().find(...)`.
|
||||
pub struct AiResultReferenceResultReferenceRowIdUnique<'ctx> {
|
||||
imp: __sdk::UniqueConstraintHandle<AiResultReference, String>,
|
||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
impl<'ctx> AiResultReferenceTableHandle<'ctx> {
|
||||
/// Get a handle on the `result_reference_row_id` unique index on the table `ai_result_reference`.
|
||||
pub fn result_reference_row_id(&self) -> AiResultReferenceResultReferenceRowIdUnique<'ctx> {
|
||||
AiResultReferenceResultReferenceRowIdUnique {
|
||||
imp: self
|
||||
.imp
|
||||
.get_unique_constraint::<String>("result_reference_row_id"),
|
||||
phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> AiResultReferenceResultReferenceRowIdUnique<'ctx> {
|
||||
/// Find the subscribed row whose `result_reference_row_id` column value is equal to `col_val`,
|
||||
/// if such a row is present in the client cache.
|
||||
pub fn find(&self, col_val: &String) -> Option<AiResultReference> {
|
||||
self.imp.find(col_val)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||
let _table = client_cache.get_or_make_table::<AiResultReference>("ai_result_reference");
|
||||
_table.add_unique_constraint::<String>("result_reference_row_id", |row| {
|
||||
&row.result_reference_row_id
|
||||
});
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::v2::TableUpdate,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<AiResultReference>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse("TableUpdate<AiResultReference>", "TableUpdate")
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for query builder access to the table `AiResultReference`.
|
||||
///
|
||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||
pub trait ai_result_referenceQueryTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Get a query builder for the table `AiResultReference`.
|
||||
fn ai_result_reference(&self) -> __sdk::__query_builder::Table<AiResultReference>;
|
||||
}
|
||||
|
||||
impl ai_result_referenceQueryTableAccess for __sdk::QueryTableAccessor {
|
||||
fn ai_result_reference(&self) -> __sdk::__query_builder::Table<AiResultReference> {
|
||||
__sdk::__query_builder::Table::new("ai_result_reference")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use super::ai_task_stage_kind_type::AiTaskStageKind;
|
||||
use super::ai_task_stage_status_type::AiTaskStageStatus;
|
||||
use super::ai_task_stage_type::AiTaskStage;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `ai_task_stage`.
|
||||
///
|
||||
/// Obtain a handle from the [`AiTaskStageTableAccess::ai_task_stage`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.ai_task_stage()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.ai_task_stage().on_insert(...)`.
|
||||
pub struct AiTaskStageTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<AiTaskStage>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `ai_task_stage`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait AiTaskStageTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`AiTaskStageTableHandle`], which mediates access to the table `ai_task_stage`.
|
||||
fn ai_task_stage(&self) -> AiTaskStageTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl AiTaskStageTableAccess for super::RemoteTables {
|
||||
fn ai_task_stage(&self) -> AiTaskStageTableHandle<'_> {
|
||||
AiTaskStageTableHandle {
|
||||
imp: self.imp.get_table::<AiTaskStage>("ai_task_stage"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AiTaskStageInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct AiTaskStageDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for AiTaskStageTableHandle<'ctx> {
|
||||
type Row = AiTaskStage;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = AiTaskStage> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = AiTaskStageInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> AiTaskStageInsertCallbackId {
|
||||
AiTaskStageInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: AiTaskStageInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = AiTaskStageDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> AiTaskStageDeleteCallbackId {
|
||||
AiTaskStageDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: AiTaskStageDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AiTaskStageUpdateCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::TableWithPrimaryKey for AiTaskStageTableHandle<'ctx> {
|
||||
type UpdateCallbackId = AiTaskStageUpdateCallbackId;
|
||||
|
||||
fn on_update(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||
) -> AiTaskStageUpdateCallbackId {
|
||||
AiTaskStageUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_update(&self, callback: AiTaskStageUpdateCallbackId) {
|
||||
self.imp.remove_on_update(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Access to the `task_stage_id` unique index on the table `ai_task_stage`,
|
||||
/// which allows point queries on the field of the same name
|
||||
/// via the [`AiTaskStageTaskStageIdUnique::find`] method.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.ai_task_stage().task_stage_id().find(...)`.
|
||||
pub struct AiTaskStageTaskStageIdUnique<'ctx> {
|
||||
imp: __sdk::UniqueConstraintHandle<AiTaskStage, String>,
|
||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
impl<'ctx> AiTaskStageTableHandle<'ctx> {
|
||||
/// Get a handle on the `task_stage_id` unique index on the table `ai_task_stage`.
|
||||
pub fn task_stage_id(&self) -> AiTaskStageTaskStageIdUnique<'ctx> {
|
||||
AiTaskStageTaskStageIdUnique {
|
||||
imp: self.imp.get_unique_constraint::<String>("task_stage_id"),
|
||||
phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> AiTaskStageTaskStageIdUnique<'ctx> {
|
||||
/// Find the subscribed row whose `task_stage_id` column value is equal to `col_val`,
|
||||
/// if such a row is present in the client cache.
|
||||
pub fn find(&self, col_val: &String) -> Option<AiTaskStage> {
|
||||
self.imp.find(col_val)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||
let _table = client_cache.get_or_make_table::<AiTaskStage>("ai_task_stage");
|
||||
_table.add_unique_constraint::<String>("task_stage_id", |row| &row.task_stage_id);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::v2::TableUpdate,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<AiTaskStage>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse("TableUpdate<AiTaskStage>", "TableUpdate")
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for query builder access to the table `AiTaskStage`.
|
||||
///
|
||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||
pub trait ai_task_stageQueryTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Get a query builder for the table `AiTaskStage`.
|
||||
fn ai_task_stage(&self) -> __sdk::__query_builder::Table<AiTaskStage>;
|
||||
}
|
||||
|
||||
impl ai_task_stageQueryTableAccess for __sdk::QueryTableAccessor {
|
||||
fn ai_task_stage(&self) -> __sdk::__query_builder::Table<AiTaskStage> {
|
||||
__sdk::__query_builder::Table::new("ai_task_stage")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use super::ai_task_kind_type::AiTaskKind;
|
||||
use super::ai_task_status_type::AiTaskStatus;
|
||||
use super::ai_task_type::AiTask;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `ai_task`.
|
||||
///
|
||||
/// Obtain a handle from the [`AiTaskTableAccess::ai_task`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.ai_task()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.ai_task().on_insert(...)`.
|
||||
pub struct AiTaskTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<AiTask>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `ai_task`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait AiTaskTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`AiTaskTableHandle`], which mediates access to the table `ai_task`.
|
||||
fn ai_task(&self) -> AiTaskTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl AiTaskTableAccess for super::RemoteTables {
|
||||
fn ai_task(&self) -> AiTaskTableHandle<'_> {
|
||||
AiTaskTableHandle {
|
||||
imp: self.imp.get_table::<AiTask>("ai_task"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AiTaskInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct AiTaskDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for AiTaskTableHandle<'ctx> {
|
||||
type Row = AiTask;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = AiTask> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = AiTaskInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> AiTaskInsertCallbackId {
|
||||
AiTaskInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: AiTaskInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = AiTaskDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> AiTaskDeleteCallbackId {
|
||||
AiTaskDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: AiTaskDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AiTaskUpdateCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::TableWithPrimaryKey for AiTaskTableHandle<'ctx> {
|
||||
type UpdateCallbackId = AiTaskUpdateCallbackId;
|
||||
|
||||
fn on_update(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||
) -> AiTaskUpdateCallbackId {
|
||||
AiTaskUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_update(&self, callback: AiTaskUpdateCallbackId) {
|
||||
self.imp.remove_on_update(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Access to the `task_id` unique index on the table `ai_task`,
|
||||
/// which allows point queries on the field of the same name
|
||||
/// via the [`AiTaskTaskIdUnique::find`] method.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.ai_task().task_id().find(...)`.
|
||||
pub struct AiTaskTaskIdUnique<'ctx> {
|
||||
imp: __sdk::UniqueConstraintHandle<AiTask, String>,
|
||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
impl<'ctx> AiTaskTableHandle<'ctx> {
|
||||
/// Get a handle on the `task_id` unique index on the table `ai_task`.
|
||||
pub fn task_id(&self) -> AiTaskTaskIdUnique<'ctx> {
|
||||
AiTaskTaskIdUnique {
|
||||
imp: self.imp.get_unique_constraint::<String>("task_id"),
|
||||
phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> AiTaskTaskIdUnique<'ctx> {
|
||||
/// Find the subscribed row whose `task_id` column value is equal to `col_val`,
|
||||
/// if such a row is present in the client cache.
|
||||
pub fn find(&self, col_val: &String) -> Option<AiTask> {
|
||||
self.imp.find(col_val)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||
let _table = client_cache.get_or_make_table::<AiTask>("ai_task");
|
||||
_table.add_unique_constraint::<String>("task_id", |row| &row.task_id);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::v2::TableUpdate,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<AiTask>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse("TableUpdate<AiTask>", "TableUpdate")
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for query builder access to the table `AiTask`.
|
||||
///
|
||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||
pub trait ai_taskQueryTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Get a query builder for the table `AiTask`.
|
||||
fn ai_task(&self) -> __sdk::__query_builder::Table<AiTask>;
|
||||
}
|
||||
|
||||
impl ai_taskQueryTableAccess for __sdk::QueryTableAccessor {
|
||||
fn ai_task(&self) -> __sdk::__query_builder::Table<AiTask> {
|
||||
__sdk::__query_builder::Table::new("ai_task")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use super::ai_task_stage_kind_type::AiTaskStageKind;
|
||||
use super::ai_text_chunk_type::AiTextChunk;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `ai_text_chunk`.
|
||||
///
|
||||
/// Obtain a handle from the [`AiTextChunkTableAccess::ai_text_chunk`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.ai_text_chunk()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.ai_text_chunk().on_insert(...)`.
|
||||
pub struct AiTextChunkTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<AiTextChunk>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `ai_text_chunk`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait AiTextChunkTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`AiTextChunkTableHandle`], which mediates access to the table `ai_text_chunk`.
|
||||
fn ai_text_chunk(&self) -> AiTextChunkTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl AiTextChunkTableAccess for super::RemoteTables {
|
||||
fn ai_text_chunk(&self) -> AiTextChunkTableHandle<'_> {
|
||||
AiTextChunkTableHandle {
|
||||
imp: self.imp.get_table::<AiTextChunk>("ai_text_chunk"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AiTextChunkInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct AiTextChunkDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for AiTextChunkTableHandle<'ctx> {
|
||||
type Row = AiTextChunk;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = AiTextChunk> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = AiTextChunkInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> AiTextChunkInsertCallbackId {
|
||||
AiTextChunkInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: AiTextChunkInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = AiTextChunkDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> AiTextChunkDeleteCallbackId {
|
||||
AiTextChunkDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: AiTextChunkDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AiTextChunkUpdateCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::TableWithPrimaryKey for AiTextChunkTableHandle<'ctx> {
|
||||
type UpdateCallbackId = AiTextChunkUpdateCallbackId;
|
||||
|
||||
fn on_update(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||
) -> AiTextChunkUpdateCallbackId {
|
||||
AiTextChunkUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_update(&self, callback: AiTextChunkUpdateCallbackId) {
|
||||
self.imp.remove_on_update(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Access to the `text_chunk_row_id` unique index on the table `ai_text_chunk`,
|
||||
/// which allows point queries on the field of the same name
|
||||
/// via the [`AiTextChunkTextChunkRowIdUnique::find`] method.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.ai_text_chunk().text_chunk_row_id().find(...)`.
|
||||
pub struct AiTextChunkTextChunkRowIdUnique<'ctx> {
|
||||
imp: __sdk::UniqueConstraintHandle<AiTextChunk, String>,
|
||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
impl<'ctx> AiTextChunkTableHandle<'ctx> {
|
||||
/// Get a handle on the `text_chunk_row_id` unique index on the table `ai_text_chunk`.
|
||||
pub fn text_chunk_row_id(&self) -> AiTextChunkTextChunkRowIdUnique<'ctx> {
|
||||
AiTextChunkTextChunkRowIdUnique {
|
||||
imp: self
|
||||
.imp
|
||||
.get_unique_constraint::<String>("text_chunk_row_id"),
|
||||
phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> AiTextChunkTextChunkRowIdUnique<'ctx> {
|
||||
/// Find the subscribed row whose `text_chunk_row_id` column value is equal to `col_val`,
|
||||
/// if such a row is present in the client cache.
|
||||
pub fn find(&self, col_val: &String) -> Option<AiTextChunk> {
|
||||
self.imp.find(col_val)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||
let _table = client_cache.get_or_make_table::<AiTextChunk>("ai_text_chunk");
|
||||
_table.add_unique_constraint::<String>("text_chunk_row_id", |row| &row.text_chunk_row_id);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::v2::TableUpdate,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<AiTextChunk>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse("TableUpdate<AiTextChunk>", "TableUpdate")
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for query builder access to the table `AiTextChunk`.
|
||||
///
|
||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||
pub trait ai_text_chunkQueryTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Get a query builder for the table `AiTextChunk`.
|
||||
fn ai_text_chunk(&self) -> __sdk::__query_builder::Table<AiTextChunk>;
|
||||
}
|
||||
|
||||
impl ai_text_chunkQueryTableAccess for __sdk::QueryTableAccessor {
|
||||
fn ai_text_chunk(&self) -> __sdk::__query_builder::Table<AiTextChunk> {
|
||||
__sdk::__query_builder::Table::new("ai_text_chunk")
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct AnalyticsDateDimensionEnsureInput {
|
||||
pub date_key: i64,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for AnalyticsDateDimensionEnsureInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct AnalyticsDateDimensionSeedInput {
|
||||
pub start_date: String,
|
||||
pub end_date: String,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for AnalyticsDateDimensionSeedInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user