Files
Digital-Dabei-Hamburg-Job-M…/.planning/quick/002-fix-duplicate-mentor-notifications-on-jo/002-SUMMARY.md
Viktor Miller 1b4449ae12 docs(quick-002): complete duplicate notification fix task
Tasks completed: 1/1
- Add post meta guard to prevent duplicate mentor notifications

SUMMARY: .planning/quick/002-fix-duplicate-mentor-notifications-on-jo/002-SUMMARY.md
2026-01-29 14:29:28 +09:00

164 lines
5.7 KiB
Markdown

---
phase: quick-002
plan: 01
subsystem: notifications
tags: [mentor-notifications, duplicate-prevention, post-meta, bug-fix]
requires: [05-01, 05-03]
provides:
- Duplicate notification prevention using post meta
- One-time mentor notification guarantee per job
affects: []
tech-stack:
added: []
patterns:
- "Post meta flags for one-time event tracking"
- "Idempotent notification scheduling"
key-files:
created: []
modified:
- includes/class-notifications.php
decisions:
- key: "Use post meta `_ddhh_mentors_notified` for duplicate prevention"
context: "Need to track whether mentors have been notified for a specific job"
options: ["Post meta flag", "Custom database table", "Transient cache"]
chosen: "Post meta flag"
rationale: "Simple, reliable, persists forever, underscore-prefix hides from UI"
- key: "Set meta flag after scheduling, not after emails sent"
context: "When to mark job as notified"
options: ["After scheduling batch", "After all emails sent", "Before scheduling"]
chosen: "After scheduling batch"
rationale: "Scheduling is synchronous and reliable; email sending is async and could fail individually"
metrics:
duration: 2
completed: 2026-01-29
---
# Quick Task 002: Fix Duplicate Mentor Notifications
**One-liner:** Post meta guard prevents mentor re-notification on job republish after edits
## What Was Built
Fixed a bug where mentors received duplicate "new job" notifications when a job was edited and republished.
**The Problem:**
The job lifecycle includes a status reset to `pending` after provider edits (decision 03-02). This means:
1. Provider submits → pending
2. Admin publishes → pending to publish → mentors notified ✓
3. Provider edits → status reset to pending
4. Admin republishes → pending to publish → mentors notified AGAIN ✗
The existing guard `if ( 'publish' === $old_status )` only prevented publish→publish transitions, not pending→publish after edits.
**The Solution:**
Added a post meta flag `_ddhh_mentors_notified` that:
- Is checked before scheduling notifications (early return if already set)
- Is set after successful batch scheduling
- Persists for the lifetime of the job post
- Uses underscore prefix to hide from WordPress custom fields UI
## Technical Implementation
**Modified:** `includes/class-notifications.php`
1. **Pre-scheduling guard** (after line 439):
- `get_post_meta( $post->ID, '_ddhh_mentors_notified', true )`
- If value is `'1'`, log skip message and return early
- Prevents duplicate scheduling entirely
2. **Post-scheduling flag** (after line 469):
- `update_post_meta( $post->ID, '_ddhh_mentors_notified', '1' )`
- Sets flag after `schedule_mentor_notification_batch()` succeeds
- Ensures future republish attempts skip notification
**Why after scheduling, not after sending?**
- Scheduling is synchronous and happens immediately
- Email sending is async (Action Scheduler batches)
- Individual emails might fail, but we still don't want re-notifications
- The intent to notify has been recorded, which is what matters
## Verification
**Syntax Check:**
```bash
php -l includes/class-notifications.php
# No syntax errors detected
```
**Code Review:**
-`get_post_meta` check exists before mentor query
-`update_post_meta` exists after scheduling
- ✅ No other notification methods modified
- ✅ Existing publish→publish guard preserved
- ✅ Underscore-prefixed meta key (hidden from UI)
## Job Lifecycle Flow (After Fix)
1. **Initial submission** (pending):
- No notification (job not published yet)
- `_ddhh_mentors_notified` = not set
2. **First publish** (pending → publish):
- ✅ Mentors notified
- `_ddhh_mentors_notified` = '1'
3. **Provider edits** (publish → pending):
- No notification (deactivation)
- `_ddhh_mentors_notified` = still '1'
4. **Republish after edit** (pending → publish):
- ❌ Mentors NOT notified (meta flag prevents it)
- `_ddhh_mentors_notified` = still '1'
5. **Any future republish**:
- ❌ Mentors NOT notified (meta flag persists)
## Impact
**Fixed:**
- Mentors no longer receive duplicate notifications for the same job
- Reduces notification fatigue and confusion
- Maintains trust in the notification system
**Unchanged:**
- Admin notifications for edits (still sent, as intended)
- First-time publish notifications (still sent)
- Publish→publish guard (still prevents updates to published jobs)
- Mentor opt-in/opt-out functionality
**Edge Cases Handled:**
- Job edited multiple times: Only first publish notifies
- Job unpublished and republished: Only first publish notifies
- Job trashed and restored: Meta persists, no re-notification
## Deviations from Plan
None - plan executed exactly as written.
## Testing Notes
**To verify in production:**
1. Create test job, submit as provider → status: pending
2. Admin publishes → Check Action Scheduler for mentor notification batches
3. Provider edits job → status: pending
4. Admin republishes → Check Action Scheduler - should see NO new batches
5. Check error_log for: "Skipping mentor notification for job #X - mentors already notified on initial publish"
**Manual database check:**
```sql
SELECT post_id, meta_value
FROM wp_postmeta
WHERE meta_key = '_ddhh_mentors_notified';
```
Should show '1' for all published jobs that have triggered notifications.
## Next Phase Readiness
**Blockers:** None
**Dependencies satisfied:** Builds on existing notification system (05-01, 05-03)
**Follow-up needed:** None - fix is complete and self-contained
This was a targeted bug fix with no architectural implications. The notification system is now fully idempotent - each job triggers exactly one mentor notification batch in its lifetime.