Files
frontend/AGENTS.md
T
2026-06-04 10:26:05 +08:00

9.0 KiB

Agent Instructions for Trace Frontend

Build & Development Commands

Development

pnpm dev                # Start dev server at http://localhost:5173

Build

pnpm build              # Build for production (outputs to dist/)
pnpm preview            # Preview production build

Testing & Linting

No test or lint commands are currently configured. When adding tests, use Vitest or Jest.

Project Overview

This is a React 19 + TypeScript frontend for the Zhejiang Beifan Trace Management Platform (溯源管理平台). It provides:

  • Public query interface for serial number verification
  • Admin dashboard for QR code generation and company management
  • Employee management with automatic employee serial generation
  • Aftersales work-order management for admins and technicians
  • User authentication and profile management

Tech Stack: React 19, TypeScript, Vite 7, Ant Design 6, React Router v7, Axios

Code Style Guidelines

File Organization

src/
├── components/        # Reusable UI components (AdminLayout, etc.)
├── pages/            # Page components (Login, Dashboard, etc.)
├── services/         # API service layer (api.ts with domain-specific APIs)
├── types/            # TypeScript type definitions (index.ts)
├── hooks/            # Custom React hooks
├── utils/            # Utility functions
├── styles/           # Global CSS files
├── assets/           # Static assets (images, etc.)
├── App.tsx           # Main app with routes
└── main.tsx          # Application entry point

Imports

  • Use @/ alias for src directory (configured in vite.config.ts and tsconfig.json)
  • Group imports: React/hooks first, then third-party libraries, then internal imports
  • Example:
    import { useState } from 'react';
    import { Form, Input, Button } from 'antd';
    import { UserOutlined } from '@ant-design/icons';
    import { useNavigate } from 'react-router-dom';
    import { authApi } from '@/services/api';
    import type { User } from '@/types';
    

Naming Conventions

  • Components: PascalCase (e.g., LoginPage, AdminLayout)
  • Functions/Methods: camelCase (e.g., handleLogin, loadStats)
  • Constants: UPPER_SNAKE_CASE (e.g., API_BASE_URL)
  • Types/Interfaces: PascalCase (e.g., User, Company, ApiResponse<T>)
  • Files: PascalCase for components/pages, lowercase for services/utils

TypeScript

  • All new code must be TypeScript
  • Use interface for object shapes, type for unions/aliases
  • Explicit return types for API functions and handlers
  • Use any only as last resort - prefer unknown with type guards
  • Strict mode enabled: no unused locals, no unused parameters

Component Patterns

  • Use functional components with hooks
  • For pages: use function PageName() (not arrow functions)
  • For layout/reusable components: use function ComponentName()
  • Export with export default ComponentName;
  • Use Ant Design components via destructuring: const { Button, Form } = antd;

Error Handling

  • Use try-catch blocks for async operations
  • Display errors with Ant Design message.error()
  • API services throw errors with descriptive messages
  • Global axios interceptor handles 401 (auth) and 404 (not found) automatically

API Services

  • API calls organized by domain in src/services/api.ts:
    • authApi - Authentication (login, logout, profile)
    • serialApi - Serial number management
    • companyApi - Company management
    • dashboardApi - Dashboard statistics
    • employeeSerialApi - Employee serial management
    • aftersalesApi - Aftersales work orders (admin + public)
    • employeesApi - Employee management (admin only): create/list/update/delete/reset password
    • usersApi - Assignable technician/admin picker via assignable
  • Auth token automatically added via axios interceptor
  • All API calls return typed responses based on src/types/index.ts

Routing

  • Use React Router v7 with <Routes> and <Route> components
  • Protected routes wrapped with <PrivateRoute> component
  • Admin pages wrapped with <AdminRoutes> layout component
  • Use useNavigate() for programmatic navigation
  • Use useLocation() to get current path
  • Public routes (no auth): /login, /query, /aftersales/:serialNumber
  • PublicQuery auto-redirects scanned zjbf-sh-* serials to /aftersales/:serialNumber
  • Shared public-page chrome (logo + 备案 footer) lives in components/PublicLayout.tsx
  • /admin/employee-serials is the employee management page despite the legacy route name.
  • Technicians should only see/use the aftersales module; admins see all admin menu items.

Roles and Employee Management

  • UserRole is limited to admin / technician / employee.
  • admin: full backend access.
  • technician: work-order module access only.
  • employee: no backend login access.
  • Employee creation fields are name, phone, employee number, position, and role.
  • Password field is shown and required only for admin and technician.
  • Employee creation uses employeesApi.create, and the backend automatically creates the employee serial; do not implement a separate "create then assign code" primary flow.
  • Employee rows should display generated employeeSerials from the employee list response.
  • Employee rows should provide a QR-code view for the active employee serial, using /query?serial=... as the scan target.
  • Public employee serial queries should show employee name, phone, employee number, and position.

Aftersales Conventions

  • Aftersales serial format is zjbf-sh-YYMMDDNN (daily sequence), e.g. zjbf-sh-26052801.
  • Service type values must use software / hardware / maintenance:
    • software: 软件故障
    • hardware: 硬件故障
    • maintenance: 售后维保
  • Aftersales companyName is a customer-company text field only. Do not call company-management APIs or create managed companies from aftersales create/update flows.
  • Use label text 现场情况说明 for issueDescription in create/detail/public-confirm views.
  • In admin detail page, use 工单分配 as the UI label for reassign action.
  • Signature display text should be 客户确认签名.

State Management

  • Use React hooks (useState, useEffect) for local component state
  • Authentication state persisted in localStorage via authApi
  • No global state management library currently used

Styling

  • Global styles in src/styles/global.css
  • Component-specific CSS in co-located styles directory (e.g., pages/styles/Login.css)
  • Import component styles with relative path: import './styles/PageName.css';
  • Use Ant Design components for primary UI, custom CSS for layout specifics

Locale & Internationalization

  • Chinese (zh_CN) locale configured globally via ConfigProvider in main.tsx
  • All UI text should be in Chinese
  • Ant Design components automatically use Chinese locale

Key Patterns & Conventions

Page Component Structure

function PageName() {
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState<DataType | null>(null);

  useEffect(() => {
    loadData();
  }, []);

  const loadData = async () => {
    setLoading(true);
    try {
      const result = await apiMethod();
      setData(result);
    } catch (error: any) {
      message.error(error.message || '加载数据失败');
    } finally {
      setLoading(false);
    }
  };

  if (loading) {
    return <Spin size="large" />;
  }

  return <div>{/* JSX content */}</div>;
}

export default PageName;

Route Guards

  • <PrivateRoute /> - Redirects to /login if not authenticated
  • <PublicRoute children={...} /> - Redirects to /admin/dashboard if authenticated
  • Use <Outlet /> for nested routes

Environment Variables

  • Use Vite's import.meta.env.VITE_* pattern
  • Example: const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || '/api';
  • Define in .env file (not committed to git)

Notes for Agents

  1. No tests configured: When adding test frameworks, update AGENTS.md accordingly
  2. No linter configured: Consider adding ESLint and Prettier
  3. Authentication flow: Tokens stored in localStorage, added to requests via interceptor
  4. API proxy: /api requests proxied to http://localhost:3000 during dev (see vite.config.ts)
  5. QR Code generation: Uses qrcode library for generating QR codes for serial numbers
  6. Admin Layout: Uses Ant Design Layout with Sider navigation and Header
  7. Type safety: Always add types for new props, state, and API responses

Common Tasks

Add a new API endpoint

  1. Add interface to src/types/index.ts
  2. Add method to appropriate API object in src/services/api.ts
  3. Handle errors appropriately with descriptive messages

Add a new page

  1. Create component in src/pages/PageName.tsx
  2. Add CSS file in src/pages/styles/PageName.css
  3. Add route in src/App.tsx
  4. If admin page, wrap in <AdminRoutes /> and add menu item in AdminLayout.tsx

Add a new component

  1. Create in src/components/ComponentName.tsx
  2. Add styles in src/components/styles/ComponentName.css if needed
  3. Import using @/components/ComponentName