Goal: Convert Map input parameters and Entity @RequestBody parameters to proper DTOs with Bean Validation, eliminating unsafe type casting and enabling automatic validation.
Architecture: Create dedicated DTOs for each Map/Entity endpoint, add @Valid to Controller methods, then simplify the Controller logic. Focus on input Maps (not response Maps) and Entity @RequestBody (overposting risk). Skip pagination-only Maps (low value, high churn).
Tech Stack: Spring Boot 2.7.18, javax.validation, MyBatis-Plus, Java 8
Scope Decision
DO convert: Map params that carry business input (create/update/action endpoints), Entity @RequestBody (overposting vulnerability)
SKIP: Pagination-only Maps (page/size/filter — many identical patterns, low validation value), Response-only Maps (return type, not input), Payment callback Maps (external systems, fragile to change)
Prioritized Task Groups
Group A: Core Business Input Maps (highest validation value)
- AssessmentOrderController: createOrder, getOrderDetail, payOrder
- AssessmentAppointmentController: createAppointment
- PointsController: adjustPoints
- WishController: setPrice, approveExchange, rejectWish, cancelWish
- RewardController: exchangeReward, approveReward, getWishlist, getExchangeHistory
- TaskController: completeMinigameTask, getTodayTasks, getTaskHistory
Group B: User/Role/Family Input Maps
- FamilyUserController: joinFamily, createFamily, switchMode, switchRole, switchToChild
- FamilyController: updateFamilyName
- UserController: updateUser
- BindInviteController: validateToken
- ParentController: createParentWishlist, exchangeParentWishlist
Group C: Guide/Teacher Input Maps
- GuideFamilyTaskController: createTaskForChild, batchReviewTasks
- TeacherMessageController: sendMessage, replyMessage
- GuideAssessmentController: enableFamilyAssessment
- GuidePackageController: getPackageDetail, updatePackage, updateStatus, deletePackage, getTemplateDetail, incrementSales
- GuideManagementController: addGuidePackage, updateGuidePackage
- GuideOrderController: confirmOrder
Group D: Other Input Maps
- MiniGameController: completeGame
- MediaController: uploadText, attachMedia
- TaskTemplatePackageController: publishPackage
- MarketController: getPublicPackages
- GrowthRecordController: syncExternalResult
- PackagePaymentController: getOrderStatus, getWechatPayParams, applyAfterPayment
Group E: Admin Input Maps + Entity Params
- AdminController: createUser, resetUserPassword, adjustPoints, approveReward + Entity params (updateUser User, updateChild Child, createRewardTemplate Reward, updateRewardTemplate Reward, updateFamily Family, createTaskTemplate TaskTemplate, updateTaskTemplate TaskTemplate)
- AdminAuthController: sendCode, resetPassword, verifyCode
- AdminGuideController: Entity params (createPackage GuidePackage, updatePackage GuidePackage)
- ServiceContentController: list, getById, update, delete
- AssessmentAdminController: createMaterial, updateMaterial, updatePointsConfig
- OperationLogController: list, getLogDetail
Group F: Pagination-only Maps (SKIP - use shared PageQueryDTO if needed later)
- AdminController: getUsers, getChildren, getTasks, getRewards, getPointsLogs, getFamilies, getTaskTemplates, getGuideApplications, getTeacherFamilyTasks, getTeacherFamilyRewards
- PointsController: getBalance, getPointsLogs
- TaskReminderController: all 4 methods
- StreetController: search, getStatistics
- GuideOrderController: getOrders
- MembershipController: canUseFeature
- GuideFamilyTaskController: getFamilyTasks (pagination)
- TeacherMessageController: getMessages
Group G: Payment/Callback Maps (SKIP - external systems)
- PaymentController: all 4 methods
- PackagePaymentController: (already in Group D for non-payment)
- MembershipController: createOrder, paymentNotify
- AdminAuthController: login, loginByPassword (response Map, input is AdminLoginDTO already @Valid)
Implementation Approach
For each DTO:
- Create DTO class in
com.etotem.cfc.dtowith @Data + @NotNull/@NotBlank/@Size annotations- Add @Valid + new DTO type to Controller method signature
- Replace Map field extraction with DTO getter calls
- Remove redundant null checks now covered by @Valid
- Compile verify after each group
DTO Naming Convention
{Entity}{Action}DTOfor action DTOs (e.g.,AssessmentCreateOrderDTO)- Simple names for common patterns (e.g.,
AdjustPointsDTO)