Skip to content

feat(calendar): assign events to worker tags (dynamic, retroactive)#1006

Merged
renemadsen merged 2 commits into
stablefrom
feature/calendar-worker-tags
Jun 14, 2026
Merged

feat(calendar): assign events to worker tags (dynamic, retroactive)#1006
renemadsen merged 2 commits into
stablefrom
feature/calendar-worker-tags

Conversation

@renemadsen

Copy link
Copy Markdown
Member

What

Adds the ability to assign backend-configuration calendar events to worker tags. A worker tag expands live to all workers carrying it, and membership/assignment changes are retroactive — they create or retract the real eForm cases for already-deployed future occurrences.

How

  • Persist: AreaRulePlanningWorkerTag links (new entity in base v10.0.43) written on create/update; validation relaxed to require explicit workers or worker tags.
  • Resolve: CalendarAssignmentResolver — effective recipients = explicit PlanningSites ∪ live SiteTag members of the event's worker tags.
  • Reconcile: pure AssignmentReconciliationPlanner + CalendarAssignmentReconciliationService — idempotent retroactive add/retract over future already-deployed occurrences; completed cases immutable; per-occurrence-exception aware.
  • Deploy: EventDeployService unions tag members into the deploy path (forward direction) and gains a site-aware idempotency guard.
  • Triggers: calendar create/update/delete; worker-tag changes on property-workers; tag-aware resignation lock + authoritative backend block.
  • Frontend: new "Assign to worker tags" field (distinct from the item-planning "Set tags"), card chips, i18n across 26 languages.

Tests

  • Unit: AssignmentReconciliationPlannerTest (6 edge-case tests)
  • Integration: WorkerTagAssignmentTest (6 tests — resolver union, removed-exclusion, retroactive add, past-skip, remove-non-completed/keep-completed)
  • e2e: calendar-worker-tags.spec.ts (tag-only event create + edit round-trip)

Notes

  • Requires base Microting.EformBackendConfigurationBase 10.0.43 (already published); ref bumped in this PR.
  • Known limitation: real-time reconcile on global worker-tag deletion is deferred (no core→plugin hook); resolver excludes deleted-tag members automatically, residual cases clean up on next event edit.

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings June 14, 2026 15:09

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds worker-tag–based assignment for Backend Configuration calendar events, including live expansion from tags to workers and retroactive reconciliation to add/retract already-deployed future occurrences when tag membership or event assignments change.

Changes:

  • Backend: Introduces resolver + reconciliation services for effective recipients (explicit sites ∪ live worker-tag members) and retroactive per-occurrence deploy/retract logic.
  • Backend: Updates deploy flow to consider worker-tag membership and strengthens idempotency to be site-aware.
  • Frontend: Adds “Assign to worker tags” field, displays worker-tag chips, and extends i18n + E2E coverage.

Reviewed changes

Copilot reviewed 69 out of 69 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Services/EventDeployService/EventDeployService.cs Includes worker-tag membership in deploy eligibility and makes idempotency guard site-aware.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Services/CalendarAssignmentReconciliation/ICalendarAssignmentResolver.cs New interface for resolving effective recipient site IDs.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Services/CalendarAssignmentReconciliation/ICalendarAssignmentReconciliationService.cs New interface for event/tag-triggered reconciliation entrypoints.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Services/CalendarAssignmentReconciliation/CalendarAssignmentResolver.cs Implements effective recipient resolution (explicit PlanningSites ∪ SDK SiteTags).
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Services/CalendarAssignmentReconciliation/CalendarAssignmentReconciliationService.cs Implements retroactive deploy/retract planner/executor for future deployed occurrences.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Services/CalendarAssignmentReconciliation/AssignmentReconciliationPlanner.cs Pure planner producing per-occurrence add/remove sets.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Services/BackendConfigurationCalendarService/BackendConfigurationCalendarService.cs Persists worker-tag links, round-trips tag IDs in responses, and triggers reconciliation on create/update.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Services/BackendConfigurationAssignmentWorkerService/BackendConfigurationAssignmentWorkerService.cs Wires reconciliation into worker update/create flow; counts assignments including worker tags.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Resources/localization.json Adds backend localization key for resignation block message.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Infrastructure/Models/Calendar/CalendarTaskResponseModel.cs Adds WorkerTagIds to calendar response model.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Infrastructure/Models/Calendar/CalendarTaskCreateRequestModel.cs Adds WorkerTagIds to calendar create request model.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Infrastructure/Helpers/BackendConfigurationAssignmentWorkerServiceHelper.cs Reconciles on tag membership change and blocks resignation when still effectively assigned via tags.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/EformBackendConfigurationPlugin.cs Registers new resolver + reconciliation services in DI.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/BackendConfiguration.Pn.csproj Bumps Microting.EformBackendConfigurationBase to 10.0.43.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Test/AssignmentReconciliationPlannerTest.cs Unit tests for reconciliation planner edge cases.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/WorkerTagAssignmentTest.cs Integration tests for resolver union behavior and retroactive reconciliation add/remove semantics.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/DocumentsGrpcServiceCalendarFileTest.cs Updates calendar service construction with reconciliation service dependency.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/CalendarYearlyMoveTests.cs Updates calendar service construction with reconciliation service dependency.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/CalendarYearlyEnumerateTests.cs Updates calendar service construction with reconciliation service dependency.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/CalendarUpdateTaskScopeTests.cs Updates calendar service construction with reconciliation service dependency.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/CalendarThisAndFollowingMoveBackReproTests.cs Updates calendar service construction with reconciliation service dependency.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/CalendarTaskListIndexTest.cs Updates calendar service construction with reconciliation service dependency.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/CalendarResizeTests.cs Updates calendar service construction with reconciliation service dependency.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/CalendarRepeatPersistenceTests.cs Updates calendar service construction with reconciliation service dependency.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/CalendarRecurrenceRulePersistenceFixTests.cs Updates calendar service construction with reconciliation service dependency.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/CalendarOrphanRenderComplianceTests.cs Updates calendar service construction with reconciliation service dependency.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/CalendarOccurrenceExceptionTests.cs Updates calendar service construction with reconciliation service dependency.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/CalendarMultiLanguageTitleDescriptionTests.cs Updates calendar service construction with reconciliation service dependency.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/CalendarComplianceMoveTests.cs Updates calendar service construction with reconciliation service dependency.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/CalendarCompleteOccurrenceTests.cs Updates calendar service construction with reconciliation service dependency.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/CalendarCompletedPeriodSuppressionTests.cs Updates calendar service construction with reconciliation service dependency.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/CalendarBoardDeleteCascadeTests.cs Updates calendar service construction with reconciliation service dependency.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/CalendarAttachmentTests.cs Updates calendar service construction with reconciliation service dependency.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/CalendarActionableOnlyTests.cs Updates calendar service construction with reconciliation service dependency.
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/BackendConfigurationCalendarServiceTaskTrackerListTest.cs Updates calendar service construction with reconciliation service dependency.
eform-client/src/app/plugins/modules/backend-configuration-pn/modules/calendar/modals/task-create-edit-modal/task-create-edit-modal.component.ts Adds worker-tags form control and includes workerTagIds in save payload.
eform-client/src/app/plugins/modules/backend-configuration-pn/modules/calendar/modals/task-create-edit-modal/task-create-edit-modal.component.html Adds worker-tags selector UI and relaxes Save button enablement to allow tag-only assignment.
eform-client/src/app/plugins/modules/backend-configuration-pn/modules/calendar/components/calendar-schedule-view/calendar-schedule-view.component.scss Styles worker-tag chips distinct from planning tags.
eform-client/src/app/plugins/modules/backend-configuration-pn/modules/calendar/components/calendar-schedule-view/calendar-schedule-view.component.html Renders worker-tag chips in calendar schedule view.
eform-client/src/app/plugins/modules/backend-configuration-pn/modules/calendar/components/calendar-container/calendar-container.component.ts Passes available tags to modal and resolves workerTagIds → display names for views.
eform-client/src/app/plugins/modules/backend-configuration-pn/modules/calendar-task-list/components/calendar-task-list-page/calendar-task-list-page.component.ts Loads available tags via EformTagService and passes to edit modal.
eform-client/src/app/plugins/modules/backend-configuration-pn/models/calendar/calendar-task.model.ts Extends task model with workerTagIds/workerTagNames fields.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/bgBG.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/csCZ.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/da.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/deDE.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/elGR.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/enUS.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/esES.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/etET.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/fiFI.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/frFR.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/hrHR.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/huHU.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/isIS.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/itIT.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/ltLT.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/lvLV.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/nlNL.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/noNO.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/plPL.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/ptBR.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/ptPT.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/roRO.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/skSK.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/slSL.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/svSE.ts Adds translations for worker-tag assignment UI strings.
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/ukUA.ts Adds translations for worker-tag assignment UI strings.
eform-client/playwright/e2e/plugins/backend-configuration-pn/l/calendar-worker-tags.spec.ts E2E test for tag-only assignment create/edit round-trip.
Comments suppressed due to low confidence (2)

eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Services/BackendConfigurationCalendarService/BackendConfigurationCalendarService.cs:1237

  • CreateTask validation now allows either explicit Sites or WorkerTagIds, but the error message still returns the localization key "AtLeastOneWorkerMustBeAssigned". That message is now inaccurate/misleading for callers (it should mention worker tags as an alternative).
            var hasExplicitSites = createModel.Sites is { Count: > 0 };
            var hasWorkerTags = createModel.WorkerTagIds is { Count: > 0 };
            if (!hasExplicitSites && !hasWorkerTags)
            {
                return new OperationDataResult<int>(false,
                    localizationService.GetString("AtLeastOneWorkerMustBeAssigned"));
            }

eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Services/BackendConfigurationCalendarService/BackendConfigurationCalendarService.cs:1424

  • UpdateTask validation now allows either explicit Sites or WorkerTagIds, but it still returns the localization key "AtLeastOneWorkerMustBeAssigned" on failure. The message should be updated to reflect that worker tags are also valid assignees, otherwise API consumers get a misleading error.
            var hasExplicitSites = updateModel.Sites is { Count: > 0 };
            var hasWorkerTags = updateModel.WorkerTagIds is { Count: > 0 };
            if (!hasExplicitSites && !hasWorkerTags)
            {
                return new OperationResult(false,
                    localizationService.GetString("AtLeastOneWorkerMustBeAssigned"));
            }

Comment on lines +4658 to +4661
"Key": "WorkerStillAssignedToEventsCannotResign",
"LocalizedValue": {
"en-US": "Worker is still assigned to one or more events and cannot be resigned. Remove them from those events (or the tags) first."
}
Comment on lines +221 to +227
// Compliance rows for this (planning, date) with a backing SDK case
// are loaded once by the caller and reused across every removed site.
foreach (var compliance in complianceList)
{
var sdkCase = await sdkDbContext.Cases
.SingleOrDefaultAsync(x => x.Id == compliance.MicrotingSdkCaseId, ct)
.ConfigureAwait(false);
Assign backend-configuration calendar events to worker tags; a tag expands
live to all workers carrying it, and membership/assignment changes retroactively
create/retract the eForm cases for already-deployed future occurrences.

- Persist AreaRulePlanningWorkerTag links (base v10.0.43) on create/update
- CalendarAssignmentResolver: effective set = explicit sites ∪ live tag members
- AssignmentReconciliationPlanner (pure) + CalendarAssignmentReconciliationService:
  idempotent retroactive add/retract; completed cases immutable; exception-aware
- EventDeployService: union tag members into deploy + site-aware idempotency guard
- Triggers: calendar create/update/delete; worker-tag changes; tag-aware
  resignation lock + authoritative backend block
- Frontend "Assign to worker tags" field (separate from item-planning tags),
  relaxed validation (workers OR tags), card chips, i18n (26 languages)
- Tests: planner unit tests, WorkerTagAssignment integration tests, Playwright e2e
- Bump Microting.EformBackendConfigurationBase 10.0.42 -> 10.0.43

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@renemadsen renemadsen force-pushed the feature/calendar-worker-tags branch from 6dfe47b to 8746b5c Compare June 14, 2026 15:19
… event has worker tags

The C4 worker-tag narrowing called coreHelper.GetCore() unconditionally,
breaking the no-op/no-tag fast paths (EventDeployServiceTest asserts
DidNotReceive().GetCore() and leaves GetCore unstubbed -> NRE). Now the SDK
core is only reached when a candidate event actually carries worker tags
(cheap backend-config check first). All 12 EventDeployServiceTest cases pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@renemadsen renemadsen merged commit 64b9b13 into stable Jun 14, 2026
26 checks passed
@renemadsen renemadsen deleted the feature/calendar-worker-tags branch June 14, 2026 16:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants