把活层退役旧品牌「造梦AI」统一改为现行「绘境AI」,brand-invariant 门红线归零。构成: ~412 Java @author 署名 + game-studio/index.html 浏览器标题 + game-runtime/package.json 描述 + game-admin/.env VITE_APP_TITLE 运营后台标题 + contracts API title/@Schema 用户协议示例/events 描述 + docs-design mockup 品牌位 + 各模块注释。全是注释/显示/元数据,零逻辑改动。 zaomeng 拼音持久化标识符按 2026-06-24 评审 GR-05 不动(347 处保留)。 白名单(docs/ip 法律备案 / _archive / 带日期留痕)与 AGENTS.md 门定义自身不动。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
74 lines
5.8 KiB
JSON
74 lines
5.8 KiB
JSON
{
|
||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||
"$id": "https://wanxiang.ai/contracts/events.schema.json",
|
||
"title": "TelemetryEvents",
|
||
"description": "绘境AI 遥测事件契约 v1(契约 #5,owner=WS5)。前端批量上报 / SDK 上报 → /app-api/telemetry/events/batch → MQ 异步入库 → qualityScore → feed 排序(数据回路闭环)。每事件带 schemaVersion;新增字段给默认值、老消费者忽略未知字段;不兼容变更用新事件名。【Wave3 GAP-4 评审记录】利用无生产数据 + MQ 未实现窗口,一次性把信封 envelope/user 由 snake_case 统一为 camelCase(与 telemetry.yaml 及前端 SDK 对齐),保持 additionalProperties:false;豁免本文件 README §2『不兼容变更用新事件名并行』规则(本次改的是信封字段命名而非事件名),已确认仓外无 snake_case 消费者(telemetry.yaml/sdk-interface.d.ts/game-studio 均为 camelCase)。",
|
||
"type": "object",
|
||
"required": ["envelope", "eventRegistry"],
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"envelope": {
|
||
"description": "事件信封(所有事件共用)。批量上报时为 { batch: Envelope[] }。",
|
||
"type": "object",
|
||
"required": ["event", "schemaVersion", "ts", "traceId", "eventId"],
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"event": { "description": "事件名(见 eventRegistry 键)", "type": "string" },
|
||
"schemaVersion": { "description": "事件 Schema 版本,如 v1 / v2", "type": "string", "pattern": "^v[0-9]+$" },
|
||
"ts": { "description": "事件发生时间戳(毫秒)", "type": "integer" },
|
||
"traceId": { "description": "全链路追踪 ID,贯穿生成→编译→加载→运行→上报", "type": "string" },
|
||
"eventId": { "description": "事件实例 UUID(每事件实例唯一,幂等真身)。前端 crypto.randomUUID() 生成;服务端落 game_telemetry_event.event_id(uk_event_id 唯一键),重放同 eventId 不重复计数。", "type": "string" },
|
||
"sessionId": { "description": "会话 ID(一次游戏流消费/一次创作会话)", "type": "string" },
|
||
"user": {
|
||
"description": "用户标识。匿名玩家用 anonId;登录后带 userId。",
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"userId": { "type": "string" },
|
||
"anonId": { "description": "纯客户端生成的稳定匿名 ID(localStorage 持久化;身份不可信,防伪造/刷量由聚合侧按 anonId/IP 异常剔除兜底——2026-06-10 鉴权拍板 §9-7=B,取代旧'匿名 token 派生'机制)", "type": "string" }
|
||
}
|
||
},
|
||
"context": {
|
||
"description": "上下文",
|
||
"type": "object",
|
||
"additionalProperties": true,
|
||
"properties": {
|
||
"gameId": { "type": "string" },
|
||
"versionId": { "type": "string" },
|
||
"channel": { "description": "渠道归因(utm/channel 解析)", "type": "string" },
|
||
"deviceType": { "type": "string", "enum": ["mobile", "desktop", "miniapp"] }
|
||
}
|
||
},
|
||
"props": { "description": "事件私有字段(结构见对应 eventRegistry 项)", "type": "object" }
|
||
}
|
||
},
|
||
"eventRegistry": {
|
||
"description": "v1 核心事件登记表。值为该事件 props 的字段说明。覆盖:创作漏斗 / 消费漏斗 / 互动 / 广告 / 变现 / 性能。",
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"create_start": { "description": "创作会话开始", "type": "object" },
|
||
"generate_submit": { "description": "提交生成。props: template_id, prompt_hash", "type": "object" },
|
||
"generate_succeeded": { "description": "生成成功。props: task_id, duration_ms(用于 ≥80% 成功率统计)", "type": "object" },
|
||
"generate_failed": { "description": "生成失败。props: task_id, reason_code(失败原因分类)", "type": "object" },
|
||
"preview_play": { "description": "预览试玩", "type": "object" },
|
||
"publish_submit": { "description": "提交发布审核", "type": "object" },
|
||
"feed_view": { "description": "进入游戏流", "type": "object" },
|
||
"user_login": { "description": "登录成功后前端补发(匿名↔登录身份衔接,2026-06-10 鉴权件)。envelope.user 双带 userId+anonId,把此前匿名 anonId 与登录 userId 关联,消除 1001/1 错位", "type": "object" },
|
||
"game_impression": { "description": "游戏卡片曝光(首屏封面)。feed 排序信号", "type": "object" },
|
||
"game_load_failed": { "description": "加载失败(超时5s跳过触发)。props: reason。降权信号", "type": "object" },
|
||
"game_play_start": { "description": "试玩开始", "type": "object" },
|
||
"game_play_end": { "description": "试玩结束。props: duration_ms, completed(完玩)。quality_score 输入", "type": "object" },
|
||
"like": { "description": "点赞", "type": "object" },
|
||
"favorite": { "description": "收藏", "type": "object" },
|
||
"share": { "description": "分享", "type": "object" },
|
||
"report": { "description": "举报。props: reason。举报阈值降权信号", "type": "object" },
|
||
"ad_impression": { "description": "广告展示上报。props: slot_id, provider", "type": "object" },
|
||
"ad_reward": { "description": "激励视频完成。props: slot_id", "type": "object" },
|
||
"income_settled": { "description": "收益归集(T+1)。props: amount, source", "type": "object" },
|
||
"perf_first_screen": { "description": "首屏加载耗时埋点(P75<3s 验收)。props: ms", "type": "object" }
|
||
}
|
||
}
|
||
}
|
||
}
|