feat(rewards): per-user assignment with runtime entity sync — no reload#162
Merged
Conversation
Add DATA_REWARD_ASSIGNED_USER_IDS field to RewardData TypedDict.
Use SENTINEL_ALL_USERS ("*") as an input-only shortcut — resolved to
explicit gamified user UUIDs at service/flow boundaries, never
persisted. Boot normalization converts any legacy sentinel or missing
fields to explicit UUIDs. Empty lists ("no users") pass through
unchanged and are intentionally supported for blank-to-clear.
Entity gating:
- AssigneeRewardStatusSensor, AssigneeRewardRedeemButton,
ApproverRewardApproveButton, and ApproverRewardDisapproveButton
are only created for users assigned to the reward
- Orphaned entities are cleaned via
remove_orphaned_assignee_reward_entities()
- Dashboard helper rewards list filters by assignment
- Reward status sensor exposes assigned_user_names attribute
from stored UUIDs (no sentinel expansion needed)
Service layer:
- create_reward and update_reward accept assigned_user_names
(display names resolved to UUIDs, "*" expands to all gamified)
and assigned_user_ids (sentinel resolved same as names)
- Services bypass assignment gating by design — administrators
can redeem/approve rewards for unassigned users via automation
- update_reward() triggers orphan entity cleanup on assignment
changes; empty list removes all assigned users
- Options flow add/edit reward steps include multi-select for
assigned users, pre-populated with all gamified users on create
Build/release:
- services.yaml and en.json document assigned_user_names field
with blank-to-clear pattern and sentinel expansion
- Wiki updated: Configuration:-Rewards, Services:-Reference
- 13 new tests; 72 total pass with zero regressions
Closes #77
Reward create and assignment updates no longer trigger a full integration reload. Instead, a targeted runtime entity sync handles sensor and button creation without disrupting the active dashboard. - create_reward_entities() upgraded from test-only to production, with assignee_ids parameter for targeted creation - create_reward_button_entities() added to button.py for runtime creation of reward redeem, approve, and disapprove buttons - async_sync_reward_entities() added to coordinator.py for one-step entity sync orchestration (create + cleanup) - Services (create_reward, update_reward) and options flow (add/edit reward) use runtime sync instead of reload - reward_manager.update_reward() no longer spawns async orphan cleanup; caller sync handles entity lifecycle - 2 new "no reload" regression tests; 74 total pass
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two major feature improvements to rewards: per-user assignment with entity gating, and runtime entity sync that eliminates full integration reloads during reward configuration.
1. Per-User Reward Assignment
Rewards now support per-user assignment via the
assigned_user_idsfield, matching the same pattern used by chores, badges, achievements, and challenges.create_rewardandupdate_rewardacceptassigned_user_names(display names resolved to UUIDs) — use["*"]for all users, pass an empty list to remove all assigned usersAssigneeRewardStatusSensorand reward buttons (redeem, approve, disapprove) are only created for assigned usersassigned_user_namesattribute showing current assignmentredeem_reward,approve_reward, anddisapprove_rewardwork regardless of assignment — administrators can create "hidden" rewards applied via automation only2. Runtime Entity Sync (No Reload)
Reward create and assignment updates no longer trigger a full integration reload. Targeted runtime entity sync handles sensor and button creation/removal without disrupting the active dashboard.
assignee_idsparameter for targeted creationcreate_reward,update_reward) and options flow (add/edit reward) use runtime sync instead of reloadValidation
Closes #77
Relates to #126