178 lines
7.5 KiB
Markdown
178 lines
7.5 KiB
Markdown
# 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 <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
|
|
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 |