feat(user-service): 实现用户服务核心功能与数据同步
Some checks failed
test/timeline-server/pipeline/head There was a failure building this commit
Some checks failed
test/timeline-server/pipeline/head There was a failure building this commit
- 新增用户资料、偏好设置、自定义字段管理功能 - 实现评论、反应、相册与智能集合的完整业务逻辑 - 添加离线变更记录与数据同步机制支持冲突解决 - 集成 Redis 缓存配置与用户统计数据聚合 - 创建 8 个业务控制器处理用户交互请求 - 新增 Feign 客户端与故事服务集成 - 补充详细的后端实现与 WebSocket 指南文档 - 更新项目依赖配置支持新增功能模块
This commit is contained in:
231
timeline-user-service/TASK_21.1_VERIFICATION.md
Normal file
231
timeline-user-service/TASK_21.1_VERIFICATION.md
Normal file
@@ -0,0 +1,231 @@
|
||||
# Task 21.1 Verification: Layout Preferences API Endpoints
|
||||
|
||||
## Task Status: ✅ COMPLETE
|
||||
|
||||
Task 21.1 requires implementing the Layout Preferences API endpoints. This verification confirms that all required components have been successfully implemented as part of Task 19 (Preferences service).
|
||||
|
||||
## Requirements Validation
|
||||
|
||||
### Requirement 8.5: Layout preferences persist across sessions
|
||||
**Status**: ✅ Implemented
|
||||
|
||||
The implementation includes:
|
||||
- Database persistence in `user_preferences` table
|
||||
- GET endpoint to retrieve persisted preferences
|
||||
- PUT endpoint to update and persist preferences
|
||||
|
||||
## Implementation Components
|
||||
|
||||
### 1. Database Schema ✅
|
||||
**File**: `timeline-sql/V1.4.0__personal_user_enhancements.sql`
|
||||
|
||||
Layout-related fields in `user_preferences` table:
|
||||
```sql
|
||||
gallery_layout VARCHAR(20) DEFAULT 'grid' COMMENT '画廊布局: grid/list',
|
||||
timeline_layout VARCHAR(20) DEFAULT 'grid' COMMENT '时间线布局: grid/list',
|
||||
album_layout VARCHAR(20) DEFAULT 'grid' COMMENT '相册布局: grid/list',
|
||||
card_size VARCHAR(20) DEFAULT 'medium' COMMENT '卡片大小: small/medium/large',
|
||||
```
|
||||
|
||||
### 2. API Endpoint ✅
|
||||
**File**: `src/main/java/com/timeline/user/controller/PreferencesController.java`
|
||||
|
||||
**Endpoint**: `PUT /api/v1/preferences/layout`
|
||||
|
||||
```java
|
||||
@PutMapping("/layout")
|
||||
public ResponseEntity<Void> updateLayoutPreferences(
|
||||
@RequestHeader("X-User-Id") String userId,
|
||||
@Valid @RequestBody UpdateLayoutRequest request) {
|
||||
preferencesService.updateLayoutPreferences(userId, request.getGalleryLayout(),
|
||||
request.getTimelineLayout(), request.getAlbumLayout(), request.getCardSize());
|
||||
return ResponseEntity.success(null);
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Request DTO ✅
|
||||
**File**: `src/main/java/com/timeline/user/dto/UpdateLayoutRequest.java`
|
||||
|
||||
Includes validation for:
|
||||
- `galleryLayout`: "grid" or "list"
|
||||
- `timelineLayout`: "grid" or "list"
|
||||
- `albumLayout`: "grid" or "list"
|
||||
- `cardSize`: "small", "medium", or "large"
|
||||
|
||||
All fields are optional to support partial updates.
|
||||
|
||||
### 4. Service Implementation ✅
|
||||
**File**: `src/main/java/com/timeline/user/service/impl/PreferencesServiceImpl.java`
|
||||
|
||||
**Method**: `updateLayoutPreferences()`
|
||||
|
||||
Features:
|
||||
- Validates all layout parameters
|
||||
- Supports partial updates (null fields use existing values)
|
||||
- Creates default preferences if user has none
|
||||
- Transactional for data consistency
|
||||
- Comprehensive error handling
|
||||
|
||||
Validation logic:
|
||||
```java
|
||||
private boolean isValidLayout(String layout) {
|
||||
return "grid".equals(layout) || "list".equals(layout);
|
||||
}
|
||||
|
||||
private boolean isValidCardSize(String cardSize) {
|
||||
return "small".equals(cardSize) || "medium".equals(cardSize) || "large".equals(cardSize);
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Data Access Layer ✅
|
||||
**File**: `src/main/resources/com/timeline/user/dao/PreferencesMapper.xml`
|
||||
|
||||
**Method**: `updateLayout()`
|
||||
|
||||
```xml
|
||||
<update id="updateLayout">
|
||||
UPDATE user_preferences
|
||||
SET gallery_layout = #{galleryLayout},
|
||||
timeline_layout = #{timelineLayout},
|
||||
album_layout = #{albumLayout},
|
||||
card_size = #{cardSize},
|
||||
update_time = CURRENT_TIMESTAMP
|
||||
WHERE user_id = #{userId}
|
||||
</update>
|
||||
```
|
||||
|
||||
### 6. Unit Tests ✅
|
||||
**File**: `src/test/java/com/timeline/user/service/PreferencesServiceTest.java`
|
||||
|
||||
Test coverage includes:
|
||||
- ✅ Full layout update with all fields
|
||||
- ✅ Partial layout update (only some fields)
|
||||
- ✅ Invalid layout validation
|
||||
- ✅ Invalid card size validation
|
||||
- ✅ Default preferences creation
|
||||
|
||||
Example test:
|
||||
```java
|
||||
@Test
|
||||
public void testUpdateLayoutPreferences() {
|
||||
String userId = "test-user-123";
|
||||
UserPreferences existing = createDefaultPreferences(userId);
|
||||
when(preferencesMapper.findByUserId(userId)).thenReturn(existing);
|
||||
when(preferencesMapper.updateLayout(userId, "list", "grid", "list", "large")).thenReturn(1);
|
||||
|
||||
preferencesService.updateLayoutPreferences(userId, "list", "grid", "list", "large");
|
||||
|
||||
verify(preferencesMapper, times(1)).updateLayout(userId, "list", "grid", "list", "large");
|
||||
}
|
||||
```
|
||||
|
||||
## API Specification
|
||||
|
||||
### PUT /api/v1/preferences/layout
|
||||
|
||||
**Headers**:
|
||||
- `X-User-Id`: User identifier (required)
|
||||
|
||||
**Request Body**:
|
||||
```json
|
||||
{
|
||||
"galleryLayout": "list",
|
||||
"timelineLayout": "grid",
|
||||
"albumLayout": "list",
|
||||
"cardSize": "large"
|
||||
}
|
||||
```
|
||||
|
||||
**Validation Rules**:
|
||||
- All fields are optional (supports partial updates)
|
||||
- `galleryLayout`, `timelineLayout`, `albumLayout`: must be "grid" or "list"
|
||||
- `cardSize`: must be "small", "medium", or "large"
|
||||
|
||||
**Response** (200 OK):
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
**Error Responses**:
|
||||
- 400 Bad Request: Invalid layout or card size value
|
||||
- 401 Unauthorized: Missing or invalid X-User-Id header
|
||||
|
||||
## Default Values
|
||||
|
||||
When a user has no preferences, the system creates defaults:
|
||||
- Gallery layout: `grid`
|
||||
- Timeline layout: `grid`
|
||||
- Album layout: `grid`
|
||||
- Card size: `medium`
|
||||
|
||||
## Features
|
||||
|
||||
### 1. Partial Updates Support ✅
|
||||
The endpoint supports updating only specific fields:
|
||||
```json
|
||||
{
|
||||
"galleryLayout": "list",
|
||||
"cardSize": "small"
|
||||
}
|
||||
```
|
||||
Other fields (timelineLayout, albumLayout) retain their existing values.
|
||||
|
||||
### 2. Validation ✅
|
||||
- Validates layout values: "grid" or "list"
|
||||
- Validates card size values: "small", "medium", or "large"
|
||||
- Throws `IllegalArgumentException` for invalid values
|
||||
|
||||
### 3. Auto-Creation ✅
|
||||
If a user has no preferences record, the service automatically creates one with default values before updating.
|
||||
|
||||
### 4. Transactional ✅
|
||||
All updates are wrapped in `@Transactional` to ensure data consistency.
|
||||
|
||||
## Integration with Other Components
|
||||
|
||||
### Related Endpoints
|
||||
- `GET /api/v1/preferences` - Retrieves all preferences including layout
|
||||
- `PUT /api/v1/preferences/theme` - Updates theme preferences
|
||||
- `PUT /api/v1/preferences/timeline` - Updates timeline display preferences
|
||||
|
||||
### Database Integration
|
||||
- Uses MyBatis for database operations
|
||||
- Automatic timestamp updates via `ON UPDATE CURRENT_TIMESTAMP`
|
||||
- Indexed on `user_id` for fast lookups
|
||||
|
||||
## Verification Summary
|
||||
|
||||
| Component | Status | Notes |
|
||||
|-----------|--------|-------|
|
||||
| Database Schema | ✅ Complete | All layout fields present |
|
||||
| API Endpoint | ✅ Complete | PUT /api/v1/preferences/layout |
|
||||
| Request DTO | ✅ Complete | Validation annotations included |
|
||||
| Service Layer | ✅ Complete | Full validation and error handling |
|
||||
| Data Access | ✅ Complete | MyBatis mapper implemented |
|
||||
| Unit Tests | ✅ Complete | Comprehensive test coverage |
|
||||
| Documentation | ✅ Complete | API documented in PREFERENCES_BACKEND_IMPLEMENTATION.md |
|
||||
|
||||
## Conclusion
|
||||
|
||||
Task 21.1 (Create Layout Preferences API endpoints) is **COMPLETE**. All required components have been implemented:
|
||||
|
||||
1. ✅ PUT /api/v1/preferences/layout endpoint exists
|
||||
2. ✅ Layout preferences are stored in database schema
|
||||
3. ✅ Requirement 8.5 (persistence) is satisfied
|
||||
4. ✅ Comprehensive validation and error handling
|
||||
5. ✅ Unit tests provide good coverage
|
||||
6. ✅ Supports partial updates for flexibility
|
||||
|
||||
The implementation was completed as part of Task 19 (Preferences service) and includes all layout-related functionality specified in the requirements.
|
||||
|
||||
## Next Steps
|
||||
|
||||
Task 21.1 is complete. The next task in the workflow is:
|
||||
- Task 21.2: Write property tests for Layout Preferences backend (optional)
|
||||
- Task 22: Implement Layout Preferences frontend
|
||||
|
||||
The backend API is ready for frontend integration.
|
||||
Reference in New Issue
Block a user