From acdad260d7b4c52efb9c1f6102ef2a8187efdd9c Mon Sep 17 00:00:00 2001 From: caoxiaozhu Date: Fri, 10 Jul 2026 16:47:29 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E4=B8=8E=E8=A7=86=E8=A7=89=E8=B5=B0=E6=9F=A5?= =?UTF-8?q?=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 视觉走查记录、设计方案规格(specs)、实施计划(plans)及配套截图资产,覆盖路由过渡、页面表层级、数据处理向导、训练日志重设计等改进项。 --- design-qa.md | 160 ++++++ .../2026-07-10-data-process-create-wizard.md | 458 ++++++++++++++++++ .../2026-07-10-multi-file-preview-selector.md | 126 +++++ .../2026-07-10-page-surface-classification.md | 94 ++++ .../2026-07-10-preview-slice-edit-mode.md | 77 +++ .../plans/2026-07-10-route-transition.md | 78 +++ .../2026-07-10-source-upload-file-list.md | 202 ++++++++ ...026-07-10-source-upload-file-pagination.md | 131 +++++ ...2026-07-10-training-log-detail-redesign.md | 128 +++++ ...26-07-09-frontend-visual-refresh-design.md | 267 ++++++++++ ...07-10-data-process-create-wizard-design.md | 194 ++++++++ ...7-10-page-surface-classification-design.md | 53 ++ ...26-07-10-preview-slice-edit-mode-design.md | 25 + .../2026-07-10-route-transition-design.md | 27 ++ ...26-07-10-source-upload-file-list-design.md | 86 ++++ ...2026-07-10-training-log-detail-redesign.md | 68 +++ .../01-create-task.png | Bin 0 -> 51272 bytes .../02-unstructured-step-change.png | Bin 0 -> 55225 bytes .../03-implementation-create-1440.png | Bin 0 -> 83816 bytes .../04-implementation-preview-1440.png | Bin 0 -> 130276 bytes ...tune-create-double-surface-before-1440.png | Bin 0 -> 69769 bytes ...-tune-create-single-surface-final-1440.png | Bin 0 -> 52718 bytes ...fine-tune-list-self-surface-final-1440.png | Bin 0 -> 78162 bytes .../model-edit-white-page-canvas-1440.png | Bin 0 -> 55483 bytes ...odel-edit-white-page-canvas-final-1440.png | Bin 0 -> 53810 bytes ...ge-surface-reference-detail-comparison.png | Bin 0 -> 399149 bytes .../assets/page-white-canvas-comparison.png | Bin 0 -> 148926 bytes .../assets/page-white-canvas-reference.png | Bin 0 -> 119541 bytes .../assets/route-transition-detail-final.png | Bin 0 -> 64285 bytes ...ining-log-detail-comparison-normalized.png | Bin 0 -> 871578 bytes .../assets/training-log-detail-comparison.png | Bin 0 -> 1304296 bytes ...g-log-detail-default-canvas-final-1440.png | Bin 0 -> 78307 bytes ...log-detail-final-comparison-normalized.png | Bin 0 -> 877011 bytes ...ing-log-detail-final-comparison-params.png | Bin 0 -> 462036 bytes ...raining-log-detail-final-expanded-1440.png | Bin 0 -> 89524 bytes ...raining-log-detail-final-expanded-full.png | Bin 0 -> 8926 bytes ...ning-log-detail-global-surface-1440-v2.png | Bin 0 -> 87953 bytes ...raining-log-detail-implementation-1440.png | Bin 0 -> 88647 bytes ...detail-implementation-expanded-1440-v2.png | Bin 0 -> 85299 bytes ...og-detail-implementation-expanded-1440.png | Bin 0 -> 51740 bytes ...etail-implementation-expanded-top-1440.png | Bin 0 -> 89170 bytes .../assets/training-log-detail-option-2.png | Bin 0 -> 907309 bytes ...ning-log-detail-white-page-canvas-1440.png | Bin 0 -> 85301 bytes ...og-detail-white-page-canvas-final-1440.png | Bin 0 -> 85298 bytes 44 files changed, 2174 insertions(+) create mode 100644 design-qa.md create mode 100644 docs/superpowers/plans/2026-07-10-data-process-create-wizard.md create mode 100644 docs/superpowers/plans/2026-07-10-multi-file-preview-selector.md create mode 100644 docs/superpowers/plans/2026-07-10-page-surface-classification.md create mode 100644 docs/superpowers/plans/2026-07-10-preview-slice-edit-mode.md create mode 100644 docs/superpowers/plans/2026-07-10-route-transition.md create mode 100644 docs/superpowers/plans/2026-07-10-source-upload-file-list.md create mode 100644 docs/superpowers/plans/2026-07-10-source-upload-file-pagination.md create mode 100644 docs/superpowers/plans/2026-07-10-training-log-detail-redesign.md create mode 100644 docs/superpowers/specs/2026-07-09-frontend-visual-refresh-design.md create mode 100644 docs/superpowers/specs/2026-07-10-data-process-create-wizard-design.md create mode 100644 docs/superpowers/specs/2026-07-10-page-surface-classification-design.md create mode 100644 docs/superpowers/specs/2026-07-10-preview-slice-edit-mode-design.md create mode 100644 docs/superpowers/specs/2026-07-10-route-transition-design.md create mode 100644 docs/superpowers/specs/2026-07-10-source-upload-file-list-design.md create mode 100644 docs/superpowers/specs/2026-07-10-training-log-detail-redesign.md create mode 100644 docs/superpowers/specs/assets/data-process-create-audit/01-create-task.png create mode 100644 docs/superpowers/specs/assets/data-process-create-audit/02-unstructured-step-change.png create mode 100644 docs/superpowers/specs/assets/data-process-create-audit/03-implementation-create-1440.png create mode 100644 docs/superpowers/specs/assets/data-process-create-audit/04-implementation-preview-1440.png create mode 100644 docs/superpowers/specs/assets/fine-tune-create-double-surface-before-1440.png create mode 100644 docs/superpowers/specs/assets/fine-tune-create-single-surface-final-1440.png create mode 100644 docs/superpowers/specs/assets/fine-tune-list-self-surface-final-1440.png create mode 100644 docs/superpowers/specs/assets/model-edit-white-page-canvas-1440.png create mode 100644 docs/superpowers/specs/assets/model-edit-white-page-canvas-final-1440.png create mode 100644 docs/superpowers/specs/assets/page-surface-reference-detail-comparison.png create mode 100644 docs/superpowers/specs/assets/page-white-canvas-comparison.png create mode 100644 docs/superpowers/specs/assets/page-white-canvas-reference.png create mode 100644 docs/superpowers/specs/assets/route-transition-detail-final.png create mode 100644 docs/superpowers/specs/assets/training-log-detail-comparison-normalized.png create mode 100644 docs/superpowers/specs/assets/training-log-detail-comparison.png create mode 100644 docs/superpowers/specs/assets/training-log-detail-default-canvas-final-1440.png create mode 100644 docs/superpowers/specs/assets/training-log-detail-final-comparison-normalized.png create mode 100644 docs/superpowers/specs/assets/training-log-detail-final-comparison-params.png create mode 100644 docs/superpowers/specs/assets/training-log-detail-final-expanded-1440.png create mode 100644 docs/superpowers/specs/assets/training-log-detail-final-expanded-full.png create mode 100644 docs/superpowers/specs/assets/training-log-detail-global-surface-1440-v2.png create mode 100644 docs/superpowers/specs/assets/training-log-detail-implementation-1440.png create mode 100644 docs/superpowers/specs/assets/training-log-detail-implementation-expanded-1440-v2.png create mode 100644 docs/superpowers/specs/assets/training-log-detail-implementation-expanded-1440.png create mode 100644 docs/superpowers/specs/assets/training-log-detail-implementation-expanded-top-1440.png create mode 100644 docs/superpowers/specs/assets/training-log-detail-option-2.png create mode 100644 docs/superpowers/specs/assets/training-log-detail-white-page-canvas-1440.png create mode 100644 docs/superpowers/specs/assets/training-log-detail-white-page-canvas-final-1440.png diff --git a/design-qa.md b/design-qa.md new file mode 100644 index 0000000..0dce641 --- /dev/null +++ b/design-qa.md @@ -0,0 +1,160 @@ +# Training Log Detail Design QA + +## Evidence + +- Source visual truth: `docs/superpowers/specs/assets/training-log-detail-option-2.png` +- Implementation screenshot: `docs/superpowers/specs/assets/training-log-detail-final-expanded-1440.png` +- Collapsed implementation screenshot with global surface: `docs/superpowers/specs/assets/training-log-detail-global-surface-1440-v2.png` +- Normalized full-view comparison: `docs/superpowers/specs/assets/training-log-detail-final-comparison-normalized.png` +- Focused parameter comparison: `docs/superpowers/specs/assets/training-log-detail-final-comparison-params.png` +- White-canvas reference: `docs/superpowers/specs/assets/page-white-canvas-reference.png` +- White-canvas implementation: `docs/superpowers/specs/assets/model-edit-white-page-canvas-final-1440.png` +- White-canvas normalized comparison: `docs/superpowers/specs/assets/page-white-canvas-comparison.png` +- Training-log white-canvas screenshot: `docs/superpowers/specs/assets/training-log-detail-white-page-canvas-1440.png` +- Self-surface list screenshot: `docs/superpowers/specs/assets/fine-tune-list-self-surface-final-1440.png` +- Default-canvas detail screenshot: `docs/superpowers/specs/assets/training-log-detail-default-canvas-final-1440.png` +- Reference/detail comparison: `docs/superpowers/specs/assets/page-surface-reference-detail-comparison.png` +- Create-page duplicate-surface evidence: `docs/superpowers/specs/assets/fine-tune-create-double-surface-before-1440.png` +- Create-page single-surface evidence: `docs/superpowers/specs/assets/fine-tune-create-single-surface-final-1440.png` +- Route-transition flash reference: `/var/folders/nk/yks07zp14wb4rv3jqq0pt_4h0000gn/T/codex-clipboard-ea775434-828f-4bca-9714-72887faa9af9.png` +- Route-transition final detail frame: `docs/superpowers/specs/assets/route-transition-detail-final.png` +- Viewport: 1440 × 1024; comparison content normalized to 1200 × 800 after removing the existing 240px sidebar and 60px header from the implementation capture. +- State: `finance-sft-001`, completed, mock data loaded, training parameters expanded. + +## Full-view comparison + +The implementation preserves the selected two-column hierarchy: task and dataset information occupy the wide left track, runtime facts use the narrow right rail, and training parameters continue as a full-width disclosure section. The selected mock omitted the product shell, so the comparison intentionally crops the existing sidebar and header rather than treating them as design drift. + +The global product mode now uses two intentional surface modes. Form and detail routes render inside one `#ffffff` page canvas with 16px radius and 24px content padding. List routes that already own a white table/card surface render that surface directly on the `#f3f5f8` application background, avoiding a redundant white layer. + +## Required fidelity surfaces + +- Fonts and typography: Existing system font stack is preserved. Heading, label, value, and muted-copy hierarchy match the selected direction; output model uses body-level contrast after iteration 1, and all “未配置” values use `#64748b` on white after iteration 2. +- Spacing and layout rhythm: 24px main gap, 16px section gap, 12px surface radius, and light row separators match the selected composition. The existing application shell reduces usable content width, but normalized proportions remain aligned. +- Colors and tokens: Indigo accent, Slate text, success status, `#f3f5f8` page background, and white content surfaces are consistent with the current product. +- Image and icon fidelity: The screen contains no raster imagery. Existing Font Awesome icons are retained to match the repository's icon system; no placeholder, emoji, CSS drawing, or handcrafted SVG was introduced. +- Copy and content: Task name, status, model, date, duration, dataset metadata, storage, SFT, LoRA, and missing-value copy match the selected design and actual mock data. + +## Interaction and responsive checks + +- Parameter disclosure changed from `aria-expanded="false"` to `true` after activation, and the expanded content became visible. +- At 1000px viewport width, the overview changed to one column and the document had no horizontal overflow. +- At 700px viewport width, dataset metrics and parameter rows changed to one column and the document had no horizontal overflow. +- Browser console: no errors. One existing Element Plus `el-link` underline deprecation warning was emitted by the login flow and is unrelated to this page. + +## Comparison history + +### Iteration 1 — blocked + +- [P2] The implementation added a visible “基础训练参数” heading that did not exist in the selected mock, creating extra vertical space. +- [P2] “暂未生成” was styled too faintly compared with the selected design. + +Fixes: + +- Removed the redundant visible base-parameter heading while retaining an accessible region label. +- Restored body-level contrast for “暂未生成”. + +Post-fix evidence: + +- `docs/superpowers/specs/assets/training-log-detail-final-comparison-normalized.png` +- `docs/superpowers/specs/assets/training-log-detail-final-comparison-params.png` + +### Iteration 2 — blocked + +- [P2] “未配置” values used `#94a3b8` on white, below WCAG AA contrast for 14px text. + +Fix: + +- Updated muted values to `#64748b`; the regression check now calculates the contrast ratio and requires at least 4.5:1. + +Post-fix evidence: + +- Browser computed color: `rgb(100, 116, 139)`. +- Browser console: no errors. + +### Iteration 3 — passed + +No actionable P0/P1/P2 differences remain. The retained P3 difference is that the generated mock does not include the real product sidebar/header; this is an intentional constraint because the existing shell is shared by every page. + +### Iteration 4 — clarified global page canvas, passed + +- [P1] The earlier interpretation left the route content directly on the gray layout background and only made individual cards white. The clarified reference requires a single white page canvas behind every route. + +Fixes: + +- Split the shell and page tokens into `--app-shell-bg: #f3f5f8` and `--app-page-bg: #ffffff`. +- Added one global `.page-canvas` around every route in `MainLayout.vue`. +- Added 16px outer gutter, 16px canvas radius, 24px canvas padding, and a subtle canvas shadow. +- Flattened a route-root `PageCard` to prevent a duplicate large card layer. + +Post-fix evidence: + +- `docs/superpowers/specs/assets/page-white-canvas-comparison.png` +- Browser computed canvas: white background, 16px radius, 24px padding; outer shell: `rgb(243, 245, 248)`. +- Both the model-edit page and training-log page render inside the same global white canvas without horizontal overflow. + +### Iteration 5 — corrected list-page surface ownership, passed + +- [P1] Applying the white page canvas to every route created a redundant layer on list pages because `DataTablePage`, model evaluation, and model management already provide their own white root card. + +Fixes: + +- Added explicit `pageSurface: 'self'` metadata to each self-surfaced list route: model tuning, model evaluation, model inference, model management, data processing, and dataset management. +- Added `.page-canvas.is-self-surface` to remove the outer canvas padding, radius, background, and shadow only for those routes. +- Preserved the default white canvas for training-log, create, edit, preview, chat, and result routes. + +Post-fix evidence: + +- `docs/superpowers/specs/assets/fine-tune-list-self-surface-final-1440.png` +- `docs/superpowers/specs/assets/training-log-detail-default-canvas-final-1440.png` +- `docs/superpowers/specs/assets/page-surface-reference-detail-comparison.png` +- Browser computed list state: transparent outer canvas, 0px padding/radius, no shadow; white 12px-radius list card on `rgb(243, 245, 248)` shell. +- Browser computed detail state: white outer canvas, 24px padding, 16px radius, subtle shadow. +- Both states have no horizontal overflow and no console errors at 1440 × 900. + +### Iteration 6 — flattened wrapped root PageCard, passed + +- [P1] The training-task creation route wraps its root `PageCard` in `.fine-tune-create`. The earlier selector only matched a `PageCard` directly under `.page-canvas`, so this page retained a second white background, 12px radius, and card shadow. + +Fixes: + +- Added an explicit `.page-card-host` marker to the training-task creation route root; the layout flattens only a directly rendered root `PageCard` or a `PageCard` inside that explicit host. +- Root `PageCard` now uses a transparent background, 0px radius, no shadow, and no bottom margin while preserving its header/body layout. +- Kept the selector excluded from `.is-self-surface`, so list cards retain their own white background, 12px radius, and shadow. +- Rejected a generic one-level descendant selector because it would also match the training-log parameter card. + +Post-fix evidence: + +- `docs/superpowers/specs/assets/fine-tune-create-double-surface-before-1440.png` +- `docs/superpowers/specs/assets/fine-tune-create-single-surface-final-1440.png` +- Browser computed create-page root card: transparent background, 0px radius, no shadow; outer canvas remains white with 24px padding. +- Browser computed list-page card remains white with 12px radius and subtle shadow on a transparent outer canvas. +- Browser computed training-log parameter card remains white with 12px radius and subtle shadow, confirming that internal business cards are not flattened. +- Both pages have no horizontal overflow; create-page console has no errors. + +### Iteration 7 — removed page-level opacity transition, passed + +- [P1] When navigating from a self-surface list to a default-canvas secondary page, `route.meta.pageSurface` changed immediately while the old list remained for the 150ms `out-in` leave animation. The result was a semi-transparent old list rendered inside the new white canvas. + +Fixes: + +- Removed the page-level Vue `transition` wrapper from `MainLayout.vue`. +- Removed the `.fade-enter-*` and `.fade-leave-*` opacity rules. +- Preserved local component animations such as dialogs, disclosures, and the selected-row batch bar. + +Post-fix evidence: + +- Source flash frame: `/var/folders/nk/yks07zp14wb4rv3jqq0pt_4h0000gn/T/codex-clipboard-ea775434-828f-4bca-9714-72887faa9af9.png`. +- Final detail frame: `docs/superpowers/specs/assets/route-transition-detail-final.png`. +- Immediate state after list → create: old list absent, route-root opacity `1`, zero `.fade-*` transition elements, correct default canvas. +- Immediate state after create → list: old create page absent, route-root opacity `1`, zero `.fade-*` transition elements, correct self-surface canvas. +- Immediate state after list → training log: old list absent, route-root opacity `1`, zero `.fade-*` transition elements, correct default canvas. +- All three paths had no horizontal overflow; browser console had no errors. + +## Build evidence gap + +The `type-check` script now uses project-reference mode (`vue-tsc -b --noEmit`) so it no longer reports a false pass. `npm run type-check` and `npm run build` remain blocked by pre-existing TypeScript errors in `src/mock/adapter.ts`, `FineTuneCreateView.vue`, and `FineTuneListView.vue`; no remaining error points to `TrainingLogView.vue` or the page-surface files. `npx vite build` succeeds, proving the updated UI bundles for production. + +Design-QA final result: passed + +final result: passed diff --git a/docs/superpowers/plans/2026-07-10-data-process-create-wizard.md b/docs/superpowers/plans/2026-07-10-data-process-create-wizard.md new file mode 100644 index 0000000..166d3f1 --- /dev/null +++ b/docs/superpowers/plans/2026-07-10-data-process-create-wizard.md @@ -0,0 +1,458 @@ +# Data Process Create Wizard Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 将 `/data-process/create` 实现为固定四步向导,并在第二步提供“右侧选择切片、左侧自动定位并高亮原文”的可编辑对照体验。 + +**Architecture:** `DataProcessCreateView.vue` 只负责向导状态、步骤切换和跨步骤数据;每个步骤拆成独立 Vue 组件。源文定位和切片生成由纯 TypeScript 模块负责,第二步组件只消费偏移范围并同步滚动、高亮和编辑状态。现有 Vue 3、Element Plus、SCSS 和 Font Awesome 继续使用,不引入新依赖。 + +**Tech Stack:** Vue 3.5、TypeScript 5.7、Vite 6、Element Plus 2.9、SCSS、Node.js 回归脚本、`vue-tsc`。 + +## Global Constraints + +- 顶部固定四步:`创建任务`、`数据预览`、`开始生成`、`结果编辑与保存`。 +- 结构化和非结构化类型不得改变步骤数量。 +- 第二步桌面端左侧约 58% 为只读源文件,右侧约 42% 为切片或记录列表及编辑器。 +- 点击右侧条目时,左侧必须定位并高亮 `sourceStart` 到 `sourceEnd` 的原始范围。 +- 编辑切片不得改写源文件;来源映射始终指向初始原文。 +- 每一步只能有一个主操作,不得同时出现“下一步”和“开始生成”等竞争动作。 +- 页面继续使用现有全局白色页面画布,不新增整页嵌套白卡。 +- 不增加第三方依赖。 + +--- + +### Task 1: 建立四步向导回归测试 + +**Files:** +- Create: `frontend/scripts/regression-data-process-wizard.mjs` +- Modify: `frontend/package.json` +- Test: `frontend/scripts/regression-data-process-wizard.mjs` + +**Interfaces:** +- Consumes: Vue SFC 源码、`@vue/compiler-sfc`、`@vue/compiler-dom`。 +- Produces: `npm run test:data-process-wizard`,验证固定步骤、组件边界、对照定位标记和底部唯一主操作。 + +- [ ] **Step 1: 写入当前实现必然失败的结构回归检查** + +```js +import assert from 'node:assert/strict' +import { readFile } from 'node:fs/promises' +import path from 'node:path' +import { fileURLToPath } from 'node:url' +import { parse as parseSfc } from '@vue/compiler-sfc' + +const scriptDir = path.dirname(fileURLToPath(import.meta.url)) +const viewSource = await readFile( + path.resolve(scriptDir, '../src/views/data-process/DataProcessCreateView.vue'), + 'utf8', +) +const previewSource = await readFile( + path.resolve(scriptDir, '../src/views/data-process/create/PreviewCompareStep.vue'), + 'utf8', +) + +assert.match(viewSource, /const WIZARD_STEPS = \[/) +for (const title of ['创建任务', '数据预览', '开始生成', '结果编辑与保存']) { + assert.ok(viewSource.includes(`title: '${title}'`), `缺少固定步骤:${title}`) +} +assert.doesNotMatch(viewSource, /all\.filter|steps\s*=\s*computed/) +assert.match(previewSource, /class="source-viewer"/) +assert.match(previewSource, /class="preview-workspace"/) +assert.match(previewSource, /scrollIntoView/) +assert.match(previewSource, /sourceStart/) +assert.match(previewSource, /sourceEnd/) + +const { descriptor } = parseSfc(viewSource) +assert.ok(descriptor.template?.content.includes('TaskSetupStep')) +assert.ok(descriptor.template?.content.includes('PreviewCompareStep')) +assert.ok(descriptor.template?.content.includes('GenerationStep')) +assert.ok(descriptor.template?.content.includes('ResultEditorStep')) + +console.log('数据处理四步向导回归检查通过') +``` + +- [ ] **Step 2: 在 `package.json` 注册命令** + +```json +{ + "scripts": { + "test:data-process-wizard": "node scripts/regression-data-process-wizard.mjs" + } +} +``` + +- [ ] **Step 3: 运行测试并确认失败原因正确** + +Run: `cd frontend && npm run test:data-process-wizard` + +Expected: FAIL,首先因 `PreviewCompareStep.vue` 不存在或固定步骤断言不成立而失败。 + +### Task 2: 建立向导类型、草稿状态和来源映射模型 + +**Files:** +- Create: `frontend/src/views/data-process/create/types.ts` +- Create: `frontend/src/views/data-process/create/previewModel.ts` +- Test: `frontend/scripts/regression-data-process-wizard.mjs` + +**Interfaces:** +- Consumes: 上传文件解析出的字符串。 +- Produces: `ProcessType`、`StepId`、`PreviewItem`、`ResultItem`、`DataProcessDraft`;`buildPreviewItems(sourceText, processType)` 和 `sourceLines(sourceText)`。 + +- [ ] **Step 1: 在回归脚本增加模型文件和关键字段断言** + +```js +const typesSource = await readFile( + path.resolve(scriptDir, '../src/views/data-process/create/types.ts'), + 'utf8', +) +const modelSource = await readFile( + path.resolve(scriptDir, '../src/views/data-process/create/previewModel.ts'), + 'utf8', +) +for (const field of ['sourceStart', 'sourceEnd', 'originalContent', 'editedContent']) { + assert.ok(typesSource.includes(field), `PreviewItem 缺少字段:${field}`) +} +assert.match(modelSource, /export function buildPreviewItems/) +assert.match(modelSource, /export function sourceLines/) +``` + +- [ ] **Step 2: 定义稳定类型** + +```ts +export type ProcessType = 'structured' | 'unstructured' +export type StepId = 'create' | 'preview' | 'generate' | 'results' + +export interface PreviewItem { + id: string + originalContent: string + editedContent: string + sourceStart: number | null + sourceEnd: number | null + sourceStartLine: number | null + sourceEndLine: number | null + tokenCount: number + status: 'original' | 'modified' | 'manual' | 'invalid' +} + +export interface ResultItem { + id: string + instruction: string + input: string + output: string + status: 'valid' | 'modified' | 'invalid' + error?: string +} +``` + +- [ ] **Step 3: 实现可重复的来源偏移生成** + +```ts +export function buildPreviewItems(sourceText: string, processType: ProcessType): PreviewItem[] { + const lines = sourceText.split('\n') + const groupSize = processType === 'structured' ? 1 : 3 + let cursor = 0 + const ranges = lines.map((line, index) => { + const start = cursor + cursor += line.length + (index < lines.length - 1 ? 1 : 0) + return { line, lineNumber: index + 1, start, end: start + line.length } + }) + + const items: PreviewItem[] = [] + for (let index = 0; index < ranges.length; index += groupSize) { + const group = ranges.slice(index, index + groupSize) + if (!group.length || group.every((item) => !item.line.trim())) continue + const content = group.map((item) => item.line).join('\n') + items.push({ + id: `preview-${items.length + 1}`, + originalContent: content, + editedContent: content, + sourceStart: group[0].start, + sourceEnd: group[group.length - 1].end, + sourceStartLine: group[0].lineNumber, + sourceEndLine: group[group.length - 1].lineNumber, + tokenCount: Math.max(1, Math.ceil(content.length / 2)), + status: 'original', + }) + } + return items +} +``` + +- [ ] **Step 4: 运行回归检查和类型检查** + +Run: `cd frontend && npm run test:data-process-wizard && npm run type-check` + +Expected: 回归测试继续因组件未完成而失败;`previewModel.ts` 和 `types.ts` 不产生 TypeScript 错误。 + +### Task 3: 实现向导壳层和第一步创建任务 + +**Files:** +- Create: `frontend/src/views/data-process/create/TaskSetupStep.vue` +- Modify: `frontend/src/views/data-process/DataProcessCreateView.vue` +- Test: `frontend/scripts/regression-data-process-wizard.mjs` + +**Interfaces:** +- Consumes: `ProcessType`、Element Plus 表单与上传组件。 +- Produces: `TaskSetupStep` 的 `v-model:name`、`v-model:description`、`v-model:processType`、`file-change`、`remove-file` 事件;父页面提供固定 `WIZARD_STEPS` 和统一底部操作。 + +- [ ] **Step 1: 将父页面步骤定义改为不可变四步** + +```ts +const WIZARD_STEPS = [ + { id: 'create', title: '创建任务', desc: '填写任务信息与上传源数据' }, + { id: 'preview', title: '数据预览', desc: '核对源文件与预览内容' }, + { id: 'generate', title: '开始生成', desc: '确认摘要并启动处理' }, + { id: 'results', title: '结果编辑与保存', desc: '检查、修改并保存结果' }, +] as const +``` + +- [ ] **Step 2: 创建第一步组件,保留现有校验并改为视觉选择块** + +```ts +const props = defineProps<{ + name: string + description: string + processType: ProcessType + file: File | null + fileCount: number +}>() + +const emit = defineEmits<{ + 'update:name': [value: string] + 'update:description': [value: string] + 'update:processType': [value: ProcessType] + 'file-change': [file: UploadFile] + 'remove-file': [] +}>() +``` + +- [ ] **Step 3: 在父页面统一步骤导航和底部动作文案** + +```ts +const primaryActionLabel = computed(() => ({ + create: '继续:数据预览', + preview: '确认预览并继续', + generate: generation.progress === 100 ? '查看生成结果' : '开始生成', + results: '保存任务', +}[currentStepId.value])) +``` + +- [ ] **Step 4: 运行回归检查和类型检查** + +Run: `cd frontend && npm run test:data-process-wizard && npm run type-check` + +Expected: 回归测试因后续三个组件缺失而失败;第一步相关代码通过类型检查。 + +### Task 4: 实现左右源文件与切片同步预览 + +**Files:** +- Create: `frontend/src/views/data-process/create/PreviewCompareStep.vue` +- Modify: `frontend/src/views/data-process/DataProcessCreateView.vue` +- Test: `frontend/scripts/regression-data-process-wizard.mjs` + +**Interfaces:** +- Consumes: `sourceText: string`、`items: PreviewItem[]`、`selectedId: string | null`、`processType: ProcessType`。 +- Produces: `update:selectedId`、`update:item-content`、`restore:item`;选中条目变化时调用 `scrollIntoView({ block: 'center' })`。 + +- [ ] **Step 1: 增加源文范围与选中态的结构断言** + +```js +for (const marker of [ + 'source-viewer', + 'source-line', + 'is-highlighted', + 'preview-item', + 'preview-editor', + 'scrollIntoView', +]) { + assert.ok(previewSource.includes(marker), `第二步缺少结构:${marker}`) +} +``` + +- [ ] **Step 2: 通过行偏移判断高亮范围** + +```ts +function isLineHighlighted(lineStart: number, lineEnd: number) { + if (!selectedItem.value || selectedItem.value.sourceStart == null || selectedItem.value.sourceEnd == null) { + return false + } + return lineEnd >= selectedItem.value.sourceStart + && lineStart <= selectedItem.value.sourceEnd +} +``` + +- [ ] **Step 3: 选中切片后定位首个高亮行** + +```ts +watch(selectedItem, async (item) => { + if (!item || item.sourceStart == null) return + await nextTick() + sourceViewerRef.value + ?.querySelector(`[data-offset="${item.sourceStart}"]`) + ?.scrollIntoView({ block: 'center', behavior: 'smooth' }) +}) +``` + +- [ ] **Step 4: 编辑时只更新 `editedContent` 和状态** + +```ts +function updateContent(item: PreviewItem, value: string) { + emit('update:item-content', item.id, value) +} +``` + +父组件处理事件时不得修改 `sourceText`、`sourceStart` 或 `sourceEnd`: + +```ts +function updatePreviewContent(id: string, value: string) { + const item = draft.previewItems.find((entry) => entry.id === id) + if (!item) return + item.editedContent = value + item.status = value === item.originalContent ? 'original' : 'modified' + draft.dirty = true +} +``` + +- [ ] **Step 5: 完成搜索、仅看已修改、上一片、下一片和恢复原文** + +Run: `cd frontend && npm run test:data-process-wizard && npm run type-check` + +Expected: 第二步结构断言通过,类型检查通过;回归测试只因第三、四步组件缺失而失败。 + +### Task 5: 实现生成与结果编辑两个独立步骤 + +**Files:** +- Create: `frontend/src/views/data-process/create/GenerationStep.vue` +- Create: `frontend/src/views/data-process/create/ResultEditorStep.vue` +- Modify: `frontend/src/views/data-process/DataProcessCreateView.vue` +- Test: `frontend/scripts/regression-data-process-wizard.mjs` + +**Interfaces:** +- Consumes: 任务摘要、预览条目、生成状态和结果条目。 +- Produces: `start`、`stop`、`retry`、`update:result`、`restore:result`、`save` 事件。 + +- [ ] **Step 1: 生成步骤只保留摘要、进度与状态** + +```ts +const emit = defineEmits<{ + start: [] + stop: [] + retry: [] +}>() +``` + +生成完成前底部唯一主操作为 `开始生成`;生成进行中为禁用的 `正在生成`;完成后变为 `查看生成结果`。 + +- [ ] **Step 2: 清理并托管模拟生成计时器** + +```ts +let generationTimer: ReturnType | null = null + +function stopGenerationTimer() { + if (generationTimer) clearInterval(generationTimer) + generationTimer = null +} + +onBeforeUnmount(stopGenerationTimer) +``` + +- [ ] **Step 3: 将预览条目转换为结构化结果字段** + +```ts +function createResults(items: PreviewItem[]): ResultItem[] { + return items.slice(0, 12).map((item, index) => ({ + id: `result-${index + 1}`, + instruction: item.editedContent.split('\n')[0] || `数据条目 ${index + 1}`, + input: '', + output: item.editedContent.split('\n').slice(1).join('\n') || item.editedContent, + status: 'valid', + })) +} +``` + +- [ ] **Step 4: 使用左侧结果列表和右侧字段编辑器替代原始 JSON 文本框** + +```ts +function validateResult(item: ResultItem) { + item.error = item.instruction.trim() && item.output.trim() ? undefined : '指令和输出不能为空' + item.status = item.error ? 'invalid' : 'modified' +} +``` + +- [ ] **Step 5: 运行回归、页面表面和类型检查** + +Run: `cd frontend && npm run test:data-process-wizard && npm run test:page-surface && npm run type-check` + +Expected: 三项检查全部 PASS。 + +### Task 6: 完成视觉实现、响应式和浏览器验收 + +**Files:** +- Modify: `frontend/src/views/data-process/DataProcessCreateView.vue` +- Modify: `frontend/src/views/data-process/create/TaskSetupStep.vue` +- Modify: `frontend/src/views/data-process/create/PreviewCompareStep.vue` +- Modify: `frontend/src/views/data-process/create/GenerationStep.vue` +- Modify: `frontend/src/views/data-process/create/ResultEditorStep.vue` +- Test: `frontend/scripts/regression-data-process-wizard.mjs` + +**Interfaces:** +- Consumes: 已完成的四步组件和现有全局页面画布。 +- Produces: 与确认修订稿一致的桌面布局,以及 900px 以下的上下布局。 + +- [ ] **Step 1: 落实单层页面、固定步骤和底部操作栏样式** + +```scss +.wizard-footer { + position: sticky; + bottom: 0; + display: flex; + align-items: center; + justify-content: space-between; + min-height: 64px; + background: rgba(255, 255, 255, 0.98); + border-top: 1px solid #eef0f5; +} +``` + +- [ ] **Step 2: 落实桌面左右对照和 900px 响应式** + +```scss +.preview-workspace { + display: grid; + grid-template-columns: minmax(0, 58fr) minmax(380px, 42fr); +} + +@media (max-width: 900px) { + .preview-workspace { + grid-template-columns: minmax(0, 1fr); + } +} +``` + +- [ ] **Step 3: 启动页面并逐步验证四步交互** + +Run: `cd frontend && npm run dev -- --host 0.0.0.0 --port 6801` + +Browser checks at `http://localhost:6801/data-process/create`: + +1. 第一步上传文本并选择非结构化数据。 +2. 第二步点击至少三个右侧切片,确认左侧滚动目标和高亮范围变化。 +3. 修改一个切片并切换前后条目,确认修改状态和内容保留。 +4. 完成生成并进入第四步,修改结果字段并保存。 +5. 返回前一步,确认草稿和选中项未丢失。 +6. 以 1440×1024 和 900px 窄屏分别截图,确认无横向溢出和底部遮挡。 + +- [ ] **Step 4: 执行完整验证** + +Run: `cd frontend && npm run test:data-process-wizard && npm run test:page-surface && npm run type-check && npm run build` + +Expected: 所有回归脚本、类型检查和生产构建全部 PASS。 + +## Self-Review Result + +- 规格中的四步稳定语义由 Tasks 1、3、5 覆盖。 +- 左右对照、来源映射、滚动高亮、编辑不改源文件由 Tasks 2、4 覆盖。 +- 生成状态、计时器清理、结果字段校验由 Task 5 覆盖。 +- 单层白底、响应式、路由转场连续性和最终验收由 Task 6 覆盖。 +- 未引入新依赖;计划中所有类型和事件名在前置任务中已有定义。 + diff --git a/docs/superpowers/plans/2026-07-10-multi-file-preview-selector.md b/docs/superpowers/plans/2026-07-10-multi-file-preview-selector.md new file mode 100644 index 0000000..019c4fa --- /dev/null +++ b/docs/superpowers/plans/2026-07-10-multi-file-preview-selector.md @@ -0,0 +1,126 @@ +# 多文件预览下拉选择器 Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 在数据处理向导第二步中支持按文件切换原文和切片,同时保留现有双栏阅读空间。 + +**Architecture:** 为每个预览条目记录来源文件 ID;父页面按当前文件筛选原文与条目。预览组件只负责可搜索下拉选择器和当前文件双栏对照,不拼接不同文件的原文。 + +**Tech Stack:** Vue 3、TypeScript、Element Plus、SCSS、Node 回归脚本。 + +## Global Constraints + +- 预览主区保持原文与切片的双栏比例,不新增常驻第三栏。 +- 下拉选择器必须支持 100 个文件的名称筛选。 +- 切换文件不得丢失其他文件已编辑的切片内容。 + +--- + +### Task 1: 锁定多文件来源映射 + +**Files:** +- Modify: `frontend/scripts/regression-data-process-wizard.mjs` +- Modify: `frontend/src/views/data-process/create/types.ts` +- Modify: `frontend/src/views/data-process/create/previewModel.ts` + +**Interfaces:** +- Produces: `PreviewItem.sourceFileId: string`。 +- Produces: `buildPreviewItems(sourceText, processType, sourceFileId)` 为同一文件生成带文件归属的唯一条目。 + +- [ ] **Step 1: 写入失败断言** + +```js +assert.match(typesSource, /sourceFileId/, 'PreviewItem 缺少来源文件标识') +assert.match(modelSource, /sourceFileId/, '切片生成没有写入来源文件标识') +``` + +- [ ] **Step 2: 运行失败断言** + +Run: `npm run test:data-process-wizard` +Expected: FAIL,提示缺少 `sourceFileId`。 + +- [ ] **Step 3: 实现文件归属** + +```ts +export interface PreviewItem { + sourceFileId: string +} + +export function buildPreviewItems(sourceText: string, processType: ProcessType, sourceFileId: string) { + // 每个 item 写入 sourceFileId,并以它构造稳定 ID。 +} +``` + +- [ ] **Step 4: 再次运行回归脚本** + +Run: `npm run test:data-process-wizard` +Expected: 新断言通过;仅保留已知的布局失败(如存在)。 + +### Task 2: 按文件驱动双栏预览 + +**Files:** +- Modify: `frontend/src/views/data-process/DataProcessCreateView.vue` + +**Interfaces:** +- Consumes: `PreviewItem.sourceFileId`。 +- Produces: `activePreviewFile`、`activePreviewItems` 与当前文件选择状态。 + +- [ ] **Step 1: 为多文件下拉接线添加失败断言** + +```js +assert.match(viewSource, /selectedPreviewFileId/, '父页面缺少当前预览文件状态') +assert.match(viewSource, /buildPreviewItems\(file\.content, processType\.value, String\(file\.uid\)\)/, '预览没有按文件分别生成') +``` + +- [ ] **Step 2: 运行失败断言** + +Run: `npm run test:data-process-wizard` +Expected: FAIL,提示缺少当前预览文件状态。 + +- [ ] **Step 3: 最小实现** + +```ts +const activePreviewFile = computed(() => uploadedFiles.value.find((file) => String(file.uid) === selectedPreviewFileId.value)) +const activePreviewItems = computed(() => previewItems.value.filter((item) => item.sourceFileId === selectedPreviewFileId.value)) +``` + +- [ ] **Step 4: 运行回归脚本** + +Run: `npm run test:data-process-wizard` +Expected: 父页面多文件断言通过。 + +### Task 3: 加入可搜索文件下拉框与布局修复 + +**Files:** +- Modify: `frontend/src/views/data-process/create/PreviewCompareStep.vue` +- Modify: `frontend/src/views/data-process/DataProcessCreateView.vue` +- Modify: `frontend/scripts/regression-data-process-wizard.mjs` + +**Interfaces:** +- Consumes: `files`、`selectedFileId`、`items`、`sourceText`。 +- Produces: `update:selectedFileId` 事件。 + +- [ ] **Step 1: 添加失败断言** + +```js +assert.match(previewSource, /filterable/, '文件选择器必须可搜索') +assert.match(previewSource, /当前文件/, '预览缺少当前文件切换器') +``` + +- [ ] **Step 2: 运行失败断言** + +Run: `npm run test:data-process-wizard` +Expected: FAIL,提示缺少可搜索的文件选择器。 + +- [ ] **Step 3: 实现下拉框与响应式样式** + +```vue + + + +``` + +- [ ] **Step 4: 将 `.wizard-content` 设为 `min-height: 0` 并运行验证** + +Run: `npm run test:data-process-wizard && npm run type-check && npm run build` +Expected: 三个命令退出码均为 0。 diff --git a/docs/superpowers/plans/2026-07-10-page-surface-classification.md b/docs/superpowers/plans/2026-07-10-page-surface-classification.md new file mode 100644 index 0000000..e940582 --- /dev/null +++ b/docs/superpowers/plans/2026-07-10-page-surface-classification.md @@ -0,0 +1,94 @@ +# Page Surface Classification Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 列表页直接使用自身白色卡片,表单和详情页继续使用主布局提供的白色圆角画布。 + +**Architecture:** 使用 Vue Router `meta.pageSurface` 做显式页面表面分类。主布局默认渲染白色画布,仅在 `pageSurface === 'self'` 时切换为透明、无内边距的承载容器。 + +**Tech Stack:** Vue 3、Vue Router 4、TypeScript、SCSS、Node.js 回归脚本 + +## Global Constraints + +- 只给六个自带白色列表卡片的路由声明 `pageSurface: 'self'`。 +- 其他路由默认继续使用白色页面画布。 +- 不新增依赖,不修改业务逻辑。 +- 先写失败测试,再实现最小修复。 + +--- + +### Task 1: 路由级页面表面分类 + +**Files:** +- Modify: `frontend/scripts/regression-page-surface.mjs` +- Modify: `frontend/src/router/index.ts` +- Modify: `frontend/src/layouts/MainLayout.vue` +- Test: `frontend/scripts/regression-page-surface.mjs` + +**Interfaces:** +- Consumes: Vue Router 当前路由对象的 `route.meta.pageSurface`。 +- Produces: `pageSurface: 'self'` 路由元数据和 `.page-canvas.is-self-surface` 布局状态。 + +- [ ] **Step 1: 写入失败回归测试** + +在 `regression-page-surface.mjs` 中读取 `src/router/index.ts`,断言六个列表路由包含 +`pageSurface: 'self'`;断言 `MainLayout` 使用 `useRoute()` 和动态类;断言状态样式为: + +```scss +.page-canvas.is-self-surface { + padding: 0; + border-radius: 0; + background-color: transparent; + box-shadow: none; +} +``` + +- [ ] **Step 2: 运行测试并确认 RED** + +Run: `npm run test:page-surface` + +Expected: FAIL,提示列表路由缺少 `pageSurface: 'self'` 或主布局缺少自表面状态。 + +- [ ] **Step 3: 写入最小实现** + +在六个列表路由中加入: + +```ts +meta: { title: '页面标题', pageSurface: 'self' }, +``` + +在 `MainLayout.vue` 中使用: + +```ts +const route = useRoute() +``` + +```vue +
+``` + +并加入透明承载容器样式。 + +- [ ] **Step 4: 运行专项测试并确认 GREEN** + +Run: `npm run test:page-surface` + +Expected: PASS,输出“全局页面背景与内容表面回归检查通过”。 + +- [ ] **Step 5: 运行相关回归与生产构建** + +Run: `npm run test:training-log-layout` + +Expected: PASS。 + +Run: `npx vite build` + +Expected: build exit code 0;允许保留项目既有字体解析和 chunk size 警告。 + +- [ ] **Step 6: 浏览器视觉验证** + +打开 `/fine-tune`,确认灰色背景上仅有列表自身白色卡片;打开 +`/training-log/1`,确认白色圆角页面画布仍存在。两个页面均不得水平溢出,控制台不得新增错误。 diff --git a/docs/superpowers/plans/2026-07-10-preview-slice-edit-mode.md b/docs/superpowers/plans/2026-07-10-preview-slice-edit-mode.md new file mode 100644 index 0000000..6d8f0ec --- /dev/null +++ b/docs/superpowers/plans/2026-07-10-preview-slice-edit-mode.md @@ -0,0 +1,77 @@ +# 切片单面板编辑模式 Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 将数据预览右侧改为列表和编辑器互斥的单面板,并通过保存或取消控制切片内容写回。 + +**Architecture:** `PreviewCompareStep.vue` 保留切片筛选、分页和源文件定位,新增组件内编辑模式与临时草稿。父页面仅在收到保存事件时更新 `PreviewItem`,删除仍复用现有确认与删除事件。 + +**Tech Stack:** Vue 3 Composition API、TypeScript、Element Plus、Node 回归脚本。 + +## Global Constraints + +- 列表行只展示编号、来源行号及编辑、删除图标操作。 +- 编辑草稿未保存时不得更新 `PreviewItem.editedContent`。 +- 搜索、分页或切换文件时退出编辑模式并丢弃草稿。 +- 不新增依赖。 + +--- + +### Task 1: 切片列表与编辑模式切换 + +**Files:** +- Modify: `frontend/src/views/data-process/create/PreviewCompareStep.vue` +- Modify: `frontend/scripts/regression-data-process-wizard.mjs` + +**Interfaces:** +- Consumes: `PreviewItem`、`update:selectedId`、`update:item-content`、`remove:item`。 +- Produces: `openEditor(item)`、`closeEditor()`、`saveEditor()` 与列表/编辑互斥渲染。 + +- [ ] **Step 1: Write the failing test** + +在 `regression-data-process-wizard.mjs` 断言组件存在 `editingItemId` 和 `editorDraft`,列表以图标按钮触发 `openEditor` 与 `remove:item`,编辑模式拥有 `保存修改`、`取消` 与 `返回列表`,并且列表不再含 `item-token`、`item-status`、`modifiedOnly`。 + +- [ ] **Step 2: Run test to verify it fails** + +Run: `npm run test:data-process-wizard` + +Expected: FAIL,提示缺少单面板编辑模式结构。 + +- [ ] **Step 3: Write minimal implementation** + +在组件中增加以下状态和行为: + +```ts +const editingItemId = ref(null) +const editorDraft = ref('') + +function openEditor(item: PreviewItem) { + editingItemId.value = item.id + editorDraft.value = item.editedContent +} + +function closeEditor() { + editingItemId.value = null + editorDraft.value = '' +} + +function saveEditor() { + if (!editingItem.value) return + emit('update:item-content', editingItem.value.id, editorDraft.value) + closeEditor() +} +``` + +列表模式只渲染编号、来源和两个无文字图标按钮;编辑模式在同一位置渲染正文输入框以及返回、取消、保存操作。搜索、翻页、文件切换调用 `closeEditor()`。 + +- [ ] **Step 4: Run test to verify it passes** + +Run: `npm run test:data-process-wizard` + +Expected: `数据处理四步向导回归检查通过`。 + +- [ ] **Step 5: Build and visually verify** + +Run: `npx vite build` + +Expected: Vite completes successfully. Open the second wizard step, verify the list has only the two icon operations and that cancel does not change the selected slice content while save returns to the list. diff --git a/docs/superpowers/plans/2026-07-10-route-transition.md b/docs/superpowers/plans/2026-07-10-route-transition.md new file mode 100644 index 0000000..c4c8afb --- /dev/null +++ b/docs/superpowers/plans/2026-07-10-route-transition.md @@ -0,0 +1,78 @@ +# Route Transition Removal Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 移除主布局的页面级透明转场,消除列表与二级页面切换时的闪烁中间帧。 + +**Architecture:** `router-view` 直接渲染当前路由组件,不再包裹 Vue `transition`。页面表面仍由 `route.meta.pageSurface` 控制,因此内容和表面在同一轮渲染中同步更新。 + +**Tech Stack:** Vue 3、Vue Router 4、SCSS、Node.js 回归脚本 + +## Global Constraints + +- 删除页面级透明度转场。 +- 保留组件内部动画。 +- 不改变路由表面分类、业务逻辑或数据加载流程。 +- 先写失败测试,再实现最小修复。 + +--- + +### Task 1: 移除主布局页面级透明转场 + +**Files:** +- Modify: `frontend/scripts/regression-page-surface.mjs` +- Modify: `frontend/src/layouts/MainLayout.vue` +- Test: `frontend/scripts/regression-page-surface.mjs` + +**Interfaces:** +- Consumes: `router-view` 提供的当前路由组件。 +- Produces: 不带页面级透明度动画的同步路由内容渲染。 + +- [ ] **Step 1: 写入失败回归测试** + +在 `regression-page-surface.mjs` 中断言主布局模板不包含页面级 `transition`,并断言主布局样式不包含 `.fade-enter-*` 或 `.fade-leave-*`。 + +- [ ] **Step 2: 运行测试并确认 RED** + +Run: `npm run test:page-surface` + +Expected: FAIL,提示主布局仍包含页面级透明转场。 + +- [ ] **Step 3: 写入最小实现** + +将: + +```vue + + + +``` + +改为: + +```vue + +``` + +并删除主布局中的 `.fade-enter-active`、`.fade-leave-active`、`.fade-enter-from` 和 `.fade-leave-to` 样式。 + +- [ ] **Step 4: 运行专项回归并确认 GREEN** + +Run: `npm run test:page-surface` + +Expected: PASS,输出“全局页面背景与内容表面回归检查通过”。 + +- [ ] **Step 5: 运行相关回归与构建** + +Run: `npm run test:training-log-layout` + +Expected: PASS。 + +Run: `npx vite build` + +Expected: exit code 0;允许项目既有字体解析和 chunk size 警告。 + +- [ ] **Step 6: 浏览器往返验证** + +验证 `/fine-tune` → `/fine-tune/create`、`/fine-tune` → `/training-log/1` 以及二级页返回列表;页面内容与表面同步切换,无半透明旧页面、无水平溢出、无新增控制台错误。 + diff --git a/docs/superpowers/plans/2026-07-10-source-upload-file-list.md b/docs/superpowers/plans/2026-07-10-source-upload-file-list.md new file mode 100644 index 0000000..d4ca105 --- /dev/null +++ b/docs/superpowers/plans/2026-07-10-source-upload-file-list.md @@ -0,0 +1,202 @@ +# 源数据上传紧凑文件列表 Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 将数据处理创建页的已上传文件从大卡片改为固定高度、可滚动且可逐项操作的紧凑列表。 + +**Architecture:** 只修改 `TaskSetupStep` 的模板和局部样式,继续消费现有的 +`uploadedFiles` 属性并派发既有 `remove-file` 事件。使用同一组件内的标题栏和 +滚动容器管理信息密度,不改变上传、格式限制或父组件数据流。 + +**Tech Stack:** Vue 3 `