# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview Work Log Service Platform (工作日志服务平台) - A lightweight, multi-terminal work log management system with PC admin console and mobile H5 interface. **Current Version**: V1.1 (2026-02-26) **Architecture**: Monolithic application with frontend-backend separation - **Backend**: worklog-api (Spring Boot 3.2.2 + MyBatis-Plus 3.5.5) - **Management Console**: worklog-web (Vue 3 + Element Plus) - **Mobile**: worklog-mobile (Vue 3 + Vant 4) ## Development Environment ### Prerequisites - **JDK**: 21 (LTS) - **Maven**: 3.6+ - **Node.js**: 18+ (for frontend) - **MySQL**: 8.0 - **Redis**: 7.x ### Environment Configuration - **Database**: localhost:3306/worklog (user: worklog, password: Wlog@123) - **Redis**: localhost:6379 (password: zjf@123456) - **Backend Port**: 8080 - **Frontend Dev Servers**: worklog-web (5173), worklog-mobile (5174) ## Common Development Commands ### Backend (worklog-api/) ```bash # Compile mvn clean compile # Run tests (35/36 pass, 1 skipped due to MyBatis Plus mock limitation) mvn test # Run single test mvn test -Dtest=LogServiceTest # Run single test method mvn test -Dtest=LogServiceTest#createLog_success_defaultType # Package mvn clean package # Run application mvn spring-boot:run # Or run packaged JAR java -jar target/worklog-api-1.0.0.jar ``` **Key URLs**: - Health check: http://localhost:8080/api/v1/health - API documentation: http://localhost:8080/swagger-ui.html ### Frontend (worklog-web/ and worklog-mobile/) ```bash # Install dependencies npm install # Development server npm run dev # Build for production npm run build # Type check npm run type-check # Lint npm run lint ``` ### Database Setup ```bash # From project root cd /home/along/MyCode/wanjiabuluo/worklog # Initialize database (creates worklog database and tables) mysql -u worklog -p < sql/init_database.sql # Password: Wlog@123 # Apply V1.1 migration (adds log_type field) mysql -u worklog -p worklog < sql/v1.1_add_log_type.sql ``` ## Architecture Overview ### Backend Layered Architecture **Critical**: Follow the strict layering pattern: ``` Controller → Service → DataService → Mapper → Database ``` **Layer Responsibilities**: 1. **Controller**: Request handling, parameter validation, calls Service 2. **Service**: Business logic, transaction control, DTO/VO conversion 3. **DataService**: Data access encapsulation, CRUD operations 4. **Mapper**: MyBatis database operations **Important Conventions**: - **Never inject Mapper directly into Service** - always use DataService as intermediary - **DataService naming**: `XxxDataService` / `XxxDataServiceImpl` (not `XxxService`) - **All MyBatis-Plus files go in `data/` directory**: entity/, mapper/, service/ - **Primary Keys**: VARCHAR(20) storing 19-digit snowflake IDs - **Audit Fields**: All entities have created_by, created_time, updated_by, updated_time, deleted - **Logical Deletion**: Use `deleted` field (0=active, 1=deleted), never physical delete ### Directory Structure Principle ``` worklog-api/src/main/java/com/wjbl/worklog/ ├── controller/ # REST API endpoints ├── service/ # Business logic layer │ └── impl/ ├── data/ # Data access layer (MyBatis-Plus) │ ├── entity/ # Database entities │ ├── mapper/ # MyBatis Mapper interfaces │ └── service/ # DataService layer │ └── impl/ ├── dto/ # Data Transfer Objects (API input) ├── vo/ # View Objects (API output) ├── enums/ # Enumerations └── common/ # Common utilities ├── Result.java # Unified API response wrapper ├── context/ # UserContext for current user info └── exception/ # Exception handling ``` ### API Design Standards **RESTful URL Pattern**: `/api/v1/{resource}/{action}` **Unified Response Format**: ```json { "code": 200, "message": "success", "data": {}, "success": true } ``` **Authentication**: - Token in header: `Authorization: Bearer {token}` - Token stored in Redis: `auth:token:{token}` (TTL: 24h) - UserContext provides current user: `UserContext.getUserId()`, `UserContext.getRole()` ### Frontend Architecture **State Management**: - Pinia stores for user/auth state - No Vuex **API Management**: - All API calls in `src/api/` directory - Never hardcode URLs in components - Use axios request wrapper with token injection **UI Frameworks**: - **worklog-web**: Element Plus (desktop admin console) - **worklog-mobile**: Vant 4 (mobile H5) ## Key Business Logic ### Log Type System (V1.1) **4 Log Types**: 1. `1` - Work Plan (工作计划) 2. `2` - Work Log (工作日志) - **DEFAULT** 3. `3` - Personal Log (个人日志) 4. `9` - Other (其他) **Uniqueness Constraint**: - Work Plan and Work Log: **ONE per user per day** - Personal Log and Other: **UNLIMITED** per day **Implementation**: - `LogTypeEnum.requiresUnique()` determines if uniqueness check needed - `workLogDataService.getByUserIdLogDateAndType()` checks existing logs - Composite index: `idx_user_date_type (user_id, log_date, log_type)` ### Calendar Interaction Pattern **Breaking API Change in V1.1**: - **Old**: `GET /api/v1/log/by-date` returned single `LogVO` - **New**: `GET /api/v1/log/by-date` returns `List` (sorted by log type) **Frontend Patterns**: - **Management Console**: Dual-dialog pattern (list dialog → detail dialog with back button) - **Mobile**: Multi-mode pattern (list mode ↔ detail mode ↔ create mode in single popup) ### Permission System **2 Roles**: - `USER`: View/edit own logs and profile - `ADMIN`: All permissions + user management + template management + view all logs **Permission Checks**: ```java // In Service layer String currentUserId = UserContext.getUserId(); String currentRole = UserContext.getRole(); if (!workLog.getUserId().equals(currentUserId) && !"ADMIN".equals(currentRole)) { throw new BusinessException("无权操作他人日志"); } ``` ## Testing Guidelines ### Backend Unit Tests **Location**: `worklog-api/src/test/java/` **Key Patterns**: ```java @ExtendWith(MockitoExtension.class) class ServiceTest { @Mock private XxxDataService dataService; @InjectMocks private XxxServiceImpl service; @BeforeEach void setUp() { // Use lenient() for flexible mocking to avoid UnnecessaryStubbing errors lenient().when(dataService.method()).thenReturn(value); // Set UserContext for permission tests UserContext.setUserInfo(new UserInfo("user-id", "username", "name", "USER")); } } ``` **Known Limitation**: - 1 test disabled in `LogServiceTest.deleteLog_success` due to MyBatis Plus Lambda cache not working in mock environment - Permission logic validated in other tests ### Frontend Testing Currently no automated frontend tests. Manual testing via browser. ## Logging and Tracing **Log Files** (in `logs/` directory): - `app.log` - Main application log - `sql.log` - SQL execution log (mandatory separate file) **Log Format** (includes trace IDs): ``` %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId:-}][%X{spanId:-}] %-5level %logger{50} - %msg%n ``` **TraceId/SpanId**: - Automatically added by `TraceInterceptor` - Propagated via HTTP headers: `X-Trace-Id`, `X-Span-Id` ## Configuration Management **Development**: - Configuration in `src/main/resources/application.yml` - Use `application-dev.yml` for dev-specific overrides **Production** (follows architecture design standard): - `conf/env.properties` - Unified environment config (DB, Redis, Nacos) - `conf/service.properties` - Service-specific config - Loaded by `bin/start.sh` script **Security**: - Never commit actual config files with credentials - Use `.example` templates in repository - All passwords encrypted with BCrypt (strength 10) ## Database Conventions **Naming**: - Tables: snake_case (e.g., `work_log`, `sys_user`) - Fields: snake_case (e.g., `log_date`, `user_id`) - Java entities: camelCase with MyBatis-Plus mapping **Standard Audit Fields**: ```sql created_by VARCHAR(20) NOT NULL, created_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_by VARCHAR(20) NOT NULL, updated_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, deleted TINYINT(1) NOT NULL DEFAULT 0 ``` **Indexes**: - Always index foreign keys - Add composite indexes for common query patterns - Example: `idx_user_date_type (user_id, log_date, log_type)` for uniqueness checks ## Common Pitfalls 1. **Don't inject Mapper into Service** - Always use DataService layer 2. **Don't skip UserContext.setUserInfo() in tests** - Required for permission checks 3. **Don't use `when()` for unused stubs** - Use `lenient().when()` to avoid strict stubbing errors 4. **Don't use List.of() in tests** - It returns immutable list; use `ArrayList` instead 5. **Don't modify log_type and log_date in updates** - These fields are immutable after creation 6. **Remember breaking API change** - `/by-date` endpoint returns List, not single object 7. **Don't forget default values** - `logType` defaults to 2 (Work Log) if not specified 8. **Check requiresUnique()** - Work Plan/Work Log need uniqueness validation; Personal/Other don't ## Documentation **Key Documents** (in `doc/` directory): - `产品需求文档PRD.md` - Product requirements (V1.1) - `架构设计文档.md` - Architecture design - `后端模块详细设计文档.md` - Backend detailed design - `前端详细设计文档.md` - Frontend detailed design - `CHANGELOG.md` - Version history and changes **Database**: - `sql/init_database.sql` - Database initialization - `sql/v1.1_add_log_type.sql` - V1.1 migration script ## Default Accounts **Admin**: - Username: `admin` - Password: `admin123` (BCrypt hashed in database) - ID: `1000000000000000001` ## Version Information **V1.1** (2026-02-26): - Added log type classification (4 types) - Unique constraint for work plan/log types - Calendar list view with multiple logs per day - API breaking change: `/by-date` returns array - 15 new unit tests (97.2% pass rate: 35/36) **V1.0** (Initial): - Basic work log management - User management - Template management - PC and mobile support