7.5 KiB
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
-
DataCollectorService Methods:
collectAircraftData(),collectVehicleData(),collectUnmannedVehicleData()- position data collectioncollectFlightNotificationData()- flight notification data collection- Store MovingObjects with NULL speed/direction in activeMovingObjectsCache
- Cache FlightNotifications in flightNotificationCache
- FORBIDDEN: No calculations, no WebSocket events, no processing
-
DataProcessingService Methods:
performPeriodicDataProcessing()- main processing loopcalculateSpeedAndDirectionForAllObjects()- calculate derived datasendPositionUpdatesForActiveObjects()- WebSocket position messagingprocessFlightNotificationUpdates()- WebSocket flight notification messagingperformViolationDetection()- rule engine integrationsaveUnmannedVehicleDataPeriodically()- 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
# 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
# Check port usage
lsof -ti:8080
# Kill process if needed
kill -9 <process-id>
# 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
- PostgreSQL with PostGIS extension enabled
- Run initialization scripts in order:
sql/create_qaup_database.sqlsql/create_sys_vehicle_info_table.sqlsql/create_sys_driver_info_table.sql
Key Configuration Files
qaup-admin/src/main/resources/application.yml: Main configurationqaup-ui/vue.config.js: Frontend build configurationqaup-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
# 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
/topicprefix 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:treeto 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