fix(10): revise plans based on checker feedback

- Plan 10-02: Added explicit UserMailService wiring in Account.scala
  onRegister handler for activation emails when activateMode == User
- Plan 10-04: Split into backend-only (models, services, admin controller)
  reducing from 16 to 15 files, estimated context ~50%
- Plan 10-05: New plan for frontend components (Posts, Post, Categories,
  RelatedPosts), Wave 3 depends on 10-04
- Updated ROADMAP.md to reflect 5 plans for Phase 10
This commit is contained in:
Jakub Zych
2026-02-05 16:13:31 +01:00
parent 4d8d5719d5
commit b05e85cd55
4 changed files with 338 additions and 186 deletions

View File

@@ -6,6 +6,7 @@ wave: 2
depends_on: ["10-01"]
files_modified:
- plugins/golem15/user/components/ResetPassword.scala
- plugins/golem15/user/components/Account.scala
- plugins/golem15/user/services/FrontendUserService.scala
- plugins/golem15/user/services/UserMailService.scala
- plugins/golem15/user/resources/views/account/profile.peb
@@ -155,6 +156,7 @@ Output: Working profile and reset features:
<name>Task 2: Password reset flow and email service</name>
<files>
plugins/golem15/user/components/ResetPassword.scala
plugins/golem15/user/components/Account.scala (modify)
plugins/golem15/user/services/UserMailService.scala
plugins/golem15/user/services/FrontendUserService.scala (modify)
plugins/golem15/user/resources/views/resetpassword/request.peb
@@ -175,6 +177,13 @@ Output: Working profile and reset features:
- Send via configured SMTP or email service
- MailError ADT: SendFailed, TemplateError, ConfigurationError
**Account.scala modification (CRITICAL - wire activation email):**
- Modify the onRegister handler created in Plan 01 to integrate UserMailService:
- Inject UserMailService dependency into Account component
- After successful userService.register call, check UserSettings.activateMode
- If activateMode == ActivateMode.User, call mailService.sendActivationEmail(user, activationCode)
- This completes the key_link from Account.scala to UserMailService
**FrontendUserService.scala additions:**
- requestPasswordReset(email: String): Unit
- Find user by email (don't reveal if not found - timing attack)
@@ -230,13 +239,14 @@ Output: Working profile and reset features:
<verify>
./mill summercms.compile succeeds
ResetPassword component registered in Plugin.scala
Account.scala onRegister calls mailService.sendActivationEmail when activateMode == User
Email templates have valid Pebble syntax
Reset code generation uses SecureRandom
</verify>
<done>
Password reset request sends email (or stubs if no SMTP).
Reset link with token allows setting new password.
Activation email template ready for registration flow.
Activation email sent during registration when activateMode is User.
No email enumeration possible (generic success messages).
</done>
</task>
@@ -247,9 +257,10 @@ Output: Working profile and reset features:
After all tasks complete:
1. User plugin compiles: `./mill summercms.compile`
2. Account component has all handlers: onSignin, onRegister, onActivate, onUpdate, onUploadAvatar
3. ResetPassword component handles: onRequest, onReset
4. Email service can send activation and reset emails
5. Templates render valid forms with HTMX
3. Account.scala onRegister integrates UserMailService for activation emails
4. ResetPassword component handles: onRequest, onReset
5. Email service can send activation and reset emails
6. Templates render valid forms with HTMX
</verification>
<success_criteria>
@@ -257,6 +268,7 @@ After all tasks complete:
- Profile update saves name/surname changes
- Password change requires current password confirmation
- Avatar upload stores image and updates user record
- Registration with activateMode=User triggers activation email via UserMailService
- Password reset request always shows success (no enumeration)
- Reset link with valid code allows new password entry
- User automatically logged in after successful reset