-
-
Notifications
You must be signed in to change notification settings - Fork 5
Technical: Notifications
This document provides technical details about the ChoreOps notification system architecture for developers and advanced users.
Terminology: This document uses terms like "chore ID", "assignee ID", and "entity ID". For precise definitions of Item vs Entity, Internal ID, and Domain Item terminology, see ARCHITECTURE.md - Lexicon Standards.
Notifications use a smart tagging system to prevent notification spam. When a new notification is sent with the same tag, it replaces the previous notification instead of stacking.
Each notification is tagged with a unique identifier combining the config entry ID, entity type, entity ID, and assignee ID:
Multi-Instance Support: The config entry ID is included as the first identifier to ensure notifications from different ChoreOps integrations don't interfere with each other. Each identifier is truncated to 8 characters to stay within mobile notification tag limits.
| Notification Type | Tag Pattern | Example |
|---|---|---|
| Chore Approval | choreops-status-{entry_id}-{chore_id}-{assignee_id} |
choreops-status-abc12345-def67890-ghi01234 |
| Reward Approval | choreops-rewards-{entry_id}-{reward_id}-{assignee_id} |
choreops-rewards-abc12345-xyz78901-ghi01234 |
| Assignee Due State Family | choreops-status-{entry_id}-{chore_id}-{assignee_id} |
choreops-status-abc12345-def67890-ghi01234 |
| System Alerts | choreops-system-{entry_id}-{assignee_id} |
choreops-system-abc12345-ghi01234 |
The assignee due-state family covers:
- due window
- due reminder
- overdue
Those three states now share one canonical mobile identity per chore and assignee. The transport behavior is intentional:
- Replace: a newer due-state notification is sent on the same canonical tag so it replaces the older one
- Clear: when the due-state prompt is no longer valid, that canonical tag is explicitly cleared
-
Compatibility clear: legacy
due_windowandoverduetags are also cleared to remove stale notifications created by older builds
When Zoë claims multiple chores, each notification remains independent:
- Zoë claims "Make Bed" (chore1) → Tag:
choreops-status-entry123-chore1ab-zoe12345 - Zoë claims "Feed Dog" (chore2) → Tag:
choreops-status-entry123-chore2cd-zoe12345
Result: Approvers see both notifications because each chore has a unique tag.
When approvers press "Remind in 30 min":
- A new notification is scheduled with the same tag as the original chore
- After 30 minutes, the reminder replaces only that specific chore's notification
- Other chore notifications remain untouched
For assignee due timing, this means a reminder replaces the earlier due-window prompt rather than stacking with it.
The integration automatically clears certain notifications from mobile devices to prevent stale action buttons and notification spam.
Approval/Disapproval Clearing (Multi-Approver Support):
- When any approver approves or disapproves a chore/reward (via notification button OR dashboard), the integration sends a
clear_notificationmessage to all approver devices - This removes the original "Chore/Reward Claimed" notification with action buttons from all approvers
- Example: Assignee claims chore → Both approvers notified → Approver 1 approves via notification button → Notification cleared from both approver devices
- Why: Prevents other approvers from seeing stale action buttons for already-processed claims
Claim/Approval Path (Assignee transient due-state notifications):
- When an assignee claims a due-window, reminder, or overdue notification, the assignee transient notification family is cleared from their device
- When a chore is approved, the assignee transient family is cleared and the approver claim workflow notification is cleared from approver devices
Which Notifications Are Auto-Cleared:
- ✅ Chore Claimed - Cleared when any approver approves/disapproves (any path)
- ✅ Reward Claimed - Cleared when any approver approves/disapproves (any path)
- ✅ Chore Due Window (Assignee) - Replaced by reminder or overdue; cleared when invalidated
- ✅ Chore Reminder (Assignee) - Replaced by overdue; cleared when invalidated
- ✅ Chore Overdue (Assignee) - Replaces earlier due-state prompts; cleared when invalidated
- ✅ Chore/Reward Reminder (30 min) - Cleared when any approver approves/disapproves
- ✅ Chore Disapproved - Auto-clears original approver claim notifications
- ❌ All other notifications - Remain until dismissed by user
The notification system now provides comprehensive auto-clearing for assignee notifications:
Chore State Transitions:
- When an assignee claims a chore → The canonical due-state family is cleared from their device
- When an approver approves any chore → The canonical due-state family is cleared from the assignee's device
- When an approver disapproves a chore → Assignee receives disapproval notification, approver claim notifications are cleared
- When a chore is reset or deleted → Invalidated transient prompts are cleared from devices
Why This Matters: Assignees no longer see stale due-window, reminder, or overdue action prompts after the chore state changes. This prevents confusion and duplicate claims.
When an assignee has multiple pending chores waiting for approval, the integration uses smart aggregation to reduce notification clutter for approvers:
How It Works:
- Assignee claims multiple chores → Each claim generates individual notifications to approvers
- Approver approves one chore → Old notification is cleared and replaced with an updated aggregated notification:
- Shows: "[Assignee] has N pending chores. Latest: [Chore Name] (X points)"
- Includes: Action buttons for the most recent pending chore
- Approver continues approving → Notification updates with new count and latest chore details
- Last chore approved → No replacement notification sent (all approvals complete)
Rewards: Do not use aggregation. Each reward approval sends independent notifications and clears the original claim notification.
Why This Matters: Approvers with multiple assignees/chores see consolidated status updates instead of a growing list of individual notifications.
Overdue notification routing is payload-driven to keep manager boundaries clean and avoid duplicate attempts.
Emit contract (ChoreManager):
- Emits one overdue event per assignee target
- Includes
user_idas the single notification target - Includes
overdue_message_typewith values:defaultsteal_available
Consume contract (NotificationManager):
- Sends overdue notifications only to payload
user_id(no rotation fan-out) - Selects assignee overdue message key strictly from
overdue_message_type - Falls back to the default overdue assignee message when the field is missing or unknown
- Keeps approver overdue message/action behavior unchanged
Mode behavior:
- Rotation + allow-steal may emit
steal_availablefor non-turn assignees - Independent / Shared (All) / Shared (First) continue using
default
Notifications are translated per-user using the integration's custom translation architecture:
- 14 languages supported via Crowdin (English, Spanish, Dutch, French, German, Italian, and more)
- Per-user preferences - Users can use different languages
- Automatic fallback to English for missing translations
-
Translation files:
translations_custom/{lang}_notifications.json -
Translation key pattern:
{notification_type}_{audience}(e.g.,chore_approved_kid,badge_earned_parent)- These key suffixes are legacy translation identifiers and remain unchanged.
- Integration determines recipient's language preference
- Loads appropriate translation file (
en_notifications.json,es_notifications.json, etc.) - Formats notification with dynamic placeholders (
{kid_name},{chore_name},{points}, etc.) - Sends translated notification to user's mobile device
Key Features:
- Titles, messages, and action button labels all translated
- Emojis preserved across all languages
- Placeholder replacement happens after translation
For complete translation architecture details (sensor entities, translation constants, Crowdin workflow), see ARCHITECTURE.md - Translation Architecture.
-
Notification Manager:
managers/notification_manager.py- Core notification logic, smart tagging, auto-clearing, aggregation -
Action Handler:
notification_action_handler.py- Processes action button presses from mobile notifications -
Translation Files:
translations_custom/{lang}_notifications.json- Notification text for 14 languages
All notification constants follow the TRANS_KEY_NOTIF_* pattern in const.py:
-
TRANS_KEY_NOTIF_TITLE_*- Translation keys for notification titles -
TRANS_KEY_NOTIF_MESSAGE_*- Translation keys for notification messages -
TRANS_KEY_NOTIF_ACTION_*- Translation keys for action button labels
Example Pattern:
TRANS_KEY_NOTIF_TITLE_CHORE_APPROVED_KID = "chore_approved_kid"
TRANS_KEY_NOTIF_MESSAGE_CHORE_APPROVED_KID = "chore_approved_kid"For complete constant naming conventions and patterns, see DEVELOPMENT_STANDARDS.md - Constant Naming Standards.
Architecture & Design:
-
ARCHITECTURE.md - Complete integration architecture
- Lexicon Standards - Item vs Entity terminology
- Translation Architecture - Translation system design
- Layered Architecture - Manager/Helper/Engine/Util separation
Development Standards:
-
DEVELOPMENT_STANDARDS.md - Coding guidelines and patterns
- Constant Naming Standards - All constant prefix patterns
- Localization Standards - Translation file management
- Data Write Standards - Manager CRUD ownership rules
Last Updated: March 2026 (payload-driven overdue steal routing)
🚀 Getting Started
- Home
- Installation
- Migration from KidsChores
- Quick Start
- Quick Start Scenarios
- Dashboard Generation
- Backup & Restore
⚙️ Configuration
- General Options
- Points
- Users
- Chores
- Rewards
- Badges - Overview
- Badges - Cumulative
- Badges - Periodic
- Achievements
- Challenges
- Notifications
🔧 Services
💡 Tips & Tricks
- Template Cookbook for Chores, Rewards, and Approvals
- Auto-Approve Chores
- Calendar Event Due Dates
- NFC Claim Workflow
- Overdue Penalty Automation
- Critical Overdue Alerts
📖 Advanced Topics
- Dashboard Integration
- Access Control
- Chores - Advanced
- Badge Cumulative - Advanced
- Badge Periodic - Advanced
📚 Technical Reference
- Points
- Users
- Entities & States
- Chores
- Badges
- Configuration Detail
- Dashboard Generation
- Notifications
- Weekly Activity Reports
👩🔧 Troubleshooting