# AGENTS.md This file provides coding guidelines and commands for AI agents working in this repository. ## Project Overview This is a **PySide6-based desktop application** for inspection management and file system browsing. The project includes: - GUI components for inspection workflows (incoming/manual inspection) - Database integration with PostgreSQL - XML parsing for element analysis data - File system browser utility **Tech Stack**: Python 3.8+, PySide6 6.7.1, PostgreSQL (psycopg2), pywin32 --- ## Build & Run Commands ### Installation ```bash # Create virtual environment (recommended) python -m venv venv source venv/bin/activate # Windows: venv\Scripts\activate # Install dependencies pip install -r requirements.txt ``` ### Running the Application ```bash # Main inspection application python run.py # File system browser (legacy) python src/main.py ``` ### Testing **Note**: This project currently has no test suite. When adding tests: ```bash # Install pytest pip install pytest pytest-qt # Run all tests pytest # Run single test file pytest tests/test_xml_parser.py # Run single test function pytest tests/test_xml_parser.py::test_parse_valid_xml # Run with verbose output pytest -v # Run with coverage pytest --cov=src --cov-report=html ``` ### Linting & Formatting **Note**: No linter/formatter is currently configured. Recommended setup: ```bash # Install tools pip install black flake8 mypy # Format code black src/ ui/ utils/ # Lint code flake8 src/ ui/ utils/ --max-line-length=120 # Type checking mypy src/ ui/ utils/ ``` --- ## Code Style Guidelines ### 1. Imports - **Order**: Standard library → Third-party → Local modules - **Style**: Absolute imports preferred; relative imports allowed within packages - **Grouping**: Separate groups with blank lines ```python # Standard library import os from pathlib import Path from dataclasses import dataclass from typing import List, Dict, Optional from datetime import datetime # Third-party from PySide6.QtWidgets import QMainWindow, QWidget from PySide6.QtCore import Qt import psycopg2 # Local from src.db_manager import DatabaseManager from ui.inspection_card import InspectionCard ``` ### 2. Formatting - **Line length**: ~120 characters (flexible, not enforced) - **Indentation**: 4 spaces (no tabs) - **Quotes**: Double quotes for strings (not strictly enforced) - **Blank lines**: 2 between top-level classes/functions, 1 within classes ### 3. Naming Conventions - **Classes**: `PascalCase` (e.g., `FileSystemReader`, `InspectionWindow`) - **Functions/Methods**: `snake_case` (e.g., `get_files_and_folders`, `parse_file`) - **Variables**: `snake_case` (e.g., `sample_name`, `data_list`) - **Constants**: `UPPER_SNAKE_CASE` (e.g., `MAX_RETRIES`) - **Private members**: Prefix with `_` (e.g., `_get_file_type`) ### 4. Type Hints - **Usage**: Encouraged but not mandatory - **Style**: Use `typing` module for complex types - **Return types**: Always specify for public methods ```python from typing import List, Dict, Optional def get_files_and_folders(self) -> List[FileInfo]: """Returns list of file information objects""" pass def parse_file(self, file_path: str) -> tuple[Optional[List[Dict]], str]: """Returns (data, error_message)""" pass ``` ### 5. Docstrings - **Style**: Google-style docstrings (simple format) - **Required for**: Public classes, public methods, complex functions - **Not required for**: Simple getters/setters, obvious utility functions ```python def get_files_and_folders(self) -> List[FileInfo]: """ Read all files and folders from the root path Returns: List[FileInfo]: List of file information objects """ pass ``` ### 6. Error Handling - **Philosophy**: Fail gracefully, skip inaccessible resources - **Pattern**: Try-except with specific exceptions, return None/empty on failure - **Logging**: Use `print()` for errors (no logging framework configured) ```python try: conn = psycopg2.connect(**self.config) return conn except Exception as e: print(f"Database connection error: {e}") return None ``` ### 7. Data Classes - Use `@dataclass` for simple data containers - Include type hints for all fields - Add `@property` methods for computed values ```python from dataclasses import dataclass @dataclass class FileInfo: name: str path: str size: int file_type: str is_dir: bool modified_time: str @property def size_readable(self) -> str: """Convert size to human-readable format""" # Implementation ``` ### 8. PySide6 GUI Patterns - **Initialization**: All UI setup in `__init__` - **Layouts**: Use explicit layout objects (QVBoxLayout, QHBoxLayout) - **Styling**: Inline stylesheets for component-specific styles - **Font**: Microsoft YaHei for Chinese text support ```python class InspectionWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("检验管理系统") # Setup layouts central_widget = QWidget() self.setCentralWidget(central_widget) main_layout = QVBoxLayout(central_widget) ``` ### 9. Database Patterns - **Connection**: Create connection per operation, close immediately - **Queries**: Use parameterized queries (never string interpolation) - **Schema**: Explicitly specify schema with `self.schema` variable - **Cursors**: Use `RealDictCursor` for dict-like results ```python def get_connection(self): try: conn = psycopg2.connect(**self.config) return conn except Exception as e: print(f"Database connection error: {e}") return None ``` ### 10. File Operations - **Path handling**: Use `pathlib.Path` (not `os.path`) - **Existence checks**: Always check before operations - **Encoding**: UTF-8 default (not explicitly specified) ```python from pathlib import Path def parse_file(self, file_path): if not os.path.exists(file_path): return None, f"文件未找到: {file_path}" ``` --- ## Project-Specific Rules 1. **Minimal Comments**: Code should be self-explanatory; avoid redundant comments 2. **Chinese UI Text**: All user-facing strings in Chinese (e.g., "入检", "手检") 3. **No Tests**: Currently no test suite; add tests when implementing new features 4. **Entry Points**: `run.py` for inspection app, `src/main.py` for file browser 5. **Database Credentials**: Hardcoded in `db_manager.py` (not production-ready) 6. **Error Messages**: Return tuple `(data, error_message)` pattern for parsers --- ## Common Patterns ### Adding a New UI Component 1. Create class in `ui/` directory 2. Inherit from appropriate PySide6 widget 3. Initialize layout in `__init__` 4. Use inline stylesheets for custom styling ### Adding Database Operations 1. Add method to `DatabaseManager` class 2. Use `get_connection()` to obtain connection 3. Always close connection in `finally` block or after operation 4. Return tuple `(success: bool, message: str)` for write operations ### Parsing New XML Structures 1. Add method to `XmlParser` class 2. Use `xml.etree.ElementTree` for parsing 3. Return tuple `(data: Optional[List[Dict]], error: str)` 4. Handle missing elements gracefully with `None` defaults --- ## Notes for AI Agents - **Preserve existing functionality**: Only modify code directly related to the task - **No unnecessary refactoring**: Keep changes minimal and targeted - **Test manually**: No automated tests; verify changes by running the application - **Database access**: Be cautious with database operations; test queries carefully - **Chinese text**: Maintain Chinese for UI elements, English for code/comments