Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
a7c0135
build(frontend): scaffold vite react typescript workspace
Jul 27, 2026
487dc17
feat(shared): add transport layer with real and mock clients
Jul 27, 2026
8536854
feat(entities): add data module public interface
Jul 27, 2026
14baa3a
feat(pages): add page modules and routing shell
Jul 27, 2026
07809a2
test(frontend): add unit tests and dependency boundary checks
Jul 27, 2026
2ff4376
docs(frontend): add module contract and setup guide
Jul 27, 2026
5d2d66a
feat(entities): execute workflow commands instead of marking steps done
Jul 27, 2026
36aa8ea
fix(quick-start): keep ai runs on their own page
Jul 27, 2026
dbe064e
test(quick-start): assert the ai entry never leaves its route
Jul 27, 2026
c21b637
docs(frontend): record the two parallel workflow entries
Jul 27, 2026
e12b98c
feat(frontend): rebuild workflow architecture for MS2
xyh202131 Jul 27, 2026
cd8fbe6
feat(mock): move the workflow state machine into the fake backend
Jul 27, 2026
e6d998b
refactor(entities): call the workflow API instead of local storage
Jul 27, 2026
c3c3cbb
fix(quick-start): keep ai runs on their own page
Jul 27, 2026
324d5d2
docs(entities): correct the workflow adapters note
Jul 27, 2026
d4d8503
feat(quick-start): add simplified creation workspace
xyh202131 Jul 28, 2026
991e145
docs(frontend): align architecture with transport boundaries
xyh202131 Jul 28, 2026
7f9e176
docs(frontend): clarify mock transport scope
xyh202131 Jul 28, 2026
41d1628
docs(frontend): document workflow editor module
xyh202131 Jul 28, 2026
84937ad
fix(frontend): validate upload limits before request
xyh202131 Jul 28, 2026
f33ab18
fix(frontend): address review feedback
xyh202131 Jul 28, 2026
f6d0818
docs(frontend): define workflow orchestration boundary
xyh202131 Jul 28, 2026
28531d3
docs(frontend): plan workflow orchestration refactor
xyh202131 Jul 28, 2026
df2926a
refactor(frontend): decouple tasks from workflow runs
xyh202131 Jul 28, 2026
f1a7614
refactor(frontend): keep workflow orchestration local
xyh202131 Jul 28, 2026
ecf2d90
docs(frontend): align orchestration with backend domains
xyh202131 Jul 28, 2026
f8ea3fc
docs(frontend): 补充接口字段说明
xyh202131 Jul 28, 2026
22e372d
refactor(frontend): 区分动作模板与角色母版命名
xyh202131 Jul 28, 2026
6cbfc54
refactor(character): require a template id for preset actions
Jul 28, 2026
740f920
docs(project): separate the project style reference from the characte…
Jul 28, 2026
5f0f50d
test(entities): lock the preset branch of the add-action input
Jul 28, 2026
44be7d4
refactor(character): rename CharacterVariant to Outfit
Jul 28, 2026
59c088e
test(entities): follow the Outfit rename in the contract assertions
Jul 28, 2026
8e09ff5
docs(frontend): follow the Outfit rename across the contract documents
Jul 28, 2026
25350fc
docs(frontend): design workflow repository hardening
xyh202131 Jul 28, 2026
3298b13
refactor(frontend): make workflow repository replaceable
xyh202131 Jul 28, 2026
bbf3cd6
fix(frontend): preserve workflow memory fallback
xyh202131 Jul 28, 2026
b2443f5
fix(frontend): fall back when randomUUID is unavailable
xyh202131 Jul 28, 2026
5e8a583
fix(frontend): distinguish unstarted generation
xyh202131 Jul 28, 2026
d27e0d9
fix(frontend): validate persisted workflow runs
xyh202131 Jul 28, 2026
4db7015
docs(frontend): document workflow repository guarantees
xyh202131 Jul 28, 2026
437fb8d
ci(frontend): add GitHub quality gate
xyh202131 Jul 28, 2026
4ba30e3
refactor(frontend): align quick start capability boundaries
xyh202131 Jul 28, 2026
92e544b
docs(frontend): define module ownership boundaries
xyh202131 Jul 28, 2026
84e7852
docs(frontend): expand module ownership audit
xyh202131 Jul 28, 2026
b062629
docs(frontend): plan module ownership refactor
xyh202131 Jul 28, 2026
f064cc8
refactor(frontend): move image generation to capabilities
xyh202131 Jul 28, 2026
61d50c7
refactor(frontend): separate upload and pagination ownership
xyh202131 Jul 28, 2026
9a5e3f4
refactor(frontend): correct entity ownership boundaries
xyh202131 Jul 28, 2026
4c6fe77
refactor(frontend): compose project repository in app
xyh202131 Jul 28, 2026
25888b0
docs(frontend): lock module ownership map
xyh202131 Jul 28, 2026
8f8a7bc
refactor(frontend): classify project HTTP adapter as candidate
Jul 29, 2026
f634780
fix(frontend): block candidate project APIs in production
Jul 29, 2026
5ab8c80
test(frontend): lock project adapter selection
Jul 29, 2026
8999dcb
docs(frontend): correct project integration status
Jul 29, 2026
fd1946f
docs(frontend): record project contract correction
Jul 29, 2026
8f32c85
refactor(generation): remove provider session assumptions
Jul 29, 2026
907b08d
test(generation): lock provider-neutral generation state
Jul 29, 2026
817c29a
test(architecture): remove provider session slice
Jul 29, 2026
96a45c1
docs(frontend): remove provider session contract
Jul 29, 2026
537b762
docs(architecture): record provider boundary correction
Jul 29, 2026
54c477b
feat(preview): add explicit service composition
Jul 29, 2026
009ee78
test(preview): cover service composition selection
Jul 29, 2026
8518839
ci(vercel): configure frontend previews
Jul 29, 2026
a871e73
docs(frontend): document preview deployment
Jul 29, 2026
9ef6a8a
refactor(frontend): align workflow contracts with mentor feedback
xyh202131 Jul 29, 2026
21304f2
refactor(quick-start): colocate the page service contract
huyanxius Jul 29, 2026
bef57c5
refactor(quick-start): remove the redundant feature slice
huyanxius Jul 29, 2026
35a1922
test(quick-start): move service ownership coverage
huyanxius Jul 29, 2026
e477890
test(quick-start): await the routed session view
huyanxius Jul 29, 2026
55755fa
docs(architecture): remove the duplicate quick-start feature
huyanxius Jul 29, 2026
cff02fd
docs(quick-start): document the page-owned service
huyanxius Jul 29, 2026
f9cc47d
test(frontend): remove the module test suite
huyanxius Jul 30, 2026
2b28529
ci(frontend): let the test step pass with no test files
huyanxius Jul 30, 2026
73c3b46
refactor(frontend): collapse each module into a single contract file
huyanxius Jul 30, 2026
b99eb8c
docs(frontend): rewrite architecture and backend alignment docs
huyanxius Jul 30, 2026
4c608dd
docs: remove the superseded frontend design plans
huyanxius Jul 30, 2026
7598b4b
refactor(workflow): rename flow nodes to steps
huyanxius Jul 30, 2026
88c39b7
feat(project): add the update api
huyanxius Jul 30, 2026
dd01b78
refactor(task): drop the cancel api the backend does not provide
huyanxius Jul 30, 2026
28f41ef
refactor(generation): model a generation as a server resource
huyanxius Jul 30, 2026
f87fb94
refactor(character): drop the unused add action input
huyanxius Jul 30, 2026
308ca1f
docs(shared): document what belongs in the shared layer
huyanxius Jul 30, 2026
ff1aab1
docs(frontend): sync architecture and contract with the step wording
huyanxius Jul 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .github/workflows/frontend-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Frontend CI

on:
pull_request:
branches: [main]
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: frontend-ci-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
frontend-checks:
name: Frontend checks
runs-on: ubuntu-latest
timeout-minutes: 15
env:
CI: 'true'

defaults:
run:
working-directory: frontend

steps:
- name: Checkout
uses: actions/checkout@v7

- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: 24
cache: npm
cache-dependency-path: frontend/package-lock.json

- name: Install dependencies
run: npm ci

- name: Check formatting
run: npm run format:check

- name: Lint
run: npm run lint

- name: Typecheck
run: npm run typecheck

- name: Test
run: npm run test

- name: Build
run: npm run build
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# macOS
.DS_Store

# 依赖与构建产物由各子项目的 .gitignore 负责
101 changes: 101 additions & 0 deletions frontend-architecture-v3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Windup 前端架构

本文记录当前前端的模块划分与依赖规则。2026-07-30 按当日评审意见重写:本阶段只提交模块边界与接口,实现进后续 PR。

---

## 1. 模块划分

业务模块都在 `src/entities/` 下:

| 模块 | 职责 |
|---|---|
| `project` | 项目级全局约束:视角、朝向数、精灵尺寸、画风 |
| `character` | 角色资产。造型、动作、帧是它内部的一棵树 |
| `action-template` | 能跨角色复用的动作配方 |
| `generation` | 一次生成任务这份业务数据 |
| `media` | 已上传媒体的不透明引用 |
| `task` | 后端异步步骤的状态 |
| `workflow-run` | 制作流程的运行记录 |
| `playtest-inspection` | 核验结论,独立于角色与流程 |

**模块判据:这个东西能不能被单独取到。**

能单独取,说明它需要自己的一套取数逻辑,才值得一个模块;取不到的,它只是别人身上的一个字段。

按这条判据,`Outfit`、`Action`、`Frame` 没有独立模块——它们不能脱离 `Character` 被取到,所以是 `character` 内部的类型。`ActionTemplate` 有独立模块,因为它能被不同角色复用。

---

## 2. 层次

```text
pages -> features -> entities -> shared
```

| 层 | 内容 |
|---|---|
| `pages` | 八个路由页面 |
| `features` | 用户操作:角色设置、生成、审核、导出;以及流程推进 `workflow-controller` |
| `entities` | 上表业务模块 |
| `shared` | 无业务语义的形状,目前只有分页 |

`app` 只做启动和路由,不构造服务、不向下注入。

### 依赖规则

1. 只能向下依赖,不允许反向。
2. 同层模块之间不互相导入。要共用就往下沉。
3. 跨模块只从模块目录的 `index.ts` 进入;`entities` 统一从 `@/entities` 使用。
4. `entities` 内部模块之间可以互相导入,对外仍是一个门。

---

## 3. 接口命名

每个模块暴露一组后端接口,统一叫 `XxxApis`:

```text
ProjectApis CharacterApis ActionTemplateApis GenerationApis
TaskApis WorkflowRunApis PlaytestInspectionApis
```

**不使用 `Repository` / `Port` / `Adapter` 这些叫法**,也不做接口与实现的分离——实现跟着接口放在同一个模块里。

---

## 4. 流程推进

`features/workflow-controller` 是快速开始与手动工作流共用的推进边界,不含界面。

Controller 围绕同一份 WorkflowRun 提供推进、更新、重启和中断。这些操作依赖同一份步骤数据,不拆成互不共享状态的独立模块。

步骤顺序固定八步:

```text
角色资料 → 角色图 → 候选选择 → 动作资料 → 首帧 → 完整动画 → 审核 → 导出
```

**步骤怎么走由前端决定。** `WorkflowRunApis` 只负责存取运行记录,不负责推进。

从历史步骤重开会追加一个新 Revision,旧 Revision 保留为只读历史,不会被改写成失败或完成。

快速开始与手动模式共用同一份推进逻辑,区别只是前者连续调用、后者一次一步。隐藏步骤不等于跳过步骤——门禁写在流程模型里,不在界面里。

---

## 5. 本次不包含

- 任何实现代码(真实请求、假数据、组件内部逻辑)
- 测试文件
- 图片上传模块(体量太小,本次不单独体现)
- 穿戴道具相关(产品侧未设计)
- 第三方登录

页面当前是占位外壳,只声明路由与模块边界。

---

## 6. 未与后端对齐的部分

明细见 `frontend/API_CONTRACT.md`。
28 changes: 28 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Vercel 本地项目链接元数据,不提交账号和项目 ID
.vercel

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
.env*
9 changes: 9 additions & 0 deletions frontend/.oxfmtrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"endOfLine": "lf",
"printWidth": 100,
"semi": false,
"singleQuote": true,
"trailingComma": "all",
"ignorePatterns": ["**/*.md"]
}
8 changes: 8 additions & 0 deletions frontend/.oxlintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": ["react", "typescript", "oxc"],
"rules": {
"react/rules-of-hooks": "error",
"react/only-export-components": ["warn", { "allowConstantExport": true }]
}
}
114 changes: 114 additions & 0 deletions frontend/API_CONTRACT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# 前后端接口对齐清单

前端各模块的 `XxxApis` 与后端 PR #64(head `10dd958`)逐条比对结果。

后端现有四个相关模块:`project`、`character`、`generation`、`media`。`asset` 与 `wearable` 已按 07-30 评审要求删除。

---

## 一、前端预期有、后端目前没有

**这几条需要后端明确做或不做;不做的前端删掉。**

| 前端接口 | 后端情况 |
|---|---|
| `WorkflowRunApis`(`get` / `create` / `save`) | 没有 workflow 模块 |
| `ActionTemplateApis.listAvailable` | 没有 action template 模块 |
| `PlaytestInspectionApis`(`getLatest` / `record`) | 没有对应模块 |
| 独立的 `task` 模块 | 后端 Task 不独立,是 `generation` 内的 `GenerationTask` |

前端已按服务端现状去掉 `TaskApis.cancel`——`GenerationService` 没有取消能力,不声明前端用不到的接口。

---

## 二、形状不一致

### 生成步骤:后端一步,前端两步

| 后端 `GenerationType` | 前端 `GenerationType` |
|---|---|
| `character_image` | `character_template` |
| `character_action` | `first_frame` → `complete_animation` |

前端设计是先出动作首帧、用户确认后再生成完整动画。后端 `generate_character_action` 是一次到底。

**这不是命名差异,是交互差异。需要确认首帧确认这一步保不保。**

### 其他

| 项 | 后端 | 前端 |
|---|---|---|
| 角色列表 | `list_characters` 分页,返回 `(list, total)` | `listByProject` 无分页 |
| 更新角色 | `update_character(character_id, **fields)` 部分更新 | `update(character)` 整棵树替换 |
| 查任务 | `get_task(project_id, task_id)` 需要 `project_id` | `get(taskId)` 只传 taskId |
| 动作类型 | `walk` `idle` `attack` `custom` | 多一个 `jump` |
| 删除项目 | 返回 `bool`(是否找到) | 返回 `void` |

ID 类型后端为 `int`、前端为 `string`,由前端转换层处理,不需要后端改动。

---

## 三、后端有、前端没接

| 后端 | 说明 |
|---|---|
| `project_name_exists(user_id, project_name)` | 建项目时的重名校验,前端未接 |
| `delete_character` | 前端 `CharacterApis` 没有删除 |
| `Character.description` | 后端存在实体上;前端只在创建入参里,创建完查不到 |
| `Character.reference_image_url` | 后端存在实体上;前端 `Character` 类型没有这个字段 |
| `MediaService.upload` | 前端本次未提交上传模块 |

---

## 四、审核数据无处保存

后端 `character_data` 的嵌套结构(见 `character/model.py`):

```text
outfits[] → id / name / preview_url / actions[]
actions[] → id / type / name / loop / fps / frame_count / frames[]
frames[] → index / image_url / duration_ms
```

前端以下字段在后端结构里没有落点:

- `Frame.qc`(系统质检结论)
- `Frame.rejected`(人工打回)
- `Action.kind`(preset / custom 来源)
- `Action.status`(planned / generating / candidate / confirmed / failed)
- `Action.keyFrameIndex`
- `Frame.rootMotion`
- `Outfit.candidateCharacterTemplates`(母版候选列表)
- `Outfit.baseFrames`

**其中 `qc` 与 `rejected` 是审核台的全部依据。后端不存这两个字段,审核结果就落不了库。**

`candidateCharacterTemplates` 同理:前端设计是生成多张候选让用户选,后端 `CharacterImageInput.num_images` 默认 1,`character_data` 里也没有候选列表。

---

## 五、概念不一致

后端 `character/model.py` 字段说明:

> `reference_image_url`: 角色参考图,即旧概念中的 Character Template

前端把这两者当成不同的东西:

- 用户上传的参考图 —— 创建角色时的输入
- AI 生成后用户选定的角色图(母版)—— `Outfit.characterTemplateUrl`

**后端合成了一个字段。** 07-30 评审也提到「模板」这个叫法容易与 action template 混淆,暂改称「角色图」。三方对这里是几个概念的理解需要统一。

---

## 待确认

- [ ] 第一节四条:后端做还是不做
- [ ] 动作生成一步还是两步
- [ ] `Frame.qc` / `Frame.rejected` 落不落库
- [ ] 母版候选几张
- [ ] 参考图与角色图是一个字段还是两个
- [ ] `Character.description` 前端要不要跟着存
- [ ] `jump` 动作类型后端加不加
- [ ] 上传模块何时提交
30 changes: 30 additions & 0 deletions frontend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Windup 前端

React + Vite + TypeScript。

## 开发

```bash
npm ci
npm run dev
```

## 检查

```bash
npm run format:check # 格式
npm run lint # 静态检查
npm run typecheck # 类型
npm run test # 测试(本阶段无测试文件)
npm run build # 构建
```

CI 按上面顺序全跑一遍。

## 结构

模块划分、依赖规则与命名约定见仓库根目录 `frontend-architecture-v3.md`。

**本阶段只提交模块边界与接口,不含实现。** 页面是占位外壳,各模块只有类型与 `XxxApis` 接口。实现按模块拆成后续 PR。

与后端尚未对齐的接口见 `API_CONTRACT.md`。
12 changes: 12 additions & 0 deletions frontend/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Windup · 2D 角色资产生成</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading