# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview QAUP-Management is an airport collision avoidance and management system built on the RuoYi framework. It integrates vehicle tracking, spatial analysis, and real-time monitoring for airport operations with Spring Boot 3.x and PostgreSQL + PostGIS. ## Architecture ### Multi-Module Maven Structure - **qaup-admin**: Main web application entry point containing controllers and startup configuration - **qaup-collision**: Core collision avoidance system with spatial analysis, WebSocket communication, and real-time monitoring - **qaup-framework**: Infrastructure layer with security, caching, and common configurations - **qaup-system**: User management, RBAC, and system administration - **qaup-common**: Shared utilities, constants, and base classes - **qaup-quartz**: Scheduled job management - **qaup-generator**: Code generation utilities ### Key Integration Pattern The collision avoidance system integrates with RuoYi through `QuapDataAdapter` (qaup-collision/src/main/java/com/qaup/collision/common/adapter/QuapDataAdapter.java:37), which bridges the collision detection system with RuoYi's service layer, avoiding direct DAO dependencies. ## Data Collection and Processing Architecture ### Critical Design Principle: Complete Service Separation **DataCollectorService and DataProcessingService MUST be completely separated** #### Service Responsibilities - **DataCollectorService** (250ms): - Only collects raw data from external APIs (position data, flight notifications) - Caches position data in activeMovingObjectsCache with NULL speed/direction - Caches flight notification data in flightNotificationCache - NO calculations, NO processing, NO WebSocket sending - Purpose: High-frequency data collection to ensure no data loss - **DataProcessingService** (1000ms): - Reads cached position data from DataCollectorService - Calculates speed and direction using SpeedCalculationService - Sends WebSocket position updates - Reads cached flight notification data from DataCollectorService - Sends WebSocket flight notification updates - Performs violation detection and path conflict detection - Saves data to database #### Implementation Pattern 1. **DataCollectorService Methods**: - `collectAircraftData()`, `collectVehicleData()`, `collectUnmannedVehicleData()` - position data collection - `collectFlightNotificationData()` - flight notification data collection - Store MovingObjects with NULL speed/direction in activeMovingObjectsCache - Cache FlightNotifications in flightNotificationCache - **FORBIDDEN**: No calculations, no WebSocket events, no processing 2. **DataProcessingService Methods**: - `performPeriodicDataProcessing()` - main processing loop - `calculateSpeedAndDirectionForAllObjects()` - calculate derived data - `sendPositionUpdatesForActiveObjects()` - WebSocket position messaging - `processFlightNotificationUpdates()` - WebSocket flight notification messaging - `performViolationDetection()` - rule engine integration - `saveUnmannedVehicleDataPeriodically()` - database persistence #### Cache Sharing Pattern - DataCollectorService owns activeMovingObjectsCache and flightNotificationCache - DataProcessingService receives cache references via setActiveMovingObjectsCache() and getFlightNotificationCache() - Both services share the same cache instances but have different responsibilities - Position data flows through activeMovingObjectsCache for calculation and WebSocket updates - Flight notification data flows through flightNotificationCache for WebSocket updates #### Why Complete Service Separation is Critical - **Data Integrity**: High-frequency collection prevents missing position updates - **Performance**: Separating collection from processing reduces computational load - **Accuracy**: Calculations based on processing intervals (1000ms) are more stable - **Architecture Clarity**: Clear separation of concerns makes system more maintainable - **Timing Consistency**: Avoids conflicts between collection and calculation frequencies #### Critical Rule **NEVER** place calculation logic or WebSocket publishing in DataCollectorService methods. **FORBIDDEN**: Direct eventPublisher.publishEvent() calls in collection methods ## Development Commands ### Build and Run ```bash # Full clean build (skip tests for faster builds) mvn clean install -DskipTests # Start backend from qaup-admin module cd qaup-admin mvn spring-boot:run # Start frontend (Vue.js) cd qaup-ui npm run dev # Production deployment using script ./ry.sh start ``` ### Testing and Debugging ```bash # Check port usage lsof -ti:8080 # Kill process if needed kill -9 # View logs tail -f qaup-admin/app.log ``` ## Technology Stack - **Backend**: Spring Boot 3.5.3 with Java 17, PostgreSQL + PostGIS, MyBatis, Redis - **Frontend**: Vue 2.6.12 with Element UI, ECharts - **Real-time**: WebSocket, JTS + GeoTools for spatial calculations ## Configuration ### Database Setup 1. PostgreSQL with PostGIS extension enabled 2. Run initialization scripts in order: - `sql/create_qaup_database.sql` - `sql/create_sys_vehicle_info_table.sql` - `sql/create_sys_driver_info_table.sql` ### Key Configuration Files - `qaup-admin/src/main/resources/application.yml`: Main configuration - `qaup-ui/vue.config.js`: Frontend build configuration - `qaup-collision/src/main/resources/config/`: Spatial configuration (airport_areas.yaml, airport_roads.yaml) ## Important Development Patterns ### Data Access Always use `QuapDataAdapter` for accessing vehicle/driver data in collision module to maintain clean separation between collision detection and system management. ### **CRITICAL: Serena MCP Token Management** **Claude MUST follow these rules to prevent excessive token usage:** #### **Mandatory Parameters** - **Always set max_answer_chars=2000** - **Always set depth=0** - **Always set include_body=false** - **Always specify exact relative_path** (never use ".") #### **Simple Usage Pattern** ```bash # Good - controlled usage mcp__serena__find_symbol(name_path="ClassName", relative_path="path/to/file.java", include_body=false, depth=0, max_answer_chars=2000) # Bad - excessive tokens mcp__serena__find_symbol(depth=1) # Never use depth=1 mcp__serena__search_for_pattern(relative_path=".") # Never search entire project ``` **This reduces token usage from 9930+ characters to under 500 characters per query.** ### Real-time Communication - WebSocket endpoints use `/topic` prefix for broadcasting - PostGIS handles geometric calculations with airport center at (120.0834104, 36.35406879) ### Application URLs - **Admin Interface**: http://localhost:8080 - **API Documentation**: http://localhost:8080/swagger-ui/index.html - **WebSocket Endpoint**: ws://localhost:8080/ws ## Common Issues ### Build Problems - If Maven build fails, ensure Java 17 is active - For dependency conflicts, use `mvn dependency:tree` to analyze ### Runtime Issues - Check Redis connectivity if caching fails - Verify PostGIS extension is properly installed for spatial operations - WebSocket connection issues often relate to CORS configuration in SecurityConfig ### Architecture Issues - If speed/direction appears as 0, check that calculations are in DataProcessingService, not DataCollectorService - If WebSocket messages are too frequent, check that eventPublisher calls are in processing phase only - Ensure complete service separation: DataCollectorService = collection only, DataProcessingService = processing + WebSocket