Files
bttoxin-pipeline/frontend/AGENTS.md
zly fe353fc0bc chore: 初始版本提交 - 简化架构 + 轮询改造
- 移除 Motia Streams 实时通信,改用 3 秒轮询
- 简化前端代码,移除冗余组件
- 简化后端架构,准备 FastAPI 重构
- 更新 pixi.toml 环境配置
- 保留 bttoxin_digger_v5_repro 作为参考文档

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-13 16:50:09 +08:00

5.4 KiB

Frontend Agent Guide

Overview

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
  • UI Library: Element Plus
  • State Management: Pinia
  • Routing: Vue Router 4
  • 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/
│   │   ├── 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

# Install dependencies
pixi run fe-install

# Start dev server (http://localhost:5173)
pixi run fe-dev

# Build for production
pixi run fe-build

# Run tests
pixi run fe-test

# Lint code
pixi run fe-lint

Via pnpm directly

cd frontend
pnpm install
pnpm dev --host
pnpm build
pnpm test:unit
pnpm lint

Coding Conventions

Component Patterns

  • Use <script setup lang="ts"> for all components
  • 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 (TaskSubmitForm.vue)
  • Composables: camelCase with use prefix
  • Utilities: camelCase (task.ts)
  • Types: camelCase (task.ts)

State Management

  • Use Pinia stores for global 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).

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

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/*.spec.ts.

# Run all tests
pixi run fe-test

# Run tests in watch mode
cd frontend && pnpm test:unit

Environment Variables

Variable Default Description
VITE_API_BASE_URL http://localhost:8000 Backend API URL

Common Tasks

Adding a New Parameter

  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