docs(06): create Phase 6 email notifications plans

Phase 6: Email Notifications
- 3 plans created
- 6 total tasks defined
- Parallel execution: 06-01 and 06-02 in Wave 1, 06-03 in Wave 2
- Ready for execution

Plans:
- 06-01: Mentor notification opt-in (2 tasks)
- 06-02: Action Scheduler integration (2 tasks)
- 06-03: Async batch email processing (2 tasks)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-14 20:59:56 +09:00
parent 464e3d9a41
commit fd88dcf025
3 changed files with 362 additions and 0 deletions

View File

@@ -0,0 +1,128 @@
---
phase: 06-email-notifications
plan: 03
type: execute
depends_on: ["06-01", "06-02"]
files_modified: [includes/class-notifications.php, includes/class-scheduler.php]
---
<objective>
Send async batch email notifications to opted-in mentors when jobs are published, preventing timeouts with background processing.
Purpose: Notify mentors about new job opportunities in real-time without blocking the admin's publish action, respecting user opt-in preferences and email provider limits.
Output: Automated email notifications to opted-in mentors on job publish, processed asynchronously in batches.
</objective>
<execution_context>
~/.claude/get-shit-done/workflows/execute-plan.md
./summary.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
# Prior work this plan builds on:
@.planning/phases/03-job-management-core/03-03-SUMMARY.md
@.planning/phases/04-job-deactivation-system/04-02-SUMMARY.md
@.planning/phases/05-mentor-job-board/05-02-SUMMARY.md
@.planning/phases/06-email-notifications/06-01-SUMMARY.md
@.planning/phases/06-email-notifications/06-02-SUMMARY.md
# Source files:
@includes/class-notifications.php
@includes/class-scheduler.php
@includes/class-user-preferences.php
**Tech stack available:** Action Scheduler (from 06-02), wp_mail, get_user_meta, WP_User_Query, get_field (ACF), transition_post_status hook
**Established patterns:**
- German email templates with error logging (Phase 03-03, 04-02, 05-02)
- transition_post_status hook for detecting status changes (Phase 03-03, 04-02)
- Notification class with static methods (Phase 03-03)
- Action Scheduler batch processing (Phase 06-02)
**Constraining decisions:**
- Phase 06-01: User meta 'ddhh_jm_notify_new_jobs' indicates opt-in status
- Phase 06-01: get_opted_in_mentors() returns array of opted-in user IDs
- Phase 06-02: schedule_mentor_notification_batch() handles batch scheduling
- Phase 06-02: Callback hook 'ddhh_jm_send_mentor_notification_batch' needs implementation
- Phase 03-03: Email templates in German, use error_log for failures
- Phase 03-03: Only trigger on specific transitions (avoid spam on every save)
- PROJECT.md line 27: "Mentor opt-in notification system for new published jobs"
</context>
<tasks>
<task type="auto">
<name>Task 1: Add job publish hook to schedule mentor notifications</name>
<files>includes/class-notifications.php</files>
<action>Add method notify_mentors_on_job_publish() to DDHH_JM_Notifications class. Hook to transition_post_status at priority 10 following established pattern. Method parameters: $new_status, $old_status, $post. Check: (1) post_type is 'job_offer', (2) new_status is 'publish', (3) old_status is NOT 'publish' (only notify on initial publish, not updates). If checks pass, get opted-in mentors via DDHH_JM_User_Preferences::get_opted_in_mentors(). If empty array, log "No opted-in mentors to notify" and return (no error - valid scenario). If mentors found, call DDHH_JM_Scheduler::schedule_mentor_notification_batch() with mentor IDs and $post->ID. Log success with count: "Scheduled X notification batches for job ID Y". Register hook in setup_hooks() method: add_action('transition_post_status', array(__CLASS__, 'notify_mentors_on_job_publish'), 10, 3). This triggers async batch processing without blocking the publish action.</action>
<verify>Check includes/class-notifications.php contains notify_mentors_on_job_publish() method. Verify transition_post_status hook registered in setup_hooks(). Confirm method only triggers on pending/draft→publish transitions. Verify calls to user preferences and scheduler classes.</verify>
<done>Job publish hook implemented, triggers only on initial publish, queries opted-in mentors, schedules async batches via scheduler, hook registered in notifications class</done>
</task>
<task type="auto">
<name>Task 2: Implement async batch email processor callback</name>
<files>includes/class-scheduler.php</files>
<action>Add method process_mentor_notification_batch() to DDHH_JM_Scheduler class. Method parameters: $user_ids (array), $job_id (int). For each user ID in batch: (1) Get user data with get_userdata($user_id), skip if null (user deleted). (2) Get user email. (3) Get job details: post_title, get_field('job_location'), get_field('job_type'), permalink (for "View Job" link). (4) Prepare German email subject: "Neues Stellenangebot: {job_title}". (5) Prepare German email body: "Hallo,\n\nein neues Stellenangebot wurde veröffentlicht:\n\nStelle: {job_title}\nStandort: {job_location}\nArt: {job_type}\n\nSie können das Angebot hier ansehen:\n{permalink}\n\nUm keine weiteren Benachrichtigungen zu erhalten, können Sie diese in Ihrem Profil deaktivieren.\n\nDiese E-Mail wurde automatisch gesendet." (6) Send email with wp_mail($email, $subject, $body). (7) If wp_mail fails, log error: "Failed to send mentor notification to user {$user_id} for job {$job_id}". (8) Add small delay (usleep(100000) = 0.1 seconds) between emails to avoid rate limits. After loop, log success: "Processed notification batch: {count} emails sent for job {$job_id}". Register callback in setup_hooks(): add_action('ddhh_jm_send_mentor_notification_batch', array(__CLASS__, 'process_mentor_notification_batch'), 10, 2). This executes asynchronously when Action Scheduler processes the queue.</action>
<verify>Check includes/class-scheduler.php contains process_mentor_notification_batch() method. Verify callback registered in setup_hooks() for hook 'ddhh_jm_send_mentor_notification_batch'. Confirm German email template with job details and permalink. Verify error logging for failed sends. Confirm rate limit delay between emails.</verify>
<done>Batch processor callback implemented, sends German emails with job details, includes unsubscribe hint, logs errors, has rate limit delay, callback registered for Action Scheduler hook</done>
</task>
</tasks>
<verification>
Before declaring plan complete:
- [ ] Job publish hook triggers only on initial publish (not updates)
- [ ] Opted-in mentors queried via user preferences class
- [ ] Batch scheduling called via scheduler class
- [ ] Async callback registered for Action Scheduler hook
- [ ] Email template in German with job details
- [ ] Error logging for failures
- [ ] Rate limit delay between emails
- [ ] Unsubscribe hint included in emails
</verification>
<success_criteria>
- Job publish triggers async mentor notifications
- Only opted-in mentors receive emails
- Emails processed in background (no blocking)
- Batches of 50 users prevent timeouts
- German email template with job details and link
- Error logging for debugging
- Rate limit compliance (0.1s delay between sends)
- Users informed how to opt-out in email
- Phase 6 complete - async notification system fully functional
</success_criteria>
<output>
After completion, create `.planning/phases/06-email-notifications/06-03-SUMMARY.md`:
# Phase 6 Plan 3: Async Mentor Notifications Summary
**[Substantive one-liner - what shipped, not "phase complete"]**
## Accomplishments
- [Key outcome 1]
- [Key outcome 2]
## Files Created/Modified
- `includes/class-notifications.php` - Description
- `includes/class-scheduler.php` - Description
## Decisions Made
[Key decisions and rationale, or "None"]
## Issues Encountered
[Problems and resolutions, or "None"]
## Next Step
Phase 6 complete. Ready for Phase 7: Testing & Polish (end-to-end testing, UI refinement, deployment preparation).
</output>