games-development-ai/docs-design/Technical Design Document.md

1172 lines
45 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Technical Design Document
# 绘境AI生态平台MVP Technical Design Document
## Product Overview
Context for the technical design.
本技术设计文档面向将要实现绘境AI生态平台MVP的工程团队基于现有PRD目标将“一句话AI生成轻量小游戏、游戏流即点即玩、创作者发布与基础数据反馈、运营审核与推荐管理”落地为可实施的系统架构、数据模型、接口设计、测试方案和部署方案。
MVP技术策略采用“模板约束生成 + Web运行容器 + 异步任务队列 + 规则推荐”的方案优先保障端到端闭环稳定性而不是追求完全开放式代码生成。生成结果以配置化游戏工程为主通过统一运行时容器在Web端加载运行便于性能控制、内容审核、埋点采集和后续扩展。
### Purpose
- 解决的问题
- 非技术创作者无法将游戏创意快速转化为可试玩作品。
- 玩家发现轻量小游戏成本高,传统游戏分发依赖下载、安装和复杂选择。
- 平台早期需要验证AI创作供给、游戏流消费和数据反馈是否能形成生态闭环。
- 技术机会
- 使用大模型理解自然语言Prompt并映射到受控玩法模板和参数配置。
- 使用Web小游戏运行容器实现即点即玩降低分发门槛。
- 使用事件埋点和内容质量信号,为后续推荐和商业化提供数据基础。
- 使用内容安全检测与审核后台降低UGC和AI生成内容的合规风险。
- 典型用户场景
- 创作者输入“做一个像素风太空躲避游戏飞船躲避陨石并收集能量坚持60秒获胜”系统生成可预览小游戏并允许编辑标题、封面和发布。
- 玩家进入首页后像刷短视频一样上下滑动试玩小游戏,支持点赞、收藏、分享和举报。
- 运营人员进入后台审核新发布游戏,试玩后执行通过、拒绝、下架或加入精选池。
- 团队通过数据看板查看生成成功率、游戏加载时间、试玩转化、互动率和举报率。
### Target Audience
- 普通创作者 / 非技术用户
- 需求:无需编程、美术和引擎知识即可生成可玩游戏。
- 技术支持Prompt输入、模板选择、异步生成进度、浏览器预览、保存草稿、发布到站内游戏流。
- 进阶UGC创作者 / 游戏达人
- 需求:快速批量产出轻量小游戏,观察数据并优化标题、封面、规则和标签。
- 技术支持:模板参数可调、版本覆盖更新、基础数据看板、分享链接和渠道参数。
- 玩家 / 轻量游戏消费者
- 需求:无需下载,低决策成本连续发现和试玩小游戏。
- 技术支持移动优先游戏流、资源预加载、CDN加速、错误自动跳过、互动反馈。
- 平台运营人员
- 需求:控制内容质量、安全合规和冷启动推荐效果。
- 技术支持:审核队列、试玩预览、风险标记、精选池、曝光限制和操作日志。
- 系统管理员 / 工程团队
- 需求:监控生成任务、运行错误、服务健康度、权限边界和安全风险。
- 技术支持结构化日志、指标看板、告警、RBAC、审计日志和回滚机制。
### Expected Outcomes
- 短期业务结果
- MVP上线后8周内支持500名注册创作者。
- 至少100名创作者完成1款游戏发布。
- 累计上线300款可试玩小游戏。
- 玩家单次会话平均试玩不少于3款游戏。
- 技术结果
- 生成任务成功率不低于85%。
- 平台核心链路可用性不低于99%。
- 游戏流首屏可交互时间P75低于3秒P95低于6秒。
- 游戏加载或运行阻断性错误率低于3%。
- 核心事件上报成功率不低于99%。
- 长期影响
- 为后续可视化编辑器、个性化推荐、广告分成、多渠道自动发布和素材市场建立可扩展架构。
- 沉淀Prompt、模板参数、互动行为和内容质量数据用于优化生成质量和推荐策略。
## Architecture
The structural design of the system.
### High-Level Architecture
- 推荐技术栈
- FrontendNext.js 14、React、TypeScript、Tailwind CSS、Zustand、React Query。
- Game RuntimePhaser 3 + 自研Game SDK桥接层优先支持2D轻量小游戏。
- BackendNestJS、TypeScript、REST API按模块化单体起步预留服务拆分边界。
- DatabasePostgreSQL 15使用Prisma ORM管理Schema和Migration。
- Cache / QueueRedis 7BullMQ用于异步生成、审核、资源打包、事件聚合任务。
- Object Storage阿里云OSS或AWS S3存储封面、上传素材、生成素材和游戏包。
- CDN阿里云CDN、CloudFront或Cloudflare用于游戏资源、封面图和静态前端加速。
- Search / Analytics MVPPostgreSQL聚合表 + ClickHouse可选MVP先用PostgreSQL分区事件表增长后迁移ClickHouse。
- AuthJWT + Refresh Token匿名游客使用anonymous_id Cookie / localStorage标识。
- ObservabilityOpenTelemetry、Prometheus、Grafana、Sentry、Loki或云日志服务。
- 主要组件
- Web App
- 创作工作台Prompt输入、模板选择、生成状态、预览、发布。
- 玩家游戏流:游戏卡片、预加载、滑动切换、互动、举报。
- 创作者后台:我的游戏、数据概览、草稿和发布状态。
- 运营后台:审核、试玩、推荐池、下架、用户权限。
- API Server
- 账号与权限模块。
- 游戏与版本管理模块。
- 生成任务模块。
- 发布与审核模块。
- 游戏流推荐模块。
- 互动与埋点模块。
- 文件上传与资源签名模块。
- Generation Worker
- 接收Prompt生成任务。
- 调用LLM解析游戏意图。
- 选择玩法模板并生成GameConfig。
- 调用素材生成服务或使用内置素材库。
- 打包游戏资源并输出可运行Manifest。
- Moderation Worker
- 检测Prompt、标题、简介、封面和上传素材。
- 输出风险等级、命中策略和审核建议。
- Event Worker
- 批量消费前端埋点。
- 写入事件表并更新聚合指标。
- Recommendation Service
- MVP为规则策略可在API Server内实现。
- 根据精选池、新发布、质量分、用户互动和加载错误率返回游戏列表。
- 通信协议
- 前端与后端REST over HTTPS。
- 生成任务状态优先Server-Sent Events或轮询MVP可使用2秒轮询后续升级WebSocket。
- Worker任务BullMQ over Redis。
- 静态资源HTTPS + CDN。
- 第三方AI服务HTTPS API。
- 设计模式
- Modular MonolithMVP阶段降低部署和运维复杂度同时保持模块边界。
- Event-driven生成、审核、发布、互动、埋点和指标聚合使用事件驱动。
- CQRS Lite写入操作走业务表读取高频的游戏流和数据看板使用聚合表或缓存。
- State MachineGenerationTask、Game、ReviewRecord采用明确状态机避免状态混乱。
### Data Structures & Algorithms
- 核心数据结构
- GameConfig
- JSON结构描述玩法模板、参数、关卡、角色、素材、胜负条件和UI文案。
- 选择理由便于受控生成、版本管理、Web运行时加载和安全校验。
- GameManifest
- JSON结构描述运行入口、资源列表、版本号、校验hash、SDK版本和预加载策略。
- 选择理由前端游戏容器可根据Manifest统一加载不同游戏。
- FeedItem
- 包含game_id、creator_id、score、reason、preload_assets、interaction_state。
- 选择理由:解耦推荐计算和前端展示。
- EventPayload
- 标准化埋点结构event_name、user_id、anonymous_id、game_id、session_id、timestamp、properties。
- 选择理由:便于漏斗、留存和内容质量分析。
- GameConfig示例
```json
{
"template": "avoidance_v1",
"theme": "pixel_space",
"durationSeconds": 60,
"player": {
"sprite": "ship_blue",
"speed": 320,
"hitPoints": 3
},
"objectives": \[
{ "type": "survive", "seconds": 60 },
{ "type": "collect", "item": "energy", "target": 20 }
\],
"enemies": \[
{ "type": "asteroid", "spawnRatePerSecond": 1.2, "speedRange": \[120, 260\] }
\],
"controls": {
"mobile": "drag",
"desktop": "arrow_keys"
},
"winCondition": "survive_and_collect",
"loseCondition": "hp_zero"
}
```
- 关键算法
- Prompt到模板映射
- 输入用户Prompt、用户选择模板、风格标签。
- 输出template_id、confidence、normalized_parameters。
- MVP实现LLM分类 + 规则兜底。
- 复杂度O(T)T为模板数量MVP模板数量小于10性能可忽略。
- 游戏配置校验
- 输入GameConfig。
- 输出validated_config或错误列表。
- 规则:数值范围、必填字段、资源引用、关卡长度、资源体积、敏感词。
- 复杂度O(N)N为配置节点数。
- 游戏流排序
- MVP评分公式score = base_weight + recency_score + quality_score + interaction_score + creator_boost - risk_penalty - error_penalty。
- 冷启动权重:精选池、最新发布、每个新作保底曝光。
- 复杂度候选集过滤O(N)排序O(N log N)。N通过分页候选集控制在200以内。
- 内容质量分
- quality_score基于试玩完成率、30秒留存、点赞率、收藏率、举报率、加载失败率。
- 每小时或每15分钟由Event Worker聚合更新。
- 扩展与性能考虑
- 生成任务使用队列削峰避免LLM和打包服务阻塞主API。
- 游戏资源限制MVP单包不超过10MB首屏关键资源不超过2MB。
- 热门游戏Manifest和元数据缓存到RedisTTL 60至300秒。
- 游戏资源文件使用hash命名启用长期CDN缓存。
- 埋点批量上报前端每10条或5秒flush一次避免影响游戏帧率。
### System Interfaces
- API endpoints
|Method|Route|Purpose|Auth|
| --------| -------------------------------------------| ----------------------------------| ---------------|
|POST|/api/v1/auth/login|登录并返回访问令牌|Public|
|POST|/api/v1/auth/refresh|刷新访问令牌|Refresh Token|
|GET|/api/v1/me|获取当前用户资料与角色|User|
|POST|/api/v1/generation/tasks|创建AI生成任务|Creator|
|GET|/api/v1/generation/tasks/{taskId}|查询生成任务状态|Creator|
|POST|/api/v1/games|从生成结果创建游戏草稿|Creator|
|GET|/api/v1/games/{gameId}|获取游戏详情|Public/Owner|
|PATCH|/api/v1/games/{gameId}|更新标题、简介、封面、标签和参数|Owner|
|POST|/api/v1/games/{gameId}/publish|提交发布|Owner|
|GET|/api/v1/feed|获取游戏流列表|Public|
|POST|/api/v1/interactions|点赞、收藏、分享、举报|User|
|POST|/api/v1/events/batch|批量上报埋点事件|Public|
|GET|/api/v1/creator/games|获取创作者游戏列表|Creator|
|GET|/api/v1/creator/games/{gameId}/stats|获取单游戏数据看板|Owner|
|GET|/api/v1/admin/reviews|获取审核队列|Operator|
|POST|/api/v1/admin/reviews/{reviewId}/decision|审核通过、拒绝或下架|Operator|
|POST|/api/v1/admin/featured-games|加入精选池|Operator|
- 创建生成任务请求示例
```json
{
"prompt": "做一个像素风太空躲避游戏玩家控制飞船躲避陨石收集能量块坚持60秒获胜。",
"templateHint": "avoidance",
"styleTags": \["pixel", "space"\],
"uploadedAssetIds": \["asset_01HXYZ"\]
}
```
- 创建生成任务响应示例
```json
{
"taskId": "gt_01HZA9Z9H4Q7",
"status": "queued",
"estimatedSeconds": 90,
"pollingIntervalMs": 2000
}
```
- 查询生成任务响应示例
```json
{
"taskId": "gt_01HZA9Z9H4Q7",
"status": "succeeded",
"progress": 100,
"currentStep": "preview_ready",
"gameDraft": {
"gameId": "game_01HZAA1M0KQ8",
"buildId": "build_01HZAA1R9QA3",
"previewUrl": "https://cdn.example.com/games/build_01HZAA1R9QA3/index.html"
},
"error": null
}
```
- 获取游戏流请求示例
```http
GET /api/v1/feed?cursor=eyJzY29yZSI6MTIzfQ&limit=10&device=mobile
Authorization: Bearer optional
```
- 获取游戏流响应示例
```json
{
"items": \[
{
"gameId": "game_01HZAA1M0KQ8",
"title": "像素太空逃亡",
"description": "躲避陨石并收集能量坚持60秒。",
"coverUrl": "https://cdn.example.com/covers/game_01HZAA1M0KQ8.webp",
"creator": {
"userId": "user_123",
"nickname": "小林"
},
"manifestUrl": "https://cdn.example.com/manifests/build_01HZAA1R9QA3.json",
"preloadAssets": \[
"https://cdn.example.com/assets/ship.webp",
"https://cdn.example.com/assets/bg.webp"
\],
"interactionState": {
"liked": false,
"favorited": false
},
"reason": "featured_and_new"
}
\],
"nextCursor": "eyJzY29yZSI6MTE5fQ"
}
```
- 批量埋点请求示例
```json
{
"sessionId": "sess_01HZAB",
"anonymousId": "anon_abc",
"events": \[
{
"eventName": "game_impression",
"occurredAt": "2026-05-28T10:00:00.000Z",
"gameId": "game_01HZAA1M0KQ8",
"properties": {
"position": 1,
"feedRequestId": "feed_req_123"
}
},
{
"eventName": "game_play_30s",
"occurredAt": "2026-05-28T10:00:32.000Z",
"gameId": "game_01HZAA1M0KQ8",
"properties": {
"fpsAvg": 52,
"loadTimeMs": 1800
}
}
\]
}
```
- Third-party integrations
- LLM Provider
- 用途Prompt理解、模板分类、参数生成、失败解释。
- 协议HTTPS JSON API。
- 要求设置超时30秒、最大重试2次、供应商错误降级到默认模板建议。
- 图片生成或素材服务
- MVP可选建议优先使用内置素材库与风格包减少生成不确定性。
- 若接入图片生成,需进行内容安全检测和资源压缩。
- 内容安全服务
- 用途文本、图片、用户资料、封面和Prompt检测。
- 协议HTTPS API。
- 输出pass、review、reject三类结果。
- 对象存储和CDN
- 用途上传素材、生成资源、游戏包、封面和Manifest。
- 要求私有源站CDN公开只读上传使用服务端签名URL。
- 数据分析工具
- MVP内部事件表即可后续可对接GrowingIO、神策、Mixpanel或自建ClickHouse。
- Internal modules
- AuthModule登录、Token、角色、匿名用户升级。
- UserModule用户资料、创作者主页。
- AssetModule上传、扫描、压缩、对象存储签名。
- GenerationModule任务创建、状态机、Prompt解析、GameConfig生成。
- GameModule草稿、版本、发布、详情、Manifest管理。
- ReviewModule审核队列、审核记录、下架、精选。
- FeedModule候选集、排序、分页、曝光保底。
- InteractionModule点赞、收藏、分享、举报。
- AnalyticsModule事件接收、聚合、看板。
- AdminModule后台权限、操作审计、系统配置。
### User Interface
- 创作工作台
- 主区域Prompt输入框、模板卡片、风格标签、上传素材入口。
- 任务页:生成状态、当前步骤、预计等待时间、失败原因和重试入口。
- 预览页:左侧游戏预览容器,右侧基础信息编辑面板。
- 发布页:发布前检查清单、审核状态说明、分享链接。
- 玩家游戏流
- 移动优先,全屏或近全屏纵向滑动。
- 每个游戏项包含封面、标题、作者、玩法提示、开始按钮、点赞、收藏、分享、举报。
- 游戏资源预加载下一项,当前项加载失败时显示错误提示并自动允许跳过。
- 低端设备启用低画质模式限制帧率到30fps。
- 创作者后台
- 我的游戏列表:封面、标题、状态、曝光、试玩、互动、最后更新时间。
- 数据详情近7天趋势、曝光到试玩漏斗、平均游玩时长、加载失败率、举报率。
- 操作:编辑、更新、下架、复制分享链接。
- 运营后台
- 审核队列:状态筛选、风险等级、发布时间、创作者、标签。
- 审核详情游戏试玩、Prompt、生成配置、素材列表、安全检测结果、历史记录。
- 操作:通过、拒绝、下架、备注、加入精选池、限制曝光。
- 交互模式
- 关键流程必须有明确状态:加载中、成功、失败、禁用、重试。
- 生成任务超过120秒提示后台等待不阻断用户离开页面。
- 所有破坏性操作使用二次确认,例如下架、删除草稿、拒绝审核。
- 可访问性与响应式设计
- 移动端优先适配360px至430px宽度。
- 桌面端优先优化创作工作台和运营后台。
- 文本对比度符合WCAG AA基础要求。
- 核心按钮支持键盘访问和可读ARIA标签。
- 错误提示不只依赖颜色表达,应同时使用文本和图标。
## Data Model
How data is structured, stored, and accessed.
### Entities
```text
User
- id: uuid (primary key)
- phone: varchar(32) (nullable, unique)
- email: varchar(255) (nullable, unique)
- password_hash: varchar(255) (nullable)
- nickname: varchar(64) (not null)
- avatar_url: text (nullable)
- role: enum(player, creator, operator, admin) (not null, default player)
- status: enum(active, suspended, deleted) (not null, default active)
- created_at: timestamptz (not null)
- updated_at: timestamptz (not null)
```
```text
CreatorProfile
- id: uuid (primary key)
- user_id: uuid (unique, foreign key User.id)
- slug: varchar(64) (unique, not null)
- bio: varchar(500) (nullable)
- total_games: integer (not null, default 0)
- total_plays: bigint (not null, default 0)
- created_at: timestamptz (not null)
- updated_at: timestamptz (not null)
```
```text
Asset
- id: uuid (primary key)
- owner_id: uuid (foreign key User.id)
- type: enum(image, audio, json, game_bundle, manifest) (not null)
- source: enum(uploaded, generated, system) (not null)
- storage_key: text (not null)
- public_url: text (nullable)
- mime_type: varchar(128) (not null)
- size_bytes: integer (not null)
- width: integer (nullable)
- height: integer (nullable)
- hash_sha256: char(64) (not null)
- moderation_status: enum(pending, passed, review, rejected) (not null, default pending)
- created_at: timestamptz (not null)
```
```text
PromptRecord
- id: uuid (primary key)
- user_id: uuid (foreign key User.id)
- raw_prompt: text (not null)
- normalized_prompt: text (nullable)
- template_hint: varchar(64) (nullable)
- style_tags: text\[\] (not null, default empty)
- moderation_status: enum(pending, passed, review, rejected) (not null)
- moderation_reason: text (nullable)
- created_at: timestamptz (not null)
```
```text
GenerationTask
- id: uuid (primary key)
- user_id: uuid (foreign key User.id)
- prompt_record_id: uuid (foreign key PromptRecord.id)
- status: enum(queued, running, succeeded, failed, canceled, timed_out) (not null)
- progress: integer (0 to 100)
- current_step: varchar(64) (nullable)
- template_id: varchar(64) (nullable)
- llm_request_id: varchar(128) (nullable)
- error_code: varchar(64) (nullable)
- error_message: text (nullable)
- started_at: timestamptz (nullable)
- completed_at: timestamptz (nullable)
- created_at: timestamptz (not null)
- updated_at: timestamptz (not null)
```
```text
Game
- id: uuid (primary key)
- creator_id: uuid (foreign key User.id)
- title: varchar(80) (not null)
- description: varchar(500) (not null)
- cover_asset_id: uuid (foreign key Asset.id, nullable)
- status: enum(draft, pending_review, published, rejected, unpublished, deleted) (not null)
- visibility: enum(private, public, limited) (not null, default private)
- tags: text\[\] (not null, default empty)
- age_rating: enum(all, teen, mature) (not null, default all)
- current_version_id: uuid (nullable)
- published_at: timestamptz (nullable)
- created_at: timestamptz (not null)
- updated_at: timestamptz (not null)
```
```text
GameVersion
- id: uuid (primary key)
- game_id: uuid (foreign key Game.id)
- version_number: integer (not null)
- generation_task_id: uuid (foreign key GenerationTask.id, nullable)
- config_json: jsonb (not null)
- manifest_asset_id: uuid (foreign key Asset.id)
- bundle_asset_id: uuid (foreign key Asset.id, nullable)
- runtime_version: varchar(32) (not null)
- status: enum(draft, active, archived, failed) (not null)
- created_at: timestamptz (not null)
```
```text
ReviewRecord
- id: uuid (primary key)
- game_id: uuid (foreign key Game.id)
- version_id: uuid (foreign key GameVersion.id)
- status: enum(pending, approved, rejected, escalated) (not null)
- risk_level: enum(low, medium, high) (not null, default low)
- reviewer_id: uuid (foreign key User.id, nullable)
- reason_code: varchar(64) (nullable)
- comment: text (nullable)
- created_at: timestamptz (not null)
- decided_at: timestamptz (nullable)
```
```text
Interaction
- id: uuid (primary key)
- user_id: uuid (foreign key User.id, nullable)
- anonymous_id: varchar(128) (nullable)
- game_id: uuid (foreign key Game.id)
- type: enum(like, favorite, share, report) (not null)
- status: enum(active, canceled) (not null, default active)
- reason: varchar(128) (nullable, for report)
- created_at: timestamptz (not null)
- updated_at: timestamptz (not null)
```
```text
EventLog
- id: uuid (primary key)
- event_name: varchar(64) (not null)
- user_id: uuid (nullable)
- anonymous_id: varchar(128) (nullable)
- session_id: varchar(128) (not null)
- game_id: uuid (nullable)
- properties: jsonb (not null)
- occurred_at: timestamptz (not null)
- received_at: timestamptz (not null)
```
```text
GameDailyStats
- id: uuid (primary key)
- game_id: uuid (foreign key Game.id)
- stat_date: date (not null)
- impressions: bigint (not null, default 0)
- load_success: bigint (not null, default 0)
- load_failed: bigint (not null, default 0)
- play_starts: bigint (not null, default 0)
- play_30s: bigint (not null, default 0)
- completes: bigint (not null, default 0)
- likes: bigint (not null, default 0)
- favorites: bigint (not null, default 0)
- shares: bigint (not null, default 0)
- reports: bigint (not null, default 0)
- avg_play_duration_ms: integer (nullable)
- created_at: timestamptz (not null)
- updated_at: timestamptz (not null)
```
```text
FeaturedGame
- id: uuid (primary key)
- game_id: uuid (foreign key Game.id)
- operator_id: uuid (foreign key User.id)
- priority: integer (not null, default 0)
- start_at: timestamptz (not null)
- end_at: timestamptz (nullable)
- created_at: timestamptz (not null)
```
```text
AuditLog
- id: uuid (primary key)
- actor_id: uuid (foreign key User.id)
- action: varchar(128) (not null)
- target_type: varchar(64) (not null)
- target_id: uuid (not null)
- metadata: jsonb (not null)
- ip_address: inet (nullable)
- user_agent: text (nullable)
- created_at: timestamptz (not null)
```
### Relationships
- User → CreatorProfileone-to-oneUser删除时CreatorProfile软删除或保留匿名化记录。
- User → Gameone-to-manycreator_id限制只能访问和修改自己的游戏。
- User → Assetone-to-many上传素材归属用户系统素材owner可为空或使用system user。
- PromptRecord → GenerationTaskone-to-many同一Prompt允许多次重试生成。
- GenerationTask → GameVersionone-to-one或one-to-many一次成功生成可创建一个版本重试可产生新版本。
- Game → GameVersionone-to-manyGame.current_version_id指向当前线上或草稿版本。
- Game → ReviewRecordone-to-many每次发布提交生成一条审核记录。
- Game → Interactionone-to-many同一用户对同一游戏的like和favorite应有唯一约束。
- Game → GameDailyStatsone-to-many按game_id和stat_date唯一。
- Game → FeaturedGameone-to-many可配置多个时间段的精选计划。
- ReviewRecord → Usermany-to-onereviewer_id为运营或管理员。
- 关键约束
- Game.status为published时必须存在current_version_id、cover_asset_id、title、description。
- GameVersion.config_json必须通过JSON Schema校验。
- Interaction唯一约束user_id + game_id + type适用于like和favoriteshare和report允许多条但需要限频。
- EventLog按occurred_at月度分区避免长期写入膨胀影响查询。
- 所有后台操作写入AuditLog。
### Storage
- 数据库
- PostgreSQL作为主库承载用户、游戏、版本、审核、互动和聚合统计。
- 使用Prisma Migration管理Schema变更。
- 关键索引:
- Game(status, published_at desc)
- Game(creator_id, updated_at desc)
- ReviewRecord(status, created_at asc)
- Interaction(game_id, type)
- EventLog(occurred_at, event_name)
- GameDailyStats(game_id, stat_date)
- 缓存
- Redis缓存游戏详情、Manifest元数据、Feed候选集、用户会话和限频计数。
- Feed缓存TTL 60秒热门游戏详情TTL 300秒。
- 生成任务状态可写PostgreSQL为准Redis用于短期进度加速读取。
- 队列
- BullMQ队列generation_queue、moderation_queue、asset_processing_queue、event_aggregation_queue、notification_queue。
- 每类任务配置重试次数、退避策略和死信队列。
- 文件/blob存储
- 原始上传素材private bucket需签名访问。
- 处理后封面和公开素材public-read via CDN或私有源站加CDN回源。
- 游戏Manifest和bundle版本化路径例如/games/{gameId}/versions/{versionId}/manifest.json。
- 所有资源文件保留sha256 hash用于去重、缓存和完整性校验。
### Data Flow
- 创作生成流程
1. 用户登录并进入创作工作台。
2. 前端提交Prompt、模板提示、风格标签和素材ID。
3. API Server创建PromptRecord和GenerationTask写入generation_queue。
4. Moderation Worker先检测Prompt和上传素材若reject则任务失败并返回明确原因。
5. Generation Worker调用LLM解析Prompt选择模板并生成GameConfig。
6. Worker使用JSON Schema和业务规则校验GameConfig。
7. Worker生成或绑定素材创建GameManifest并上传对象存储。
8. Worker创建Game草稿和GameVersion更新任务状态为succeeded。
9. 前端轮询任务状态并跳转预览页。
- 发布审核流程
1. 创作者编辑标题、简介、封面、标签和操作说明。
2. 点击发布后API执行发布前检查。
3. 系统创建ReviewRecord并将Game置为pending_review。
4. 低风险内容可自动通过或进入运营队列,具体由配置控制。
5. 运营通过后Game置为published和public写入AuditLog。
6. Feed候选集下次刷新时包含该游戏并为新作分配保底曝光。
- 玩家游戏流流程
1. 玩家打开首页,前端请求/api/v1/feed。
2. FeedModule从精选、最新、质量分候选池取数据并排序。
3. 前端展示第一款游戏并预加载下一款Manifest和关键资源。
4. 玩家开始试玩Game SDK上报load、start、30s、complete和error事件。
5. 前端批量调用/events/batch上报埋点。
6. Event Worker聚合更新GameDailyStats和质量分。
7. 后续Feed排序降低高错误、高举报游戏的曝光。
- 运营审核流程
1. 运营登录后台,调用/admin/reviews获取待审核列表。
2. 运营查看游戏详情、Prompt、安全检测结果和试玩预览。
3. 运营提交通过、拒绝、下架或精选操作。
4. API更新Game、ReviewRecord、FeaturedGame并写AuditLog。
## Testing Plan
How the product will be validated at every level.
### Testing Strategy
- Unit tests
- 覆盖范围Prompt解析适配器、GameConfig校验、状态机转换、Feed评分、权限Guard、事件聚合逻辑。
- 框架Vitest或Jest。
- 覆盖目标核心业务模块行覆盖率不低于80%状态机和权限模块不低于90%。
- Integration tests
- 覆盖范围REST API、PostgreSQL、Redis Queue、对象存储Mock、内容安全Mock、LLM Mock。
- 重点验证:生成任务创建到成功、发布审核、游戏流返回、互动写入、事件聚合。
- 使用Testcontainers启动PostgreSQL和Redis避免只依赖内存Mock。
- E2E tests
- 框架Playwright。
- 覆盖关键用户流:创作者生成游戏、预览发布、运营审核、玩家游戏流试玩互动、创作者查看数据。
- 移动端视口必须覆盖iPhone和Android常见宽度。
- Performance tests
- 工具k6。
- 目标:
- /feed P95低于300ms不含CDN资源加载。
- /events/batch P95低于200ms。
- /generation/tasks创建任务P95低于500ms。
- 500并发玩家浏览Feed时错误率低于1%。
- 每分钟5,000条事件写入时队列无持续积压。
- Game runtime tests
- 使用自动化脚本加载每个模板生成的Manifest。
- 验证资源存在、启动成功、SDK事件发出、低端设备模拟下帧率不低于30fps。
- 对每个模板维护golden config样例。
### Testing Tools
- Frontend
- Vitest组件逻辑和工具函数。
- React Testing LibraryUI状态和交互。
- Playwright跨浏览器和移动视口E2E。
- Lighthouse CI性能、可访问性和最佳实践检查。
- Backend
- Jest或Vitest服务、控制器和状态机单测。
- SupertestAPI集成测试。
- TestcontainersPostgreSQL和Redis依赖环境。
- Prisma migrate diffSchema变更验证。
- Game runtime
- Playwright加载游戏容器并监听SDK事件。
- 自定义Manifest Validator校验Manifest资源、hash和字段完整性。
- Performance and security
- k6API压测。
- OWASP ZAP Baseline Scan基础Web安全扫描。
- npm audit、pnpm audit、Snyk或GitHub Dependabot依赖漏洞扫描。
- CI integration
- Pull Request阶段lint、type check、unit tests、API integration tests、build。
- Merge to main阶段完整测试、Docker镜像构建、安全扫描、部署到staging。
- Release阶段staging E2E、性能冒烟、手动批准生产部署。
- Code coverage
- 全仓库最低70%。
- 核心后端业务模块最低80%。
- 权限、审核和发布状态机最低90%。
- 覆盖率不达标阻断合并。
### Key Test Cases
- 创作链路Happy Path
- 创作者登录。
- 输入合法Prompt并选择模板。
- 创建生成任务成功。
- Worker生成GameConfig和Manifest。
- 前端预览成功加载游戏。
- 创作者填写标题、封面、标签并保存。
- 发布与审核
- 发布前缺少标题时返回明确错误。
- 内容安全reject时不得进入公开Feed。
- pending_review游戏只有作者和运营可访问。
- 运营通过后游戏出现在Feed候选集中。
- 运营拒绝后创作者看到原因且可修改重提。
- 玩家游戏流
- 未登录用户可以浏览和试玩。
- 未登录用户点击点赞时触发登录引导,并在登录后恢复操作上下文。
- 游戏加载失败时记录game_load_failed并允许跳过。
- 上下滑动切换不会重复曝光同一游戏,除非列表耗尽。
- 下一款游戏资源成功预加载。
- 互动与埋点
- 同一用户重复点赞不会重复计数。
- 收藏取消后状态更新为canceled。
- 举报行为触发风险信号并对同一匿名用户限频。
- 批量事件中部分无效事件不影响有效事件写入。
- Event Worker聚合后数据看板数值正确。
- 权限与安全敏感操作
- 普通用户不能访问/admin接口。
- 创作者不能编辑他人游戏。
- 运营操作必须写入AuditLog。
- 已删除或下架游戏不能在公开Feed返回。
- 上传非图片或超大文件会被拒绝。
- 性能边界
- 单个游戏Manifest资源超过大小限制时生成失败并返回可理解原因。
- 高并发Feed请求不造成数据库慢查询。
- Redis不可用时Feed可降级为数据库读取并告警。
- LLM超时后任务进入failed或timed_out允许用户重试。
### Reporting
- CI报告
- GitHub Actions或GitLab CI展示每次PR的测试、覆盖率、构建和安全扫描结果。
- 失败测试必须阻断合并。
- 质量看板
- Grafana展示API错误率、P95延迟、队列长度、生成成功率、游戏加载失败率。
- Sentry展示前端错误、游戏运行错误和后端异常。
- 每日自动生成MVP质量报告生成任务数、成功率、平均生成时长、审核积压、Feed错误率。
- 缺陷管理
- P0核心链路不可用、权限绕过、数据丢失、安全事故。
- P1生成成功率显著下降、游戏流加载异常、审核流程阻塞。
- P2单页面体验问题、非关键统计延迟、文案错误。
## Deployment Plan
How the product moves from code to production.
### Environment Setup
- Development
- 本地运行Docker ComposePostgreSQL、Redis、MinIO、本地邮件或通知Mock。
- 前端Next.js热更新运行在localhost:3000。
- 后端NestJS运行在localhost:4000。
- Worker独立进程运行generation、moderation和event aggregation。
- 使用seed脚本创建管理员、运营、示例创作者、示例游戏和模板数据。
- LLM和内容安全默认使用Mock Provider可通过环境变量切换真实Provider。
- Staging
- 与生产同构但缩小规格。
- 使用独立PostgreSQL、Redis、OSS bucket和CDN域名。
- 接入真实内容安全服务LLM可使用较低成本模型。
- 仅允许白名单用户访问创作和后台。
- 每次main合并自动部署。
- Production
- 云基础设施建议:
- API Server运行在Kubernetes、ECS、Cloud Run或Render/Fly.io等容器平台。
- Worker按队列类型独立部署可横向扩容。
- PostgreSQL使用云托管数据库开启自动备份和只读副本预留。
- Redis使用托管版开启持久化和监控。
- 静态前端部署到Vercel、Netlify或对象存储加CDN。
- 生产访问必须使用HTTPS。
- 所有Secrets从云Secret Manager或Vault读取不写入代码仓库。
### CI/CD Pipeline
- Build steps
1. 安装依赖pnpm install --frozen-lockfile。
2. 静态检查eslint、prettier check。
3. 类型检查tsc --noEmit。
4. 单元测试vitest/jest with coverage。
5. 集成测试Testcontainers PostgreSQL和Redis。
6. 前端构建next build。
7. 后端构建nest build。
8. Docker镜像构建并打tag。
9. 依赖漏洞扫描和镜像扫描。
- Deployment trigger
- Pull Request创建Preview Deployment仅连接staging级别Mock服务。
- Merge to main自动部署Staging。
- Production手动批准发布建议每周固定窗口或MVP阶段按需发布。
- Preview deployments
- 每个PR生成前端预览URL。
- 后端可共享staging API或部署临时环境。
- Preview环境禁止使用真实用户数据和真实支付/广告相关配置。
### Deploy Process
1. 准备发布版本
- 确认main分支CI全绿。
- 确认数据库Migration已在staging成功执行。
- 确认Feature Flag默认值符合发布策略。
- Verification checkpointstaging smoke tests通过错误率无异常。
2. 执行数据库迁移
- 在生产数据库执行向后兼容Migration。
- 禁止直接删除字段或重命名字段采用expand-migrate-contract策略。
- Verification checkpoint迁移执行成功关键表读写正常。
3. 部署后端API
- 使用滚动发布或蓝绿部署。
- 保持旧版本至少可服务5至10分钟确保无中断。
- Verification checkpoint/health、/ready、登录、Feed接口正常。
4. 部署Worker
- 先暂停或降低新任务消费。
- 部署Worker新版本。
- 恢复队列消费并观察失败率。
- Verification checkpointgeneration_queue和event_aggregation_queue无异常积压。
5. 部署前端
- 发布Next.js前端或静态资源。
- 刷新CDN缓存中需要更新的HTML和Manifest加载脚本。
- Verification checkpoint创作工作台、游戏流、后台入口可访问。
6. 灰度开启功能
- 使用Feature Flag先对内部用户开放。
- 观察30至60分钟后扩大到种子用户。
- Verification checkpoint生成成功率、Feed错误率、Sentry错误无异常增长。
### Rollback Strategy
- 应用回滚
- 保留最近3个稳定Docker镜像。
- API和Worker可通过部署平台一键回滚到上一版本。
- 前端可通过Vercel/Netlify回滚或CDN切回上一构建。
- 数据库回滚
- 优先使用向后兼容Migration避免必须回滚数据库。
- 对高风险Migration预先准备rollback SQL。
- 删除数据类操作必须先备份MVP阶段原则上不做破坏性Migration。
- Feature flags
- generation_v2_enabled控制新生成链路。
- feed_ranking_v2_enabled控制新推荐评分。
- auto_review_enabled控制自动审核通过。
- external_asset_generation_enabled控制外部图片生成服务。
- 任何P0异常优先关闭相关Flag而不是全站回滚。
- 队列回滚
- Worker新版本异常时暂停队列消费。
- 将失败任务标记为retryable或保持queued待旧版本恢复后继续消费。
- 对不兼容任务payload使用version字段区分处理逻辑。
### Post-Deploy Verification
- Smoke tests
- 用户登录成功。
- 创建生成任务成功Mock或真实低成本生成可完成。
- 预览游戏可加载并触发game_load_success。
- 游戏可提交审核。
- 运营可通过审核。
- 已发布游戏可出现在Feed。
- 点赞、收藏和埋点上报成功。
- Monitoring dashboards
- API LatencyP50、P95、P99。
- API Error Rate4xx、5xx分布。
- Queue Health等待数、处理中、失败数、平均处理时长。
- Generation Health成功率、失败原因、平均生成时长。
- Game Runtime加载成功率、运行错误率、平均FPS、资源加载时长。
- DatabaseCPU、连接数、慢查询、锁等待。
- CDN命中率、回源错误、流量峰值。
- Alert thresholds
- API 5xx错误率5分钟内超过2%触发P1告警。
- /feed P95超过800ms持续10分钟触发P1告警。
- 生成成功率15分钟内低于70%触发P1告警。
- generation_queue等待任务超过500或最老任务等待超过10分钟触发P1告警。
- 游戏加载失败率超过8%持续15分钟触发P1告警。
- 数据库连接使用率超过85%持续10分钟触发P1告警。
- 权限相关异常或后台接口未授权访问激增触发P0安全告警。
## Security & Performance
Non-functional requirements and how they are addressed.
### Security
- Authentication
- 使用JWT Access Token和Refresh Token。
- Access Token有效期15分钟Refresh Token有效期7至30天。
- Refresh Token存储hash支持注销和设备级撤销。
- 游客使用anonymous_id只允许浏览和试玩不允许发布、收藏和后台操作。
- Authorization
- 使用RBACplayer、creator、operator、admin。
- 所有修改游戏、审核、精选、下架和查看后台接口必须校验角色和资源归属。
- 后台接口单独命名空间/admin并增加IP风险监控和操作审计。
- Input validation and sanitization
- API使用Zod或class-validator校验请求。
- Prompt长度限制例如10至1,000字符。
- 标题限制80字符简介限制500字符标签数量限制10个。
- 上传文件限制MIME、扩展名、大小和尺寸。
- 所有用户可见文本输出做HTML escaping禁止直接渲染未清洗HTML。
- Game sandboxing
- 游戏运行在受控iframe或隔离容器中。
- 禁止生成游戏访问任意网络、Cookie、localStorage和父页面DOM。
- Game SDK只暴露有限能力事件上报、结束游戏、读取配置。
- 设置Content Security Policy限制脚本源、资源源和frame权限。
- Secrets management
- 本地开发使用.env.local不提交仓库。
- Staging和Production使用Secret Manager或Vault。
- LLM、内容安全、OSS、数据库和Redis凭证定期轮换。
- 日志中禁止输出Token、手机号、邮箱、Prompt敏感检测明文结果和第三方API Key。
- Dependency vulnerability scanning
- Pull Request阶段运行pnpm audit或Snyk。
- Docker镜像使用Trivy或云厂商镜像扫描。
- Dependabot自动提交安全升级PR。
- OWASP Top 10 considerations
- Broken Access ControlRBAC、资源归属校验、后台审计。
- Cryptographic FailuresHTTPS、数据库备份加密、敏感字段加密或脱敏。
- InjectionPrisma参数化查询禁止拼接SQLPrompt不直接作为系统指令执行。
- Insecure Design状态机限制非法发布和审核状态转换。
- Security MisconfigurationCSP、CORS白名单、生产关闭debug、对象存储私有源站。
- Vulnerable Components依赖扫描和锁文件审计。
- Identification and Authentication FailuresRefresh Token轮换、登录限频、密码hash使用Argon2或bcrypt。
- Software and Data Integrity Failures游戏Manifest hash校验CI签名镜像可选。
- Security Logging and Monitoring Failures后台操作、登录失败、安全拒绝全部记录。
- SSRF后端不允许用户提交任意URL抓取资源如后续支持必须使用URL allowlist和内网IP阻断。
- Content safety and compliance
- Prompt、标题、简介、封面和上传素材均经过内容安全检测。
- risk_level为high时自动拒绝medium进入人工审核low可进入普通审核或自动通过。
- 举报达到阈值时自动限制曝光并进入运营复核。
- 针对未成年人保护、版权素材和暴力色情等内容建立可配置策略。
### Performance
- Targets
- 游戏流API响应P95低于300msP99低于800ms。
- 游戏详情API响应P95低于200ms。
- 埋点批量上报API响应P95低于200ms。
- 生成任务创建API响应P95低于500ms。
- 生成任务完成时长P75低于120秒P95低于240秒。
- 游戏流首屏可交互时间P75低于3秒P95低于6秒。
- 游戏运行帧率中端移动设备平均不低于45fps低端设备低画质不低于30fps。
- 平台吞吐MVP支持500并发浏览用户、每分钟5,000条埋点事件、每日1,000次生成任务。
- Optimization
- 前端
- Next.js路由级代码分割。
- 游戏流只保留当前、前一、后一三个游戏容器。
- 图片使用WebP/AVIF封面多尺寸裁剪。
- 下一款游戏Manifest和关键资源预加载。
- 埋点异步批量发送使用sendBeacon兜底。
- 后端
- 高频读接口使用Redis缓存。
- Feed候选集预计算或短TTL缓存。
- 事件写入走批量insert聚合异步执行。
- 数据库连接池按实例规格配置,避免连接耗尽。
- 资源
- 游戏bundle hash命名CDN长期缓存。
- 限制单游戏总资源大小和首屏关键资源大小。
- 音频延迟加载,非关键图片懒加载。
- Worker
- 生成Worker按队列长度自动扩容。
- LLM调用设置超时、重试和熔断。
- 资产处理使用并发限制避免CPU尖峰。
- Monitoring
- APMOpenTelemetry trace跨API、Worker和数据库。
- Error trackingSentry捕获前端、Game Runtime和后端异常。
- Custom metrics生成成功率、审核积压、Feed曝光、游戏加载失败率、互动率。
- Scaling
- MVP阶段API Server 2个实例Worker按队列1至3个实例PostgreSQL单主实例Redis托管实例。
- 增长阶段:
- API Server水平扩容。
- Generation Worker按任务量独立扩容。
- Event Worker和Analytics迁移到ClickHouse或数据仓库。
- Feed Service从API Server拆分为独立服务。
- PostgreSQL增加只读副本读多写少接口走读副本。
- Auto-scaling配置
- APICPU超过65%或RPS超过阈值扩容。
- Worker队列等待任务数超过100或最老任务等待超过2分钟扩容。
- Event Worker事件队列积压超过10,000条扩容。
### Observability
- Logging strategy
- 使用结构化JSON日志。
- 所有日志包含request_id、user_id可选、anonymous_id可选、module、operation、duration_ms、status。
- 生成任务日志包含task_id、template_id、provider、error_code但不直接记录敏感Prompt全文。
- 审核和后台操作写AuditLog并长期保存。
- 日志保留应用日志30天审计日志至少180天安全日志至少180天。
- Metrics
- Product metrics
- creator_activation_rate。
- generation_success_rate。
- first_publish_conversion_rate。
- feed_session_games_played。
- game_interaction_rate。
- player_d7_retention。
- System metrics
- API RPS、latency、error rate。
- Queue depth、processing time、failure count。
- Database CPU、connections、slow queries、locks。
- Redis memory、hit rate、evictions。
- CDN hit rate、origin error rate。
- Game metrics
- game_load_time_ms。
- game_load_failed_rate。
- runtime_error_rate。
- fps_avg。
- asset_size_bytes。
- Alerting
- 告警渠道飞书、Slack、邮件或短信按严重级别区分。
- P0响应核心链路不可用、安全事故、数据丢失15分钟内响应。
- P1响应生成失败率异常、Feed延迟异常、队列严重积压工作时间30分钟内响应。
- P2响应非核心页面错误、低频统计延迟下一工作日处理。
- 每个告警必须包含Runbook链接问题现象、排查仪表盘、常见原因、回滚步骤和负责人。