chore: 初始版本提交 - 简化架构 + 轮询改造

- 移除 Motia Streams 实时通信,改用 3 秒轮询
- 简化前端代码,移除冗余组件
- 简化后端架构,准备 FastAPI 重构
- 更新 pixi.toml 环境配置
- 保留 bttoxin_digger_v5_repro 作为参考文档

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zly
2026-01-13 16:50:09 +08:00
parent 4c9a7d0978
commit fe353fc0bc
134 changed files with 1237947 additions and 2518 deletions

View File

@@ -2,60 +2,83 @@
## Overview
BtToxin Task Monitor - Vue 3 frontend for submitting and monitoring BtToxin pipeline analysis tasks.
BtToxin Pipeline Frontend - Vue 3 frontend for submitting and monitoring analysis tasks.
## Tech Stack
- **Framework**: Vue 3 (Composition API with `<script setup>`)
- **Build Tool**: Vite 7
- **Build Tool**: Vite
- **UI Library**: Element Plus
- **State Management**: Pinia
- **Routing**: Vue Router 4
- **HTTP Client**: Axios
- **Testing**: Vitest + fast-check (property-based testing)
- **HTTP Client**: fetch API (polling-based)
- **Testing**: Vitest + fast-check
- **Linting**: ESLint + Prettier
## Key Changes (v2.0)
### Polling vs Real-time Streams
The previous version used Motia Streams for real-time updates. The current version uses simple HTTP polling:
- **Old**: SSE/WebSocket streams for real-time updates
- **New**: `setInterval` polling every 3 seconds
- **Benefit**: Simpler architecture, no external dependencies
### Task Flow
```
1. Upload .fna file
2. POST /api/tasks -> get task_id
3. Navigate to /{task_id}
4. Poll GET /api/tasks/{task_id} every 3s
5. On completion, download results
```
## Project Structure
```
frontend/
├── src/
│ ├── api/ # API client modules
│ │ ├── http.ts # Axios instance configuration
│ │ ── task.ts # Task API endpoints
│ ├── bttoxin.ts # BtToxin-specific API
│ │ └── types.ts # API type definitions
├── components/ # Reusable Vue components
│ │ └── task/ # Task-related components
│ ├── TaskFlowPanel.vue
│ ├── TaskStatusBar.vue
│ │ ├── TaskStepLogDrawer.vue
│ │ └── TaskSubmitForm.vue
│ ├── composables/ # Vue composables (hooks)
│ │ ── useAsync.ts # Async operation helper
│ ├── useMotiaStreams.ts # Real-time stream connection
│ │ └── useTaskState.ts # Task state management
│ ├── stores/ # Pinia stores
│ └── toxin.ts # Toxin analysis state
│ ├── types/ # TypeScript type definitions
│ │ └── task.ts # Task-related types
│ ├── utils/ # Utility functions
│ │ ├── error.ts # Error handling utilities
│ │ └── task.ts # Task helper functions
│ ├── views/ # Page components
│ │ ├
/TaskMonitorView.vue # Task monitoring page
│ │ └── TaskSubmitView.vue # Task submission page
│ ├── router/ # Vue Router configuration
│ ├── App.vue # Root component
│ └── main.ts # Application entry point
├── public/ # Static assets
├── package.json # Dependencies and scripts
├── vite.config.ts # Vite configuration
├── vitest.config.ts # Vitest configuration
└── tsconfig.json # TypeScript configuration
│ ├── api/
│ │ ├── http.ts # Axios instance (deprecated, using fetch)
│ │ ── task.ts # Task API functions (polling-based)
│ ├── components/
│ │ └── task/
│ ├── TaskSubmitForm.vue # Task submission form
│ │ └── (legacy components removed)
├── composables/ # Vue composables
├── views/
│ │ ├── TaskSubmitView.vue # Task submission page
│ │ └── TaskMonitorView.vue # Task status page (polling)
│ ├── types/
│ │ ── task.ts # Task types and utilities
│ ├── router/
│ │ └── index.ts # Vue Router config
│ ├── App.vue # Root component
│ └── main.ts # Application entry point
├── public/
├── package.json
├── vite.config.ts
└── tsconfig.json
```
## Pages
### Task Submit Page (`/`)
- Upload .fna file (drag & drop)
- Configure parameters (min_identity, min_coverage, etc.)
- Submit and navigate to task page
### Task Monitor Page (`/{taskId}`)
- Poll task status every 3 seconds
- Display progress bar and current stage
- Show estimated time remaining
- Download results when complete
- 30-day retention notice
## Development Commands
### Via pixi (recommended)
@@ -82,7 +105,7 @@ pixi run fe-lint
```bash
cd frontend
pnpm install
pnpm dev
pnpm dev --host
pnpm build
pnpm test:unit
pnpm lint
@@ -93,49 +116,109 @@ pnpm lint
### Component Patterns
- Use `<script setup lang="ts">` for all components
- Use Composition API with composables for reusable logic
- Use Composition API with composables
- Prefer `ref()` and `computed()` over reactive objects
- Use `defineProps<T>()` and `defineEmits<T>()` for type-safe props/events
### File Naming
- Components: PascalCase (`TaskFlowPanel.vue`)
- Composables: camelCase with `use` prefix (`useTaskState.ts`)
- Utilities: camelCase (`error.ts`)
- Components: PascalCase (`TaskSubmitForm.vue`)
- Composables: camelCase with `use` prefix
- Utilities: camelCase (`task.ts`)
- Types: camelCase (`task.ts`)
### Element Plus Usage
- Import components via auto-import (unplugin-vue-components)
- Use `el-` prefix components directly in templates
- Follow Element Plus design patterns for forms and layouts
### State Management
- Use Pinia stores for global state
- Use composables for component-local reactive state
- Use `ref()` for component-local reactive state
- Prefer `readonly()` when exposing state to prevent mutations
## API Integration
The frontend connects to the FastAPI backend at `VITE_API_BASE_URL` (default: http://localhost:8000).
```typescript
import { createTask, getTaskStatus, downloadResult } from '@/api/task'
// Create task
const response = await createTask(formData)
// { task_id, token, status, created_at, expires_at, estimated_duration_seconds }
// Poll status
const status = await getTaskStatus(taskId)
// { task_id, status, progress, current_stage, estimated_remaining_seconds, ... }
// Download results
const blob = await downloadResult(taskId)
// Blob file for download
```
## Polling Implementation
```typescript
const POLL_INTERVAL = 3000 // 3 seconds
function startPolling(taskId: string) {
// Initial fetch
fetchStatus()
// Set up interval
pollTimer.value = window.setInterval(() => {
fetchStatus()
}, POLL_INTERVAL)
}
function stopPolling() {
if (pollTimer.value) {
clearInterval(pollTimer.value)
pollTimer.value = null
}
}
// Clean up on unmount
onUnmounted(() => {
stopPolling()
})
```
## Testing
Tests are located in `src/__tests__/` and `src/types/*.property.spec.ts`.
Tests are located in `src/__tests__/` and `src/types/*.spec.ts`.
```bash
# Run all tests
pixi run fe-test
# Run tests in watch mode (use pnpm directly)
# Run tests in watch mode
cd frontend && pnpm test:unit
```
### Property-Based Testing
## Environment Variables
Uses fast-check for property-based tests. See `src/types/task.property.spec.ts` for examples.
| Variable | Default | Description |
|----------|---------|-------------|
| `VITE_API_BASE_URL` | http://localhost:8000 | Backend API URL |
## API Integration
## Common Tasks
The frontend connects to the FastAPI backend at `http://localhost:8000/api/`.
### Adding a New Parameter
- Development proxy configured in `vite.config.ts`
- API client in `src/api/http.ts`
- Type definitions in `src/api/types.ts`
1. Update `TaskFormData` in `TaskSubmitForm.vue`
2. Add form field in template
3. Update `CreateTaskRequest` in `frontend/src/types/task.ts`
4. Update API call in `frontend/src/api/task.ts`
### Adding a New Pipeline Stage
1. Add stage to `PIPELINE_STAGES` in `frontend/src/types/task.ts`
2. Update stage display in `TaskMonitorView.vue`
3. Add stage handling in backend `web/backend/tasks.py`
## Removed Components
The following components were removed in v2.0:
- `TaskFlowPanel.vue` - Replaced with simpler stage list
- `TaskStatusBar.vue` - Integrated into TaskMonitorView
- `TaskStepLogDrawer.vue` - No longer needed (no real-time logs)
- `useMotiaStreams.ts` - Replaced with simple polling
- `useTaskState.ts` - Replaced with direct API calls