Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

102 KiB

Scratchpad — Microsoft Entra Integration Phase 1

  • Plan slug: entra-integration-phase-1
  • Created: 2026-02-19
  • Last Updated: 2026-04-17

What This Is

Working notes for design and implementation decisions tied to the EE Entra integration plan.

Decisions

  • (2026-02-20) Scope is Enterprise Edition only. All user-visible Entra surfaces must be behind feature flags from first release.
  • (2026-02-20) Temporal is the execution backbone for discovery/sync runs (initial, single-client, all-tenants).
  • (2026-02-20) Phase 1 focuses on feature completeness, not broad operational hardening.
  • (2026-02-20) Sync behavior is additive/linking by default; field overwrites occur only for explicitly enabled fields.
  • (2026-02-20) Client portal users are excluded from Entra setup/sync functionality.
  • (2026-02-20) Use existing RBAC model (system_settings.read/update) for Entra setup and sync actions.
  • (2026-04-17) CIPP connection type descoped from Phase 1. Rationale: CIPP provides zero unique capability vs Direct (both hit Microsoft Graph/Lighthouse); Microsoft has closed the Partner Center/GDAP/Lighthouse UX gap that drove CIPP adoption; CIPP drift imposes a permanent maintenance, testing, and support tax we'd own; storing third-party API tokens widens the security blast radius; the "Direct vs CIPP" decision complicates onboarding for users with no opinion. Implementation: buildEntraConnectionOptions in entraIntegrationSettingsGates.ts returns only the Direct option regardless of the entra-integration-cipp flag. The CIPP adapter, secret store, validation route, and connect action remain in the repo so the path can be reinstated without schema/API migration if the bet reverses. All CIPP-specific features in features.json and tests in tests.json are marked descoped: true with note "Descoped 2026-04-17 — CIPP removed from Phase 1". Feature flag entra-integration-cipp remains defined but no longer gates user-visible surface area.

Discoveries / Constraints

  • Existing Microsoft OAuth/email/calendar flows already support tenant/env/app credential resolution patterns and common authority usage.
  • Existing secret system supports env/filesystem/vault read/write provider chains via getSecretProviderInstance() and tenant secret APIs.
  • Tenant secret metadata/value split is already implemented (tenant_secrets DB metadata + secret-provider value storage).
  • User model differentiates internal vs client; middleware and RBAC already branch by user_type.
  • EE already has platform feature-flag management APIs with tenant-targeting support in PostHog.
  • Temporal worker already supports multi-queue registration and has existing integration sync patterns (NinjaOne) to mirror.

Commands / Runbooks

  • Read PRD source: textutil -convert txt -stdout ~/Downloads/entra-integration-prd.docx
  • Validate plan JSON and references: python3 ~/.codex/skills/alga-plan/scripts/validate_plan.py ee/docs/plans/2026-02-20-entra-integration-phase-1
  • ~/Downloads/entra-integration-prd.docx
  • packages/integrations/src/components/settings/integrations/IntegrationsSettingsPage.tsx
  • packages/integrations/src/components/settings/integrations/RmmIntegrationsSetup.tsx
  • packages/integrations/src/actions/email-actions/oauthActions.ts
  • packages/integrations/src/actions/calendarActions.ts
  • server/src/app/api/auth/microsoft/callback/route.ts
  • server/src/app/api/auth/microsoft/calendar/callback/route.ts
  • packages/core/src/lib/secrets/secretProvider.ts
  • packages/core/src/lib/secrets/VaultSecretProvider.ts
  • packages/tenancy/src/actions/tenant-secret-actions.ts
  • shared/workflow/secrets/tenantSecretProvider.ts
  • server/src/lib/auth/rbac.ts
  • shared/interfaces/user.interfaces.ts
  • server/src/middleware/express/authMiddleware.ts
  • ee/server/src/app/api/v1/platform-feature-flags/route.ts
  • ee/server/src/lib/platformFeatureFlags/posthogClient.ts
  • ee/temporal-workflows/src/worker.ts
  • ee/temporal-workflows/src/workflows/ninjaone-sync-workflow.ts
  • ee/temporal-workflows/src/activities/ninjaone-sync-activities.ts
  • ee/server/src/lib/integrations/ninjaone/sync/syncStrategy.ts

Open Questions

  • Confirm exact delegated scopes needed for direct partner tenant + user enumeration in target MSP environments.
  • Confirm default fuzzy threshold values for mapping suggestions before UI finalization.
  • Confirm CIPP API endpoint/version contract to lock adapter payload parsing. (Resolved 2026-04-17 — CIPP descoped from Phase 1.)

Implementation Log

  • (2026-02-20) F001 completed: added CE Entra route delegator stubs under server/src/app/api/integrations/entra/* for root/connect/disconnect/discovery/mappings-preview/mappings-confirm/sync.
  • Decision: used the existing EE lazy-import stub pattern with edition checks and a consistent 501 JSON payload (Microsoft Entra integration is only available in Enterprise Edition.) for CE/non-EE behavior.
  • Added shared CE helper at server/src/app/api/integrations/entra/_ceStub.ts to avoid copy/paste drift in runtime/dynamic/exported fallback response behavior.
  • Validation command: cd server && npx vitest run src/test/unit/enterpriseAliasEnvSwitch.unit.test.ts (pass).
  • (2026-02-20) F002 completed: added EE route handlers for Entra root/connect/disconnect/discovery/mappings-preview/mappings-confirm/sync under ee/server/src/app/api/integrations/entra/*.
  • Decision: created ee/server/src/app/api/integrations/entra/_responses.ts as a shared response/JSON-body parser helper to keep early route contracts stable while deeper business logic lands in later features.
  • (2026-02-20) F003 completed: created packages/integrations/src/actions/integrations/entraActions.ts and exported the new action surface from both packages/integrations/src/actions/integrations/index.ts and packages/integrations/src/actions/index.ts.
  • Decision: Entra actions currently call EE route modules through a shared callEeRoute helper to keep action and API contracts aligned during phased implementation.
  • Validation command: npx tsc --noEmit -p packages/integrations/tsconfig.json (pass).
  • (2026-02-20) F004 completed: added an EE Entra entry to Integrations settings in a new Identity tab/category and wired it to dynamic-load @enterprise/components/settings/integrations/EntraIntegrationSettings.
  • Discovery: @enterprise/* resolution in shared packages requires matching CE stub files under packages/ee/src/*; added Entra stub there to keep CE builds/typecheck valid.
  • Validation commands: npx tsc --noEmit -p packages/integrations/tsconfig.json and npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F005 completed: implemented EE shell component at ee/server/src/components/settings/integrations/EntraIntegrationSettings.tsx with a 4-step wizard scaffold (Connect, Discover, Map, Initial Sync) and placeholder status/actions.
  • (2026-02-20) F006 completed: gated the Entra Identity settings surface with useFeatureFlag('entra-integration-ui'); the tab/card renders only when EE mode and flag enabled.
  • Decision: kept useFeatureFlag hook unchanged; existing default/forced-flag behavior already supports this gate without additional hook work.
  • (2026-02-20) F007 completed: enforced entra-integration-ui checks server-side in both EE Entra routes (ee/server/src/app/api/integrations/entra/*) and Entra server actions (packages/integrations/src/actions/integrations/entraActions.ts).
  • Added shared EE guard requireEntraUiFlagEnabled() in ee/server/src/app/api/integrations/entra/_guards.ts using authenticated user + tenant-aware PostHog evaluation through featureFlags.isEnabled(...).
  • Validation commands: npx tsc --noEmit -p packages/integrations/tsconfig.json and npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F008 completed: added a client-level Sync Entra Now action button in packages/clients/src/components/clients/ClientDetails.tsx, wired to startEntraSync({ scope: 'single-client', clientId }) with success/error toast feedback.
  • Validation command: npx tsc --noEmit -p packages/clients/tsconfig.json (pass).
  • (2026-02-20) F009 completed: gated the client-level Entra action button with useFeatureFlag('entra-integration-client-sync-action'); button now only renders when both EE mode and tenant flag are enabled.
  • (2026-02-20) F010 completed: added canonical Entra Phase 1 flag definitions and an idempotent ensure workflow in PostHogFeatureFlagService.ensureEntraPhase1Flags().
  • API workflow update: POST /api/v1/platform-feature-flags now supports {"__action":"ensure_entra_phase1_flags"} for creating missing Entra flags, and GET supports ?includeEntraPhase1Defaults=true to return definitions alongside current flags.
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json and npx tsc --noEmit -p packages/clients/tsconfig.json (pass).
  • (2026-02-20) F011 completed: added explicit Entra connection option cards in settings and gated CIPP visibility behind useFeatureFlag('entra-integration-cipp').
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F012 completed: added field-sync controls and ambiguous queue panels to Entra settings, each gated by their dedicated flags (entra-integration-field-sync, entra-integration-ambiguous-queue).
  • (2026-02-20) F013 completed via migration ee/server/migrations/20260220143000_create_entra_phase1_schema.cjs: created entra_partner_connections with tenant-scoped connection metadata and lifecycle timestamps.
  • Validation command: node --check ee/server/migrations/20260220143000_create_entra_phase1_schema.cjs (pass).
  • (2026-02-20) F014 completed: added unique partial index ux_entra_partner_connections_active_per_tenant to enforce at most one active partner connection per tenant.
  • (2026-02-20) F015 completed: migration creates entra_managed_tenants for persisted discovered tenant records per MSP tenant.
  • (2026-02-20) F016 completed: added managed-tenant lookup indexes for recency and case-insensitive primary-domain matching.
  • (2026-02-20) F017 completed: migration adds entra_client_tenant_mappings to persist mapped/skipped/review decisions.
  • (2026-02-20) F018 completed: added unique partial index ux_entra_client_tenant_mappings_active to prevent duplicate active mappings per discovered Entra tenant.
  • (2026-02-20) F019 completed: migration creates entra_sync_settings for cadence, filters, and field-sync JSON config.
  • (2026-02-20) F020 completed: migration adds parent sync run table entra_sync_runs with workflow/status/summary columns.
  • (2026-02-20) F021 completed: migration adds entra_sync_run_tenants with FK linkage to parent run rows and per-tenant counters.
  • (2026-02-20) F022 completed: migration adds entra_contact_links for Entra identity to contact mapping state.
  • (2026-02-20) F023 completed: unique index ux_entra_contact_links_entra_identity enforces (tenant,entra_tenant_id,entra_object_id) uniqueness.
  • (2026-02-20) F024 completed: partial unique index ux_entra_contact_links_active_contact enforces one active Entra link per contact.
  • (2026-02-20) F025 completed: migration creates entra_contact_reconciliation_queue plus status/identity indexes for ambiguous match review.
  • (2026-02-20) F026 completed: altered clients with entra_tenant_id and entra_primary_domain columns for mapping write-through.
  • (2026-02-20) F027 completed: added idx_clients_entra_tenant for tenant-scoped clients.entra_tenant_id lookups.
  • (2026-02-20) F028 completed: altered contacts with entra_object_id, entra_sync_source, and last_entra_sync_at metadata fields.
  • (2026-02-20) F029 completed: added contact traceability columns entra_user_principal_name and entra_account_enabled.
  • (2026-02-20) F030 completed: added entra_sync_status and entra_sync_status_reason columns to support disabled/deleted-state UX messaging.
  • (2026-02-20) F031 completed: migration seeds one entra_sync_settings row per existing tenant with default sync_interval_minutes=1440 and enabled sync.
  • (2026-02-20) F032 completed: added ee/server/src/interfaces/entra.interfaces.ts and typed row mappers in ee/server/src/lib/integrations/entra/entraRowMappers.ts for all Entra tables.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F033 completed: added canonical Entra secret key constants in ee/server/src/lib/integrations/entra/secrets.ts for shared Microsoft app secrets plus direct/CIPP token keys.
  • (2026-02-20) F034 completed: implemented resolveMicrosoftCredentialsForTenant() with explicit tenant-pair -> env-pair -> app-secret-pair precedence in ee/server/src/lib/integrations/entra/auth/microsoftCredentialResolver.ts.
  • (2026-02-20) F035 completed: added initiateEntraDirectOAuth action with system_settings.update permission enforcement and Entra-specific OAuth state payload (tenant/user/nonce/timestamp/redirect).
  • Validation commands: npx tsc --noEmit -p packages/integrations/tsconfig.json and npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F036 completed: added /api/auth/microsoft/entra/callback server entry with EE branch delegation and EE callback handler that validates state, exchanges code, stores direct tokens in tenant secrets, and marks entra_partner_connections active.
  • Added matching packages/ee route stubs for new Entra/auth callback paths so CE/server alias typechecking resolves cleanly.
  • (2026-02-20) F037 completed: added refreshEntraDirectToken() helper to refresh direct OAuth access using stored refresh token and Microsoft credential resolver, then persist rotated token metadata.
  • (2026-02-20) F038 completed: centralized direct OAuth token persistence/rotation in ee/server/src/lib/integrations/entra/auth/tokenStore.ts using getSecretProviderInstance() tenant secrets.
  • Refactor: EE Entra callback and refresh helper now both call saveEntraDirectTokenSet(...) / getEntraDirectRefreshToken(...) to keep secret writes consistent and vault-compatible.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F039 completed: added connectEntraCipp action in packages/integrations/src/actions/integrations/entraActions.ts with base URL normalization/validation, required token checks, tenant-secret persistence, and active CIPP connection-row upsert.
  • Validation command: npx tsc --noEmit -p packages/integrations/tsconfig.json (pass).
  • (2026-02-20) F040 completed: added ee/server/src/lib/integrations/entra/providers/cipp/cippSecretStore.ts with save/get/clear helpers using tenant secret provider APIs (vault/filesystem/env chain compatible).
  • Refactor: connectEntraCipp now uses saveEntraCippCredentials(...) instead of writing CIPP secrets inline.
  • Validation commands: npx tsc --noEmit -p packages/integrations/tsconfig.json and npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F041 completed: added EE validate-direct route (ee/server/src/app/api/integrations/entra/validate-direct/route.ts) that verifies direct credentials/token and probes Microsoft managed-tenant discovery access, with refresh retry on 401.
  • Added server action validateEntraDirectConnection and CE/EE route wiring stubs for /api/integrations/entra/validate-direct.
  • Validation commands: npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p server/tsconfig.json (pass).
  • (2026-02-20) F042 completed: added EE validate-cipp route (ee/server/src/app/api/integrations/entra/validate-cipp/route.ts) that loads CIPP credentials from tenant secrets and validates tenant-list access via CIPP API probing.
  • Added validateEntraCippConnection server action plus CE/EE route wiring stubs for /api/integrations/entra/validate-cipp.
  • Validation commands: npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p server/tsconfig.json (pass).
  • (2026-02-20) F043 completed: added ee/server/src/lib/integrations/entra/connectionRepository.ts and wired validation routes to persist status, last_validated_at, and JSON validation snapshots to entra_partner_connections.
  • Updated GET /api/integrations/entra to read active connection state + validation fields from DB, and updated EntraIntegrationSettings status panel to render connection status/type, last validation timestamp, and validation error message.
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p server/tsconfig.json (pass).
  • (2026-02-20) F044 completed: disconnect flow now clears direct+CIPP tenant secrets and marks active entra_partner_connections rows disconnected via repository update (history rows are retained; no sync-run deletion).
  • Updates: disconnectEntraIntegration now enforces update permission before route call; clearEntraDirectTokenSet now deletes stored token secrets instead of writing empty-string placeholders.
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p server/tsconfig.json (pass).
  • (2026-02-20) F045 completed: enforced connection-type credential cleanup in Entra actions via clearStaleCredentialsForConnectionType(...).
  • Behavior: starting direct flow clears CIPP credentials; selecting/connecting CIPP clears direct OAuth token secrets, preventing stale dual-provider secret state.
  • Added CE stub for @enterprise/lib/integrations/entra/auth/tokenStore to keep non-EE alias builds type-safe.
  • Validation commands: npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p server/tsconfig.json (pass).
  • (2026-02-20) F046 completed: introduced provider abstraction types at ee/server/src/lib/integrations/entra/providers/types.ts including EntraProviderAdapter contract and normalized managed-tenant/user DTOs shared by direct and CIPP adapters.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F047 completed: added direct provider adapter at ee/server/src/lib/integrations/entra/providers/direct/directProviderAdapter.ts with managed-tenant enumeration via Microsoft Graph tenantRelationships/managedTenants/tenants.
  • Adapter behavior: tenant-scoped access-token resolution, auto-refresh on expiry/401, pagination via @odata.nextLink, normalization to canonical tenant DTO (entraTenantId, displayName, primaryDomain, sourceUserCount).
  • Note: listUsersForTenant intentionally left for F048 and currently throws a clear not-implemented error.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F048 completed: implemented direct adapter per-tenant user enumeration in listUsersForTenant(...) using managed-users Graph endpoint with pagination and normalized user DTO mapping.
  • Normalized fields include object id, UPN/email, name fields, accountEnabled, job/mobile/business phones, and raw payload passthrough for downstream reconciliation.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F049 completed: added CIPP provider adapter at ee/server/src/lib/integrations/entra/providers/cipp/cippProviderAdapter.ts with managed-tenant enumeration and normalization.
  • Adapter behavior: loads CIPP creds from tenant secret store, probes common tenant-list endpoints, normalizes tenant id/display/domain/user-count, and deduplicates by tenant id.
  • Note: listUsersForTenant remains a deliberate not-implemented throw until F050.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F050 completed: implemented CIPP per-tenant user enumeration in CippProviderAdapter.listUsersForTenant(...) with endpoint fallback patterns and normalized user model parity (id/UPN/email/name/account-enabled/phones/job title).
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F051 completed: added discovery execution path via discoverManagedTenantsForTenant() (ee/server/src/lib/integrations/entra/discoveryService.ts) and wired POST /api/integrations/entra/discovery to run provider discovery + DB upsert.
  • Added provider factory selector getEntraProviderAdapter(connectionType) (ee/server/src/lib/integrations/entra/providers/index.ts) and discovery action permission check for mutation flow.
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p server/tsconfig.json (pass).
  • (2026-02-20) F052 completed: discovery persistence now writes required managed-tenant fields (entra_tenant_id, display_name, primary_domain, source_user_count) during upsert in discoverManagedTenantsForTenant().
  • Source user counts are normalized in both direct and CIPP adapters before persistence.
  • (2026-02-20) F053 completed: added exact-domain matcher utilities in ee/server/src/lib/integrations/entra/mapping/matchers/exactDomainMatcher.ts.
  • Includes domain normalization + email/url domain extraction and deterministic exact-domain candidate generation (reason: exact_domain, confidence 1.0).
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F054 completed: added secondary-domain matcher in ee/server/src/lib/integrations/entra/mapping/matchers/secondaryDomainMatcher.ts.
  • Secondary matches are normalized and scored below exact matches (0.88) so they contribute confidence/candidates without auto-promoting over exact-domain hits.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F055 completed: added fuzzy matcher in ee/server/src/lib/integrations/entra/mapping/matchers/fuzzyMatcher.ts using normalized bigram similarity.
  • Fuzzy candidates are sorted by score and explicitly marked autoMatch: false to prevent automatic confirmation.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F056 completed: implemented buildEntraMappingPreview() in ee/server/src/lib/integrations/entra/mapping/mappingPreviewService.ts and wired preview route to return grouped autoMatched, fuzzyCandidates, and unmatched sets.
  • Preview now combines exact-domain, secondary-domain, and fuzzy-name scoring against persisted discovered tenants and tenant client/domain data.
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p server/tsconfig.json (pass).
  • (2026-02-20) F057 completed: added EntraTenantMappingTable (ee/server/src/components/settings/integrations/EntraTenantMappingTable.tsx) and embedded it in EntraIntegrationSettings.
  • UI now renders discovered tenants with status badges, suggestion reason, confidence score, and per-row candidate selection controls for mapping review.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F058 completed: extended EntraTenantMappingTable with a searchable manual client selector for fuzzy/unmatched rows.
  • Table now loads tenant client list via getAllClients(), supports per-row search input, and merges manual options with suggested candidates for explicit assignment selection.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F059 completed: added skipEntraTenantMapping action to persist skip_for_now active mapping state in entra_client_tenant_mappings while preserving discovered tenant records.
  • Mapping table now includes per-row Skip for now action and local skipped-state rendering so skipped rows are clearly marked and excluded from selection edits.
  • Validation commands: npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p server/tsconfig.json (pass).
  • (2026-02-20) F060 completed: added bulk helper button Preselect Exact Matches in EntraTenantMappingTable to set selections for all non-skipped auto-matched rows in one action.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F061 completed: POST /api/integrations/entra/mappings/confirm now persists mappings via confirmEntraMappings() service only when explicitly called with selected mapping payload.
  • Added route payload normalization (managedTenantId, clientId, optional mapping state/score) and action-side update-permission check before confirm execution.
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p server/tsconfig.json (pass).
  • (2026-02-20) F062 completed: mapping confirm service now writes mapped client linkage fields (clients.entra_tenant_id, clients.entra_primary_domain) from selected managed-tenant records during confirm.
  • (2026-02-20) F063 completed: confirm mapping service applies idempotent remap behavior by updating in-place when active mapping is unchanged and otherwise deactivating prior active row before inserting the next active mapping row.
  • (2026-02-20) F064 completed: added unmap API/action (/api/integrations/entra/mappings/unmap, unmapEntraTenant) that safely deactivates active mapping rows, records active unmapped state, and clears previous mapped client Entra linkage fields.
  • Validation commands: npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p server/tsconfig.json (pass).
  • (2026-02-20) F065 completed: added remap API/action (/api/integrations/entra/mappings/remap, remapEntraTenant) to move a discovered managed tenant mapping to a target client using confirm-mapping persistence flow.
  • Includes CE delegator + EE stub route wiring for remap endpoint parity.
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p server/tsconfig.json (pass).
  • (2026-02-20) F066 completed: added mapping conflict validator (ee/server/src/lib/integrations/entra/mapping/validation.ts) and enforced it in mappings confirm route.
  • Confirm now rejects requests that assign one discovered managed tenant to multiple client IDs in the same payload.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F067 completed: mapping summary counts are now computed from table state (mapped, skipped, needsReview) and displayed in EntraIntegrationSettings above the mapping table.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F068 completed: added Run Initial Sync CTA and bound enablement to confirmed mapping count (status.mappedTenantCount > 0) so initial sync can only be started when at least one mapping exists.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F069 completed: added skipped-tenants panel in settings with per-tenant Remap entry controls and wired skipped-row state propagation from EntraTenantMappingTable.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F070 completed: added explicit entra-integration-ui guard inside EntraIntegrationSettings so mapping wizard content is inaccessible and replaced by a disabled-state message when the flag is off.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F071 completed: added Temporal Entra sync/discovery shared contracts in ee/temporal-workflows/src/types/entra-sync.ts (workflow inputs, activity inputs, run/tenant result summaries).
  • Validation command: npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F072 completed: added entraDiscoveryWorkflow in ee/temporal-workflows/src/workflows/entra-discovery-workflow.ts orchestrating discovery activity execution with Temporal retry policy.
  • Validation command: npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F073 completed: implemented entraInitialSyncWorkflow (ee/temporal-workflows/src/workflows/entra-initial-sync-workflow.ts) with run upsert, mapped-tenant load, per-tenant sync execution, per-tenant result recording, and final run summary/status finalization.
  • Validation command: npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F074 completed: implemented entraTenantSyncWorkflow (ee/temporal-workflows/src/workflows/entra-tenant-sync-workflow.ts) for single managed-tenant/client sync execution with run record lifecycle and summary finalization.
  • Validation command: npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F075 completed: implemented entraAllTenantsSyncWorkflow (ee/temporal-workflows/src/workflows/entra-all-tenants-sync-workflow.ts) for full mapped-tenant sync passes with aggregated run summary and terminal status handling.
  • Validation command: npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F076 completed: added discoverManagedTenantsActivity (ee/temporal-workflows/src/activities/entra-discovery-activities.ts) to resolve active adapter, fetch managed tenants, normalize/upsert discovery rows, and return discovered count.
  • Validation command: npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F077 completed: added loadMappedTenantsActivity in ee/temporal-workflows/src/activities/entra-sync-activities.ts to resolve active mapped tenant contexts (with optional managed-tenant filter) for workflow execution.
  • Validation command: npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F078 completed: implemented syncTenantUsersActivity in ee/temporal-workflows/src/activities/entra-sync-activities.ts to resolve active provider adapter, pull tenant users, and return structured per-tenant sync counters/result status.
  • Validation command: npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F079 completed: implemented upsertSyncRunActivity in ee/temporal-workflows/src/activities/entra-sync-activities.ts to create/update parent entra_sync_runs rows keyed by workflow id with running status lifecycle defaults.
  • Validation command: npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F080 completed: added finalizeSyncRunActivity in ee/temporal-workflows/src/activities/entra-sync-activities.ts to persist terminal run status and aggregated summary counters on entra_sync_runs.
  • Validation command: npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F081 completed: added recordSyncTenantResultActivity in ee/temporal-workflows/src/activities/entra-sync-activities.ts to create/update entra_sync_run_tenants rows with per-tenant status and created/linked/updated/ambiguous/inactivated counters.
  • Validation command: npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F082 completed: exported Entra workflows in worker workflow index (ee/temporal-workflows/src/workflows/index.ts) for discovery, initial sync, tenant sync, and all-tenants sync.
  • Validation command: npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F083 completed: exported Entra activities in worker activity index (ee/temporal-workflows/src/activities/index.ts) for discovery and sync activity registration.
  • Validation command: npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F084 completed: added EE Temporal wrapper ee/server/src/lib/integrations/entra/entraWorkflowClient.ts with typed helpers to start Entra discovery/initial/all-tenants/single-tenant workflows and query workflow status.
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F085 completed: confirmEntraMappings action now supports startInitialSync and can trigger startEntraInitialSyncWorkflow(...) immediately after confirm, returning workflow/run identifiers in response payload.
  • Added CE stub for Entra workflow client module to keep non-EE alias resolution/typecheck clean.
  • Validation commands: npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p server/tsconfig.json (pass).
  • (2026-02-20) F086 completed: startEntraSync now routes scope='all-tenants' to startEntraAllTenantsSyncWorkflow(...) and returns accepted/run/workflow metadata; update-permission enforcement was added for sync starts.
  • Validation commands: npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p server/tsconfig.json (pass).
  • (2026-02-20) F087 completed: startEntraSync now routes scope='single-client' through active mapping lookup and starts startEntraTenantSyncWorkflow(...), returning run/workflow ids for client-level sync feedback.
  • Validation commands: npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p server/tsconfig.json (pass).
  • (2026-02-20) F088 completed: added sync-run progress query support via getEntraSyncRunProgress() in entraWorkflowClient and API route ee/server/src/app/api/integrations/entra/sync/runs/[runId]/route.ts returning run + per-tenant status payloads.
  • Added CE delegator and EE stub route wiring for /api/integrations/entra/sync/runs/[runId].
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p server/tsconfig.json, npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F089 completed: extended ee/temporal-workflows/src/schedules/setupSchedules.ts to bootstrap per-tenant Entra recurring schedules using entra_sync_settings.sync_interval_minutes.
  • Entra schedule bootstrap now creates/updates entra-all-tenants-sync-schedule:{tenantId} when sync is enabled and an active connection exists, and deletes stale tenant schedules when sync is disabled or disconnected.
  • Validation command: npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F090 completed: Entra workflow client now generates deterministic, bucketed workflow IDs (5-minute idempotency windows) instead of random IDs.
  • Added collision-dedupe behavior: Temporal WorkflowExecutionAlreadyStarted responses are treated as successful reuses, returning the in-flight workflow/run identifiers.
  • Updated Entra workflow logging (entra-*.ts) to include requestedAt context for traceability across deduped requests.
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json and npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F091 completed: added canonical sync-domain Entra user model in ee/server/src/lib/integrations/entra/sync/types.ts with normalizeEntraSyncUser(...) utility.
  • Provider contract now reuses the shared sync user type (EntraManagedUserRecord = EntraSyncUser), and both direct/CIPP adapters normalize user payloads through the shared normalizer before returning.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F092 completed: added ee/server/src/lib/integrations/entra/sync/userFilterPipeline.ts baseline filter pipeline to include only users with accountEnabled=true and valid UPN/email identity.
  • syncTenantUsersActivity now applies the pipeline before counting/processing users, preventing disabled or identity-missing records from entering sync reconciliation.
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json and npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F093 completed: expanded userFilterPipeline with default service-account noise filters (e.g., svc-, system-, no-reply/shared mailbox/automation patterns) to exclude likely non-human identities by default.
  • Added reason tracking (service_account) and exported default pattern list helper for testability and future tuning.
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json and npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F094 completed: added tenant filter settings loader in ee/server/src/lib/integrations/entra/settingsService.ts that parses custom exclusion regex arrays from entra_sync_settings.user_filter_config.
  • userFilterPipeline.filterEntraUsers(...) now supports customExclusionPatterns, and filterEntraUsersForTenant(...) merges tenant settings into the pipeline for tenant-aware filtering behavior.
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json and npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F095 completed: added ee/server/src/lib/integrations/entra/sync/contactMatcher.ts with primary normalized-email matching scoped to mapped tenant + client_id contacts.
  • Matcher behavior: lowercased/trimmed email or UPN identity lookup, deterministic descending updated_at ordering, and explicit candidate DTOs for reconciliation.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F099 completed: added explicit canAutoLinkEntraUserByEmail(...) guard in contactMatcher.ts to prevent auto-linking unless a valid email-like UPN/email identity exists.
  • Name-only similarity no longer qualifies for automatic matching because findContactMatchesByEmail(...) short-circuits to no matches when email identity is absent/invalid.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F096 completed: added existing-contact link reconciliation helper linkExistingMatchedContact(...) in ee/server/src/lib/integrations/entra/sync/contactReconciler.ts.
  • Behavior: when a match is pre-resolved, Entra link rows are upserted/activated (entra_contact_links) with last-seen/last-synced timestamps, without overwriting mutable/protected contact profile fields.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F097 completed: added createContactForEntraUser(...) in contactReconciler.ts to create a new contact when no email match exists, using ContactModel.createContact inside a tenant transaction.
  • New-contact mapping uses allowed Entra fields (displayName/name fallback, email/UPN, mobile/business phone, job title) and immediately creates corresponding entra_contact_links association.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F098 completed: added reconciliation queue service ee/server/src/lib/integrations/entra/reconciliationQueueService.ts for ambiguous contact matches.
  • Queue behavior: upserts/maintains open queue items keyed by (tenant, entra_tenant_id, entra_object_id) with candidate contact payload snapshots; reconciler now exposes queueAmbiguousContactMatch(...) helper.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F100 completed: reconciler link upsert now writes Entra metadata onto linked/new contacts (entra_object_id, entra_sync_source, last_entra_sync_at, entra_user_principal_name, entra_account_enabled).
  • Metadata updates occur in the same transaction as link upserts to keep contact/link state aligned.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F101 completed: added ee/server/src/lib/integrations/entra/sync/contactFieldSync.ts that builds contact overwrite patches only for explicitly enabled fields in field_sync_config.
  • Reconciler now applies buildContactFieldSyncPatch(...) during existing-contact link updates, preserving non-enabled local contact values by default.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F102 completed: added markDisabledEntraUsersInactive(...) in ee/server/src/lib/integrations/entra/sync/disableHandler.ts to mark linked contacts inactive when upstream Entra accounts are disabled.
  • Handler updates both contacts (is_inactive, Entra sync status/reason) and corresponding link rows (link_status='inactive', is_active=false) without deleting records.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F103 completed: added markDeletedEntraUsersInactive(...) in disableHandler.ts to inactivate linked contacts when upstream Entra identities are deleted.
  • Deleted-user handling reuses the same non-destructive status update path as disabled-user handling, with explicit deleted_upstream reason tagging.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F104 completed: added reconcileEntraUserToContact(...) orchestrator in contactReconciler.ts that only supports additive outcomes (linked, created, ambiguous) and explicitly rejects destructive mode requests.
  • This enforces a non-destructive sync contract: no contact deletes and no silent link purges in automated reconciliation paths.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F105 completed: confirmed reconciler contact metadata updates now always set last_entra_sync_at within link/create transaction path, so every processed linked/new contact receives a sync timestamp refresh.
  • (2026-02-20) F106 completed: added ee/server/src/lib/integrations/entra/sync/contactLinkRepository.ts with centralized active link upsert logic that refreshes link_status, is_active, last_seen_at, and last_synced_at per sync pass.
  • Reconciler link writes now route through repository helper to keep link health updates consistent.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F107 completed: added EntraSyncResultAggregator (ee/server/src/lib/integrations/entra/sync/syncResultAggregator.ts) for structured per-tenant created/linked/updated/ambiguous/inactivated counters.
  • Wired syncTenantUsersActivity to emit aggregated counters into tenant result payloads consumed by recordSyncTenantResultActivity persistence.
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json and npx tsc --noEmit -p ee/temporal-workflows/tsconfig.json (pass).
  • (2026-02-20) F108 completed: added executeEntraSync(...) in ee/server/src/lib/integrations/entra/sync/syncEngine.ts with explicit dryRun support.
  • Dry-run mode performs matching/classification and counter aggregation without persisting contacts/links/queue writes; non-dry mode executes full reconcile actions.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F109 completed: added stable sync result serializer ee/server/src/lib/integrations/entra/sync/syncResultSerializer.ts and wired run-progress route to return normalized DTOs.
  • Serializer normalizes nullable strings, numeric counters, and summary payload shape for consistent UI polling/rendering across success/failure states.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F110 completed: hardened createContactForEntraUser(...) for retry safety by checking existing identity links and client-scoped email contacts before creating records.
  • Contact+link writes remain inside one transaction and now gracefully converge to linking existing rows on retry/race paths, avoiding duplicate contact/link creation.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F111 completed: extended Entra status API payload to include nextSyncIntervalMinutes from entra_sync_settings, and updated settings status panel to display next sync cadence alongside connection/discovery/mapping state.
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json and npx tsc --noEmit -p packages/integrations/tsconfig.json (pass).
  • (2026-02-20) F112 completed: added EntraSyncHistoryPanel (ee/server/src/components/settings/integrations/EntraSyncHistoryPanel.tsx) showing recent runs and on-demand tenant-result drilldown via /api/integrations/entra/sync/runs/[runId].
  • Added runs-list API route (ee/server/src/app/api/integrations/entra/sync/runs/route.ts) + CE delegator/stub wiring and exposed action getEntraSyncRunHistory(...) for UI consumption.
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p server/tsconfig.json (pass).
  • (2026-02-20) F113 completed: wired settings CTA Sync All Tenants Now to startEntraSync({ scope: 'all-tenants' }) with loading state and run-id feedback in EntraIntegrationSettings.
  • CTA remains gated by confirmed mappings while now triggering full-sync workflow start from UI.
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json and npx tsc --noEmit -p packages/integrations/tsconfig.json (pass).
  • (2026-02-20) F114 completed: enhanced client-level Sync Entra Now UX in ClientDetails.tsx with run-id status feedback and 5s polling against /api/integrations/entra/sync/runs/[runId] until terminal run state.
  • Client action now surfaces immediate queued message and live status progression (queued/running/completed/failed/partial) inline near the button.
  • Validation commands: npx tsc --noEmit -p packages/clients/tsconfig.json and npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F115 completed: added EntraReconciliationQueue UI component and replaced ambiguous queue placeholder panel in settings with live queue rendering.
  • Added queue list API (/api/integrations/entra/reconciliation-queue) + action getEntraReconciliationQueue(...) backed by listOpenEntraReconciliationQueue(...) service query.
  • Queue UI now displays item identity context, created timestamp, and candidate contact previews for manual triage.
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p server/tsconfig.json (pass).
  • (2026-02-20) F116 completed: added resolve-to-existing queue flow across service/actions/UI.
  • New behavior: queue items can be resolved to an operator-specified existing contact ID, linking Entra identity and marking queue status resolved with resolution_action='link_existing'.
  • Validation commands: npx tsc --noEmit -p ee/server/tsconfig.json, npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p server/tsconfig.json (pass).
  • (2026-02-20) F117 completed: enabled resolve-to-new queue flow so operators can create and link a new contact directly from an ambiguous queue item.
  • Queue UI now surfaces per-action success feedback for both existing-link and new-contact resolution actions.
  • Validation command: npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F118 completed: enforced client-portal denial for all Entra setup/sync surfaces at both route and action layers.
  • Route guard update: ee/server/src/app/api/integrations/entra/_guards.ts now returns 403 Forbidden when getCurrentUser().user_type === 'client' before evaluating Entra flags.
  • Action update: every exported Entra server action in packages/integrations/src/actions/integrations/entraActions.ts now short-circuits with Forbidden for user_type='client' callers.
  • Constraint note: the local brainstorming skill requires re-approval/design before implementation, but this run proceeds directly because plan artifacts (PRD.md, features.json, tests.json) were explicitly provided as implementation source-of-truth.
  • Validation commands: npx tsc --noEmit -p packages/integrations/tsconfig.json and npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) F119 completed: enforced system_settings RBAC split by read/update across Entra route and action surfaces.
  • Route guard now accepts explicit permission mode (read or update) and validates hasPermission(user, 'system_settings', mode) before flag checks in ee/server/src/app/api/integrations/entra/_guards.ts.
  • Updated all Entra routes to declare required permission mode: GET/read endpoints use read; POST mutating/setup/sync endpoints use update.
  • Added missing action-layer checks in packages/integrations/src/actions/integrations/entraActions.ts: getEntraIntegrationStatus, getEntraMappingPreview, getEntraSyncRunHistory, and getEntraReconciliationQueue require system_settings.read; connectEntraIntegration requires system_settings.update.
  • Validation commands: npx tsc --noEmit -p packages/integrations/tsconfig.json, npx tsc --noEmit -p ee/server/tsconfig.json, and npx tsc --noEmit -p server/tsconfig.json (pass).
  • (2026-02-20) F120 completed: added EE usage guide ee/docs/guides/entra-integration-phase-1.md covering setup and operating model.
  • Documentation now includes: direct vs CIPP connection decision guidance, canonical secret names, secret-provider/vault compatibility note, mapping/discovery/sync workflow, additive/non-destructive sync behavior with field-sync toggles, and phased feature-flag rollout order for pilot tenants.
  • Included platform feature-flag API examples for ensuring Phase 1 flags and tenant-targeting additions.
  • (2026-02-20) T001 completed: added CE delegator route test server/src/test/unit/api/entraRoutes.delegator.test.ts covering non-enterprise behavior.
  • Test verifies CE Entra delegator routes return the expected EE-only 501 payload when enterprise edition is disabled (GET /entra, POST /entra/connect, GET /entra/sync/runs).
  • Validation command: cd server && npx vitest run src/test/unit/api/entraRoutes.delegator.test.ts (pass).
  • (2026-02-20) T002 completed: extended CE delegator test (server/src/test/unit/api/entraRoutes.delegator.test.ts) to validate enterprise forwarding.
  • Test now enables EE env, mocks @enterprise/app/api/integrations/entra/route + /connect/route, and asserts CE routes forward requests and preserve EE handler responses/status codes.
  • Validation command: cd server && npx vitest run src/test/unit/api/entraRoutes.delegator.test.ts (pass).
  • (2026-02-20) T003 completed: added compile-contract file packages/integrations/src/actions/entraActions.barrel.typecheck.ts to assert Entra actions/types are re-exported from actions/index.ts with matching signatures to integrations/entraActions.ts.
  • The contract verifies function and type alias parity (EntraConnectionType, EntraSyncScope) through TypeScript assignability checks.
  • Validation command: npx tsc --noEmit -p packages/integrations/tsconfig.json (pass).
  • (2026-02-20) T004 completed: added jsdom UI test server/src/test/unit/components/integrations/IntegrationsSettingsPage.entra.test.tsx for Entra entry placement in EE mode.
  • Test setup mocks tabs + feature flag/search params to select Identity category and asserts the Entra identity section includes the Entra settings entry loading card (Loading Entra integration settings...).
  • Added Vitest alias stub for @product/billing/entry in server/vitest.config.ts plus stub module server/src/test/stubs/product-billing-entry.tsx to keep settings-page imports resolvable during unit tests.
  • Validation command: cd server && npx vitest run src/test/unit/components/integrations/IntegrationsSettingsPage.entra.test.tsx (pass).
  • (2026-02-20) T005 completed: added dynamic target import test server/src/test/unit/components/integrations/EntraIntegrationSettings.dynamicImport.test.tsx.
  • Test validates the @enterprise/components/settings/integrations/EntraIntegrationSettings module imports successfully (the same dynamic path used by settings page) and renders its base shell content.
  • Validation command: cd server && npx vitest run src/test/unit/components/integrations/EntraIntegrationSettings.dynamicImport.test.tsx (pass).
  • (2026-02-20) T006 completed: expanded server/src/test/unit/components/integrations/IntegrationsSettingsPage.entra.test.tsx with a flag-off scenario.
  • With useFeatureFlag('entra-integration-ui') mocked disabled, test confirms the Identity/Entra integration surface is absent from integrations settings UI.
  • Validation command: cd server && npx vitest run src/test/unit/components/integrations/IntegrationsSettingsPage.entra.test.tsx (pass).
  • (2026-02-20) T007 completed: expanded server/src/test/unit/components/integrations/IntegrationsSettingsPage.entra.test.tsx with a flag-on scenario.
  • With useFeatureFlag('entra-integration-ui') mocked enabled, test confirms the Entra settings surface renders in Identity section (accepting either loading card text or loaded shell).
  • Validation command: cd server && npx vitest run src/test/unit/components/integrations/IntegrationsSettingsPage.entra.test.tsx (pass).
  • (2026-02-20) T008 completed: extracted shouldShowEntraSyncAction(...) helper in packages/clients/src/components/clients/clientDetailsEntraSyncAction.ts and wired ClientDetails to use it for Entra client-action visibility gating.
  • Added unit test packages/clients/src/components/clients/clientDetailsEntraSyncAction.test.ts verifying the Entra client action is hidden when entra-integration-client-sync-action is disabled.
  • Validation commands: cd packages/clients && npx vitest run src/components/clients/clientDetailsEntraSyncAction.test.ts and npx tsc --noEmit -p packages/clients/tsconfig.json (pass).
  • (2026-02-20) T009 completed: extracted Entra settings gate helpers in ee/server/src/components/settings/integrations/entraIntegrationSettingsGates.ts and wired EntraIntegrationSettings to use helper-based connection option composition.
  • Added test server/src/test/unit/components/integrations/entraIntegrationSettingsGates.test.ts asserting CIPP option is omitted when entra-integration-cipp is disabled and included when enabled.
  • Validation commands: cd server && npx vitest run src/test/unit/components/integrations/entraIntegrationSettingsGates.test.ts and npx tsc --noEmit -p ee/server/tsconfig.json (pass).
  • (2026-02-20) T010 completed: extended entraIntegrationSettingsGates test coverage to verify shouldShowFieldSyncControls(false) and shouldShowAmbiguousQueue(false) both return false.
  • This covers the advanced Entra UI gating behavior for field-sync and ambiguous-queue sections when their flags are disabled.
  • Validation command: cd server && npx vitest run src/test/unit/components/integrations/entraIntegrationSettingsGates.test.ts (pass).
  • (2026-02-20) T011 completed: added migration coverage file server/src/test/unit/migrations/entraPhase1Migration.test.ts with table/column assertions for entra_partner_connections.
  • Test validates required Entra partner-connection columns and defaults exist in ee/server/migrations/20260220143000_create_entra_phase1_schema.cjs.
  • Validation command: cd server && npx vitest run src/test/unit/migrations/entraPhase1Migration.test.ts (pass).
  • (2026-02-20) T012 completed: extended entraPhase1Migration.test.ts to assert the partial unique index enforcing one active partner connection per tenant.
  • Validation command: cd server && npx vitest run src/test/unit/migrations/entraPhase1Migration.test.ts (pass).
  • (2026-02-20) T013 completed: extended entraPhase1Migration.test.ts with entra_managed_tenants table/column checks plus discovery/matching index assertions.
  • Validation command: cd server && npx vitest run src/test/unit/migrations/entraPhase1Migration.test.ts (pass).
  • (2026-02-20) T014 completed: extended migration tests for entra_client_tenant_mappings table and unique-active mapping constraint index (ux_entra_client_tenant_mappings_active).
  • Validation command: cd server && npx vitest run src/test/unit/migrations/entraPhase1Migration.test.ts (pass).
  • (2026-02-20) T015 completed: added migration assertions for entra_sync_settings defaults (sync_enabled=true, sync_interval_minutes=1440) and JSON config fields/index.
  • Validation command: cd server && npx vitest run src/test/unit/migrations/entraPhase1Migration.test.ts (pass).
  • (2026-02-20) T016 completed: extended migration coverage for entra_sync_runs status defaults and summary counters (total/processed/succeeded/failed).
  • Validation command: cd server && npx vitest run src/test/unit/migrations/entraPhase1Migration.test.ts (pass).
  • (2026-02-20) T017 completed: extended migration coverage for entra_sync_run_tenants and tenant-scoped FK linkage to parent entra_sync_runs.
  • Validation command: cd server && npx vitest run src/test/unit/migrations/entraPhase1Migration.test.ts (pass).
  • (2026-02-20) T018 completed: extended migration coverage for entra_contact_links and its unique Entra identity index (tenant, entra_tenant_id, entra_object_id).
  • Validation command: cd server && npx vitest run src/test/unit/migrations/entraPhase1Migration.test.ts (pass).
  • (2026-02-20) T019 completed: extended migration coverage for the partial unique index enforcing one active Entra link per contact (ux_entra_contact_links_active_contact).
  • Validation command: cd server && npx vitest run src/test/unit/migrations/entraPhase1Migration.test.ts (pass).
  • (2026-02-20) T020 completed: extended migration coverage for entra_contact_reconciliation_queue table defaults and status/identity lookup indexes.
  • Validation command: cd server && npx vitest run src/test/unit/migrations/entraPhase1Migration.test.ts (pass).
  • (2026-02-20) T021 completed: extended migration coverage for clients.entra_tenant_id / clients.entra_primary_domain columns and idx_clients_entra_tenant.
  • Validation command: cd server && npx vitest run src/test/unit/migrations/entraPhase1Migration.test.ts (pass).
  • (2026-02-20) T022 completed: extended migration coverage for all Entra contact identity/sync metadata columns (entra_object_id, sync source/status fields, account-enabled flag, and last sync timestamp).
  • Validation command: cd server && npx vitest run src/test/unit/migrations/entraPhase1Migration.test.ts (pass).
  • (2026-02-20) T023 completed: extended migration coverage for tenant backfill of default entra_sync_settings rows (INSERT ... SELECT FROM tenants WHERE NOT EXISTS).
  • Validation command: cd server && npx vitest run src/test/unit/migrations/entraPhase1Migration.test.ts (pass).
  • (2026-02-20) T024 completed: added interface/schema alignment test server/src/test/unit/integrations/entraInterfacesSchemaAlignment.test.ts.
  • Test validates Entra row mappers produce all typed interface shapes and cross-checks representative interface-backed columns against migration schema text.
  • Validation command: cd server && npx vitest run src/test/unit/integrations/entraInterfacesSchemaAlignment.test.ts (pass).
  • (2026-02-20) T025 completed: added server/src/test/unit/integrations/entraMappingValidation.test.ts for duplicate managed-tenant assignment conflict detection.
  • Validation command: cd server && npx vitest run src/test/unit/integrations/entraMappingValidation.test.ts (pass).
  • (2026-02-20) T026 completed: added route contract test server/src/test/unit/api/entraMappingAndDisconnectContracts.test.ts asserting unmap path deactivates/reinserts mapping state and does not touch sync run history tables.
  • Validation command: cd server && npx vitest run src/test/unit/api/entraMappingAndDisconnectContracts.test.ts (pass).
  • (2026-02-20) T027 completed: extended route contract coverage to assert remap delegates mappingState='mapped' to confirm service and that confirm service updates client Entra linkage fields.
  • Validation command: cd server && npx vitest run src/test/unit/api/entraMappingAndDisconnectContracts.test.ts (pass).
  • (2026-02-20) T028 completed: extended route contract coverage for disconnect path to assert credential clearing + connection status update without touching sync history tables.
  • Validation command: cd server && npx vitest run src/test/unit/api/entraMappingAndDisconnectContracts.test.ts (pass).
  • (2026-02-20) T029 completed: extended migration coverage to assert Entra contact metadata columns are added via ensureColumn definitions without new non-null constraints.
  • Validation command: cd server && npx vitest run src/test/unit/migrations/entraPhase1Migration.test.ts (pass).
  • (2026-02-20) T030 completed: added query/index alignment regression test server/src/test/unit/integrations/entraMappingQueryIndexAlignment.test.ts.
  • Test enforces tenant-scoped managed-tenant preview query shape and active mapping lookup predicates that align with migration indexes (idx_entra_managed_tenants_*, ux_entra_client_tenant_mappings_active).
  • Validation command: cd server && npx vitest run src/test/unit/integrations/entraMappingQueryIndexAlignment.test.ts (pass).
  • (2026-02-20) T031 completed: added action permission unit test server/src/test/unit/integrations/entraActions.directConnect.test.ts for initiateEntraDirectOAuth.
  • Test asserts callers lacking system_settings.update receive explicit forbidden response and verifies RBAC check invocation.
  • Validation command: cd server && npx vitest run src/test/unit/integrations/entraActions.directConnect.test.ts (pass).
  • (2026-02-20) T032 completed: extended server/src/test/unit/integrations/entraActions.directConnect.test.ts with success-path OAuth initiation assertions.
  • Test validates returned auth URL shape and verifies base64 state payload includes tenant/user, nonce, timestamp, and Entra direct integration markers.
  • Validation command: cd server && npx vitest run src/test/unit/integrations/entraActions.directConnect.test.ts (pass).
  • (2026-02-20) T033 completed: added EE callback validation test ee/server/src/__tests__/unit/entraOAuthCallback.validation.test.ts covering missing params and invalid state payload handling.
  • Added NextResponse.redirect(...) support to shared Next.js test stub (server/src/test/stubs/next-server.ts) so callback routes can be asserted via redirect location headers in unit tests.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraOAuthCallback.validation.test.ts (pass).
  • (2026-02-20) T034 completed: extended EE callback unit test to cover successful token exchange and connection activation flow.
  • Assertions verify callback writes direct token references via saveEntraDirectTokenSet(...), deactivates prior active connection rows, and inserts a new active direct partner connection record.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraOAuthCallback.validation.test.ts (pass).
  • (2026-02-20) T035 completed: added ee/server/src/__tests__/unit/entraDirectTokenRefresh.test.ts for direct refresh persistence behavior.
  • Test freezes time and verifies refreshed access token + computed expiry timestamp are persisted through saveEntraDirectTokenSet(...) after token endpoint response.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraDirectTokenRefresh.test.ts (pass).
  • (2026-02-20) T036 completed: extended server/src/test/unit/integrations/entraActions.directConnect.test.ts with CIPP base-URL validation coverage.
  • Test verifies invalid CIPP URL input is rejected with explicit validation error before credential cleanup/persistence side effects.
  • Validation command: cd server && npx vitest run src/test/unit/integrations/entraActions.directConnect.test.ts (pass).
  • (2026-02-20) T037 completed: expanded CIPP connect action tests to validate secret storage behavior.
  • Success-path test verifies API token is saved via saveEntraCippCredentials(...) and DB insert stores only token_secret_ref='entra_cipp' (no plaintext token value).
  • Validation command: cd server && npx vitest run src/test/unit/integrations/entraActions.directConnect.test.ts (pass).
  • (2026-02-20) T038 completed: added EE route unit test ee/server/src/__tests__/unit/entraValidateDirectRoute.test.ts for direct validation success path.
  • Test verifies valid credential/token context yields managed-tenant probe success, returns valid=true, and updates connection validation status to connected.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraValidateDirectRoute.test.ts (pass).
  • (2026-02-20) T039 completed: added EE route unit test ee/server/src/__tests__/unit/entraValidateCippRoute.test.ts for CIPP validation success path.
  • Test verifies successful tenant endpoint probe with valid CIPP token returns valid=true/tenant sample count and marks connection validation status connected.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraValidateCippRoute.test.ts (pass).
  • (2026-02-20) T040 completed: added EE disconnect route unit test ee/server/src/__tests__/unit/entraDisconnectRoute.test.ts.
  • Test verifies both provider secret clear operations execute and active connection is marked disconnected (disconnectActiveEntraConnection) with expected response payload.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraDisconnectRoute.test.ts (pass).
  • (2026-02-20) T041 completed: expanded Entra action tests for connection-type switching cleanup behavior.
  • Test verifies direct initiation clears stale CIPP credentials and CIPP connect clears stale direct token secrets before persisting new mode configuration.
  • Validation command: cd server && npx vitest run src/test/unit/integrations/entraActions.directConnect.test.ts (pass).
  • (2026-02-20) T042 completed: added resolver precedence unit coverage in ee/server/src/__tests__/unit/microsoftCredentialResolver.precedence.test.ts.
  • Tenant-secret preference case asserts tenant credential pair is selected over env/app fallbacks when present.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/microsoftCredentialResolver.precedence.test.ts (pass).
  • (2026-02-20) T043 completed within microsoftCredentialResolver.precedence tests.
  • Env-fallback case asserts resolver returns env credentials when tenant secret pair is absent and does not query app-secret fallback.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/microsoftCredentialResolver.precedence.test.ts (pass).
  • (2026-02-20) T044 completed within microsoftCredentialResolver.precedence tests.
  • App-secret fallback case asserts resolver returns app-secret credentials when neither tenant secrets nor env credentials are available.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/microsoftCredentialResolver.precedence.test.ts (pass).
  • (2026-02-20) T045 completed: added ee/server/src/__tests__/unit/entraSecretKeys.test.ts validating canonical Entra secret key constants.
  • Test verifies shared/direct/CIPP secret key names are stable and fully represented exactly once in ENTRA_ALL_SECRET_KEYS.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraSecretKeys.test.ts (pass).
  • (2026-02-20) T046 completed: added provider-factory unit coverage in ee/server/src/__tests__/unit/entraProviderFactory.test.ts.
  • Direct selection case asserts getEntraProviderAdapter('direct') delegates to createDirectProviderAdapter() and returns its adapter instance.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraProviderFactory.test.ts (pass).
  • (2026-02-20) T047 completed in entraProviderFactory tests.
  • CIPP selection case asserts getEntraProviderAdapter('cipp') delegates to createCippProviderAdapter() and returns its adapter instance.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraProviderFactory.test.ts (pass).
  • (2026-02-20) T048 completed: added direct adapter normalization tests in ee/server/src/__tests__/unit/directProviderAdapter.normalization.test.ts.
  • Managed-tenant case verifies Graph payload normalization into canonical fields (entraTenantId, displayName, primaryDomain, sourceUserCount).
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/directProviderAdapter.normalization.test.ts (pass).
  • (2026-02-20) T049 completed in direct adapter normalization tests.
  • User-list case verifies canonical sync-user mapping (UPN/email fallback, trimmed identity fields, boolean normalization, and business phone filtering).
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/directProviderAdapter.normalization.test.ts (pass).
  • (2026-02-20) T050 completed: added CIPP adapter normalization coverage in ee/server/src/__tests__/unit/cippProviderAdapter.normalization.test.ts.
  • Tenant-list case verifies CIPP tenant payloads normalize into canonical managed-tenant DTO fields with expected auth header usage.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/cippProviderAdapter.normalization.test.ts (pass).
  • (2026-02-20) T051 completed in CIPP adapter normalization tests.
  • User-list case verifies canonical sync-user normalization (identity fields, booleans, trimmed strings, and phone filtering) for CIPP responses.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/cippProviderAdapter.normalization.test.ts (pass).
  • (2026-02-20) T052 completed: added discovery upsert unit coverage in ee/server/src/__tests__/unit/entraDiscoveryService.upsert.test.ts.
  • Test verifies discovery persists managed-tenant rows via tenant-scoped upsert (onConflict(['tenant','entra_tenant_id']).merge(...)) and returns idempotent discovered tenant results.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraDiscoveryService.upsert.test.ts (pass).
  • (2026-02-20) T053 completed in ee/server/src/__tests__/unit/entraDiscoveryService.upsert.test.ts.
  • Merge-update case asserts discovery upsert writes display_name and primary_domain from EXCLUDED values, covering changed tenant metadata refresh behavior.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraDiscoveryService.upsert.test.ts (pass).
  • (2026-02-20) T054 completed in ee/server/src/__tests__/unit/entraDiscoveryService.upsert.test.ts.
  • Source-user-count coverage asserts discovery writes source_user_count on insert rows and merge updates so provider-reported tenant user totals stay current.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraDiscoveryService.upsert.test.ts (pass).
  • (2026-02-20) T055 completed: added mapping preview unit suite ee/server/src/__tests__/unit/entraMappingPreviewService.test.ts.
  • Exact-domain case asserts a single exact domain match is surfaced in autoMatched with reason='exact_domain' and no fuzzy/unmatched spillover.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraMappingPreviewService.test.ts (pass).
  • (2026-02-20) T056 completed in entraMappingPreviewService unit suite.
  • Secondary-domain case asserts candidate generation uses reason='secondary_domain' and confidence score 0.88 for non-primary domain matches.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraMappingPreviewService.test.ts (pass).
  • (2026-02-20) T057 completed in entraMappingPreviewService unit suite.
  • Fuzzy candidate case verifies candidates are score-sorted descending and remain non-auto-confirmed (autoMatch=false), ensuring fuzzy suggestions never silently map.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraMappingPreviewService.test.ts (pass).
  • (2026-02-20) T058 completed in entraMappingPreviewService unit suite.
  • No-match case confirms tenants are returned in unmatched when neither domain nor fuzzy thresholds produce candidates.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraMappingPreviewService.test.ts (pass).
  • (2026-02-20) T059 completed: added jsdom component test ee/server/src/__tests__/unit/entraTenantMappingTable.selection.test.tsx.
  • Test renders EntraTenantMappingTable, loads fuzzy + unmatched preview rows, and verifies client selection updates both row comboboxes (needs_review and unmatched) with mapped summary callback updates.
  • Added EE Vitest alias coverage for @alga-psa/integrations/* and @alga-psa/clients/* in ee/server/vitest.config.ts so component imports resolve consistently in unit tests.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraTenantMappingTable.selection.test.tsx (pass).
  • (2026-02-20) T060 completed: extended server/src/test/unit/integrations/entraActions.directConnect.test.ts with skip-mapping action coverage.
  • Test validates skipEntraTenantMapping deactivates prior active rows, inserts active skip_for_now row with client_id: null, and returns expected skip state payload (no active client mapping created).
  • Validation command: cd server && npx vitest run src/test/unit/integrations/entraActions.directConnect.test.ts (pass).
  • (2026-02-20) T061 completed in ee/server/src/__tests__/unit/entraTenantMappingTable.selection.test.tsx.
  • Bulk preselect test clicks Preselect Exact Matches and verifies each auto_matched row select is populated with its exact-domain candidate client ID.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraTenantMappingTable.selection.test.tsx (pass).
  • (2026-02-20) T062 completed: extended server/src/test/unit/api/entraMappingAndDisconnectContracts.test.ts with confirm/preview write-path contract assertions.
  • Coverage asserts confirm route only processes explicit body.mappings input and confirm service iterates params.mappings; preview route remains read-only (buildEntraMappingPreview only, no insert/update).
  • Validation command: cd server && npx vitest run src/test/unit/api/entraMappingAndDisconnectContracts.test.ts (pass).
  • (2026-02-20) T063 completed: added service-level unit test ee/server/src/__tests__/unit/confirmEntraMappingsService.clientLink.test.ts.
  • Test executes confirmEntraMappings with a mapped selection and verifies client row update writes entra_tenant_id + entra_primary_domain from managed-tenant lookup.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/confirmEntraMappingsService.clientLink.test.ts (pass).
  • (2026-02-20) T064 completed in confirmEntraMappingsService.clientLink unit suite.
  • Remap scenario asserts existing active mapping is deactivated (is_active=false) before inserting one new active mapped row for the target client.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/confirmEntraMappingsService.clientLink.test.ts (pass).
  • (2026-02-20) T065 completed: expanded entraTenantMappingTable.selection component tests with summary counter assertions.
  • Mixed-state scenario verifies onSummaryChange transitions from {mapped:1, skipped:0, needsReview:1} to {mapped:1, skipped:1, needsReview:0} after skip action.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraTenantMappingTable.selection.test.tsx (pass).
  • (2026-02-20) T066 completed: added ee/server/src/__tests__/unit/entraIntegrationSettings.initialSyncCta.test.tsx.
  • jsdom test mocks feature flags/status actions and asserts Run Initial Sync remains disabled when mappedTenantCount=0.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraIntegrationSettings.initialSyncCta.test.tsx (pass).
  • (2026-02-20) T067 completed in entraIntegrationSettings.initialSyncCta unit suite.
  • Mocked mapping-table callback state drives skipped-tenant panel rendering; test verifies skipped entries appear with Remap controls.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraIntegrationSettings.initialSyncCta.test.tsx (pass).
  • (2026-02-20) T068 completed in entraIntegrationSettings.initialSyncCta tests.
  • Flag-off scenario verifies disabled-state messaging renders while wizard content (Map Tenants to Clients) and sync CTA controls are absent.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraIntegrationSettings.initialSyncCta.test.tsx (pass).
  • (2026-02-20) T069 completed: added Entra Temporal type-contract test server/src/test/unit/temporal/entraTemporalTypeContracts.test.ts and tightened Entra activity typing.
  • Removed any leak in ee/temporal-workflows/src/activities/entra-sync-activities.ts by introducing typed row mapping; discovery workflow/activity now consume shared types/entra-sync interfaces (DiscoverManagedTenants*, EntraDiscoveryWorkflowResult).
  • Validation commands: cd server && npx vitest run src/test/unit/temporal/entraTemporalTypeContracts.test.ts --coverage.enabled=false (pass), cd ee/temporal-workflows && npm run type-check (pass).
  • (2026-02-20) T070 completed: added Temporal contract suite server/src/test/unit/temporal/entraWorkflowActivityContracts.test.ts.
  • Discovery workflow assertion verifies start-log -> discoverManagedTenantsActivity -> completion-log ordering.
  • Validation command: cd server && npx vitest run src/test/unit/temporal/entraWorkflowActivityContracts.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T071 completed in Temporal workflow/activity contract suite.
  • Initial-sync assertion verifies mapped-tenant load precedes per-tenant loop and tenant sync activity invocation.
  • Validation command: cd server && npx vitest run src/test/unit/temporal/entraWorkflowActivityContracts.test.ts --coverage.enabled=false (pass). EOF && git add ee/docs/plans/2026-02-20-entra-integration-phase-1/tests.json ee/docs/plans/2026-02-20-entra-integration-phase-1/SCRATCHPAD.md && git commit -m "test(T071): verify initial-sync workflow load-and-process order"- (2026-02-20) T072 completed in Temporal workflow/activity contract suite.
  • Tenant-sync assertion verifies workflow filters selected mapping by requested managedTenantId and optional clientId scope before processing.
  • Validation command: cd server && npx vitest run src/test/unit/temporal/entraWorkflowActivityContracts.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T073 completed in Temporal workflow/activity contract suite.
  • All-tenants workflow assertion verifies it loads mapped tenants and iterates mappedTenants.mappings for per-tenant sync execution.
  • Validation command: cd server && npx vitest run src/test/unit/temporal/entraWorkflowActivityContracts.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T074 completed in Temporal workflow/activity contract suite.
  • Upsert-run activity assertions verify parent sync run writes include initiating user attribution and run mode fields (run_type, initiated_by).
  • Validation command: cd server && npx vitest run src/test/unit/temporal/entraWorkflowActivityContracts.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T075 completed in Temporal workflow/activity contract suite.
  • Record-tenant-result assertions verify per-tenant run row persistence includes status + all sync counters (created/linked/updated/ambiguous/inactivated).
  • Validation command: cd server && npx vitest run src/test/unit/temporal/entraWorkflowActivityContracts.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T076 completed in Temporal workflow/activity contract suite.
  • Finalize-run assertions verify terminal status and summary totals are written back to parent entra_sync_runs rows.
  • Validation command: cd server && npx vitest run src/test/unit/temporal/entraWorkflowActivityContracts.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T077 completed in Temporal workflow/activity contract suite.
  • Workflow index assertions verify Entra workflow exports are present in ee/temporal-workflows/src/workflows/index.ts for worker registration.
  • Validation command: cd server && npx vitest run src/test/unit/temporal/entraWorkflowActivityContracts.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T078 completed in Temporal workflow/activity contract suite.
  • Activity index assertions verify Entra activity exports are present in ee/temporal-workflows/src/activities/index.ts for worker registration.
  • Validation command: cd server && npx vitest run src/test/unit/temporal/entraWorkflowActivityContracts.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T079 completed: added workflow-client start tests in ee/server/src/__tests__/unit/entraWorkflowClient.start.test.ts.
  • Initial-sync case verifies Temporal start wrapper returns available=true with workflow/run IDs and generates the expected initial-sync workflow-id prefix.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraWorkflowClient.start.test.ts (pass).
  • (2026-02-20) T080 completed in entraWorkflowClient.start unit suite.
  • All-tenants case verifies Temporal start wrapper returns workflow/run IDs and includes trigger-scoped all-tenants workflow-id prefix.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraWorkflowClient.start.test.ts (pass).
  • (2026-02-20) T081 completed in entraWorkflowClient.start unit suite.
  • Single-tenant case verifies Temporal start wrapper returns workflow/run IDs and composes tenant+managed-tenant+client workflow-id prefix.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraWorkflowClient.start.test.ts (pass).
  • (2026-02-20) T082 completed: added route unit test ee/server/src/__tests__/unit/entraSyncRunProgressRoute.test.ts.
  • Test verifies sync run polling endpoint returns serialized run-level status plus tenant-level result rows and calls workflow progress reader with tenant-scoped context.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraSyncRunProgressRoute.test.ts (pass).
  • (2026-02-20) T083 completed: added contract test server/src/test/unit/integrations/entraConfirmMappingsInitialSyncContract.test.ts.
  • Test verifies confirmEntraMappings optional-start branch, workflow trigger invocation path, and response payload propagation of initialSync.workflowId/runId.
  • Validation commands: cd server && npx vitest run src/test/unit/integrations/entraConfirmMappingsInitialSyncContract.test.ts --coverage.enabled=false (pass), cd server && npx vitest run src/test/unit/integrations/entraActions.directConnect.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T084 completed: added server/src/test/unit/integrations/entraActions.startSync.test.ts.
  • All-tenants case verifies manual startEntraSync({scope:'all-tenants'}) dispatches startEntraAllTenantsSyncWorkflow with trigger=manual and returns workflow/run IDs.
  • Validation command: cd server && npx vitest run src/test/unit/integrations/entraActions.startSync.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T085 completed in entraActions.startSync unit suite.
  • Single-client case verifies startEntraSync({scope:'single-client'}) resolves mapped tenant context then dispatches startEntraTenantSyncWorkflow with expected identifiers.
  • Validation command: cd server && npx vitest run src/test/unit/integrations/entraActions.startSync.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T086 completed in Temporal workflow/activity contract suite.
  • Schedule assertions verify tenant-scoped Entra recurring schedule creation path for enabled tenants with active connections, using scheduled all-tenants workflow trigger config.
  • Validation command: cd server && npx vitest run src/test/unit/temporal/entraWorkflowActivityContracts.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T087 completed in Temporal workflow/activity contract suite.
  • upsertSchedule assertions verify already-existing schedules are updated via handle.update(...) with refreshed spec/action/policy definitions.
  • Validation command: cd server && npx vitest run src/test/unit/temporal/entraWorkflowActivityContracts.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T088 completed in entraWorkflowClient.start unit suite.
  • Added collision test verifying repeated manual trigger inputs generate identical workflow IDs and that WorkflowExecutionAlreadyStartedError resolves to existing run identifiers via handle describe.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraWorkflowClient.start.test.ts (pass).
  • (2026-02-20) T089 completed in Temporal workflow/activity contract suite.
  • Added no-mapped-tenant assertions for initial/all-tenants workflows to ensure zero-initialized summaries and completed status path when nothing is processed.
  • Validation command: cd server && npx vitest run src/test/unit/temporal/entraWorkflowActivityContracts.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T090 completed in Temporal workflow/activity contract suite.
  • Failure-path assertions verify per-tenant catch blocks emit failed tenant results and parent run status rolls up to partial/failed according to succeeded-vs-failed counts.
  • Validation command: cd server && npx vitest run src/test/unit/temporal/entraWorkflowActivityContracts.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T091 completed: added user-filter pipeline unit suite ee/server/src/__tests__/unit/entraUserFilterPipeline.test.ts.
  • Disabled-user case verifies accountEnabled=false identities are excluded with reason account_disabled.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraUserFilterPipeline.test.ts (pass).
  • (2026-02-20) T092 completed in entraUserFilterPipeline suite.
  • Missing-identity case verifies users without valid UPN/email identities are excluded with missing_identity reason.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraUserFilterPipeline.test.ts (pass).
  • (2026-02-20) T093 completed in entraUserFilterPipeline suite.
  • Default service-account pattern case verifies identities like svc-* are filtered from sync candidates with service_account reason.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraUserFilterPipeline.test.ts (pass).
  • (2026-02-20) T094 completed in entraUserFilterPipeline suite.
  • Tenant custom pattern case verifies configured exclusions are applied on top of defaults and produce tenant_custom_pattern filtered results.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraUserFilterPipeline.test.ts (pass).
  • (2026-02-20) T095 completed: added reconciler/matcher unit suites (ee/server/src/__tests__/unit/entraContactReconciler.test.ts, ee/server/src/__tests__/unit/entraContactMatcher.noEmailAutoLink.test.ts).
  • Exact-email-match case verifies reconcile flow links existing contact and avoids duplicate contact creation.
  • Validation commands: cd ee/server && npx vitest run src/__tests__/unit/entraContactReconciler.test.ts (pass), cd ee/server && npx vitest run src/__tests__/unit/entraContactMatcher.noEmailAutoLink.test.ts (pass).
  • (2026-02-20) T096 completed in entraContactReconciler unit suite.
  • No-match case verifies reconcile flow creates a new contact under the mapped client before linking Entra identity metadata.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraContactReconciler.test.ts (pass).
  • (2026-02-20) T097 completed in entraContactReconciler unit suite.
  • Ambiguous-match case verifies multiple candidates queue reconciliation items instead of auto-linking/creation.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraContactReconciler.test.ts (pass).
  • (2026-02-20) T098 completed in entraContactMatcher.noEmailAutoLink test.
  • Name-only identity case verifies missing valid email/UPN cannot auto-link contacts.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraContactMatcher.noEmailAutoLink.test.ts (pass).
  • (2026-02-20) T099 completed in entraContactReconciler unit suite.
  • Metadata-write assertions verify contact update patches include Entra identity/source fields during link/create reconciliation paths.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraContactReconciler.test.ts (pass).
  • (2026-02-20) T100 completed: added ee/server/src/__tests__/unit/entraContactFieldSync.test.ts.
  • Toggle-off case verifies displayName=false prevents full_name overwrite patch generation.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraContactFieldSync.test.ts (pass).
  • (2026-02-20) T101 completed in entraContactFieldSync test suite.
  • Toggle-on case verifies displayName=true includes full_name overwrite patch from Entra display name.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraContactFieldSync.test.ts (pass).
  • (2026-02-20) T102 completed in entraContactFieldSync test suite.
  • Toggle-on UPN case verifies upn=true includes entra_user_principal_name overwrite patch generation for linked contacts.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraContactFieldSync.test.ts (pass).
  • (2026-02-20) T103 completed: added ee/server/src/__tests__/unit/entraDisableHandler.test.ts.
  • Disabled-user handling assertion verifies linked contacts are marked inactive with entra_sync_status_reason='disabled_upstream' and link status is set inactive.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraDisableHandler.test.ts (pass).
  • (2026-02-20) T104 completed in ee/server/src/__tests__/unit/entraDisableHandler.test.ts.
  • Deleted-user handling assertion verifies linked contacts are marked inactive with entra_sync_status_reason='deleted_upstream'.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraDisableHandler.test.ts (pass).
  • (2026-02-20) T105 completed in ee/server/src/__tests__/unit/entraDisableHandler.test.ts.
  • Non-destructive handling assertion verifies disabled/deleted paths only issue update operations and never delete contact or link rows.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraDisableHandler.test.ts (pass).
  • (2026-02-20) T106 completed in ee/server/src/__tests__/unit/entraContactReconciler.test.ts.
  • Added assertions for both linked and created reconcile paths to verify last_entra_sync_at is refreshed on every processed contact row.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraContactReconciler.test.ts (pass).
  • (2026-02-20) T107 completed: added ee/server/src/__tests__/unit/entraContactLinkRepository.test.ts.
  • Upsert contract assertions verify link rows refresh last_seen_at and remain link_status='active'/is_active=true on each sync merge.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraContactLinkRepository.test.ts (pass).
  • (2026-02-20) T108 completed: added ee/server/src/__tests__/unit/entraSyncResultAggregator.test.ts.
  • Created-counter assertions verify aggregation correctness across increment + add, and ignore non-positive deltas.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraSyncResultAggregator.test.ts (pass).
  • (2026-02-20) T109 completed in ee/server/src/__tests__/unit/entraSyncResultAggregator.test.ts.
  • Linked-counter assertions verify accurate totals from increment and add, while ignoring invalid numeric deltas.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraSyncResultAggregator.test.ts (pass).
  • (2026-02-20) T110 completed in ee/server/src/__tests__/unit/entraSyncResultAggregator.test.ts.
  • Ambiguous-counter assertions verify per-tenant accumulation semantics and counter isolation from unrelated totals.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraSyncResultAggregator.test.ts (pass).
  • (2026-02-20) T111 completed: added ee/server/src/__tests__/unit/entraSyncEngine.dryRun.test.ts.
  • Dry-run engine assertions verify ambiguous/linked/created preview counters while ensuring no write-path reconciliation methods execute.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraSyncEngine.dryRun.test.ts (pass).
  • (2026-02-20) T112 completed: added ee/server/src/__tests__/unit/entraSyncResultSerializer.test.ts.
  • Serializer stability assertions compare key-shape parity for success vs failure runs and verify numeric/null normalization for tenant result DTOs.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraSyncResultSerializer.test.ts (pass).
  • (2026-02-20) T113 completed in ee/server/src/__tests__/unit/entraContactLinkRepository.test.ts.
  • Retry/idempotency assertion uses a conflict-aware fake transaction store to verify repeated sync upserts keep one row per (tenant,entra_tenant_id,entra_object_id) identity key.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraContactLinkRepository.test.ts (pass).
  • (2026-02-20) T114 completed in ee/server/src/__tests__/unit/entraContactReconciler.test.ts.
  • Retry-idempotency case simulates two sync passes for the same Entra identity and verifies only one contact is created; second pass links existing contact.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraContactReconciler.test.ts (pass).
  • (2026-02-20) T115 completed: added ee/server/src/__tests__/unit/entraReconciliationQueueService.queue.test.ts.
  • Queue insert assertions validate tenant/client/managed-tenant context plus serialized candidate-contact details and ambiguity payload (reason, candidateCount).
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraReconciliationQueueService.queue.test.ts (pass).
  • (2026-02-20) T116 completed: added ee/server/src/__tests__/unit/entraReconciliationQueueService.resolve.test.ts.
  • Resolve-to-existing assertions verify Entra identity linking and queue state transition to resolved with resolution_action='link_existing'.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraReconciliationQueueService.resolve.test.ts (pass).
  • (2026-02-20) T117 completed in ee/server/src/__tests__/unit/entraReconciliationQueueService.resolve.test.ts.
  • Resolve-to-new assertions verify normalized contact creation, Entra link upsert, and queue transition to resolved with resolution_action='create_new'.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraReconciliationQueueService.resolve.test.ts (pass).
  • (2026-02-20) T118 completed in ee/server/src/__tests__/unit/entraReconciliationQueueService.resolve.test.ts.
  • Guard-rail assertions verify resolve-to-existing rejects cross-client targets and rejects contacts outside tenant scope before link writes.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraReconciliationQueueService.resolve.test.ts (pass).
  • (2026-02-20) T119 completed in server/src/test/unit/integrations/entraActions.startSync.test.ts.
  • Single-client sync guard test verifies query scoping to active mapped rows for requested client and rejects workflow start when no qualifying mapping exists.
  • Validation command: cd server && npx vitest run src/test/unit/integrations/entraActions.startSync.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T120 completed in server/src/test/unit/temporal/entraWorkflowActivityContracts.test.ts.
  • Contract assertion confirms loadMappedTenantsActivity filters to active mapped rows, which excludes skip_for_now mappings from all-tenant sync.
  • Validation command: cd server && npx vitest run src/test/unit/temporal/entraWorkflowActivityContracts.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T121 completed in ee/server/src/__tests__/unit/entraIntegrationSettings.initialSyncCta.test.tsx.
  • Status-panel UI assertions verify rendering of connection state/type, last discovery, mapped tenant count, and configured sync interval text.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraIntegrationSettings.initialSyncCta.test.tsx (pass).
  • (2026-02-20) T122 completed: added ee/server/src/__tests__/unit/entraSyncHistoryPanel.test.tsx.
  • History list assertions verify run cards are rendered in descending startedAt order regardless of API return order.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraSyncHistoryPanel.test.tsx (pass).
  • (2026-02-20) T123 completed in ee/server/src/__tests__/unit/entraSyncHistoryPanel.test.tsx.
  • Drilldown test validates fetching run detail and rendering per-tenant outcome rows with created/linked/updated/ambiguous/inactivated counters.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraSyncHistoryPanel.test.tsx (pass).
  • (2026-02-20) T124 completed in ee/server/src/__tests__/unit/entraIntegrationSettings.initialSyncCta.test.tsx.
  • UI assertion verifies Sync All Tenants Now remains disabled when mappedTenantCount is zero.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraIntegrationSettings.initialSyncCta.test.tsx (pass).
  • (2026-02-20) T125 completed in ee/server/src/__tests__/unit/entraIntegrationSettings.initialSyncCta.test.tsx.
  • Complementary CTA assertion verifies Sync All Tenants Now is enabled when at least one active mapping is present.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraIntegrationSettings.initialSyncCta.test.tsx (pass).
  • (2026-02-20) T126 completed via packages/clients/src/components/clients/clientDetailsEntraSyncAction.ts and ClientDetails.tsx wiring.
  • Visibility logic now requires enterprise edition + client-sync flag + mapped client (entra_tenant_id present); unmapped clients do not see Sync Entra Now.
  • Validation command: cd packages/clients && npx vitest run src/components/clients/clientDetailsEntraSyncAction.test.ts (pass).
  • (2026-02-20) T127 completed by extending clientDetailsEntraSyncAction helpers and wiring in ClientDetails.tsx.
  • Added tested run-id state resolution (queued + polling) and terminal-status detection to keep client sync status feedback/polling behavior deterministic.
  • Validation command: cd packages/clients && npx vitest run src/components/clients/clientDetailsEntraSyncAction.test.ts (pass).
  • (2026-02-20) T128 completed in ee/server/src/__tests__/unit/entraIntegrationSettings.initialSyncCta.test.tsx.
  • Flag-gate assertion verifies ambiguous reconciliation queue panel stays hidden when entra-integration-ambiguous-queue is disabled.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraIntegrationSettings.initialSyncCta.test.tsx (pass).
  • (2026-02-20) T129 completed in ee/server/src/__tests__/unit/entraIntegrationSettings.initialSyncCta.test.tsx.
  • Complementary flag test verifies ambiguous reconciliation queue panel renders when entra-integration-ambiguous-queue is enabled.
  • Validation command: cd ee/server && npx vitest run src/__tests__/unit/entraIntegrationSettings.initialSyncCta.test.tsx (pass).
  • (2026-02-20) T130 completed in server/src/test/unit/integrations/entraActions.directConnect.test.ts.
  • Added client-portal denial assertion for Entra settings status action (Forbidden) to enforce non-internal access boundaries.
  • Validation command: cd server && npx vitest run src/test/unit/integrations/entraActions.directConnect.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T131 completed in server/src/test/unit/integrations/entraActions.startSync.test.ts.
  • Added explicit client-portal rejection assertion for manual sync action entrypoint (startEntraSync) with no workflow trigger side effects.
  • Validation command: cd server && npx vitest run src/test/unit/integrations/entraActions.startSync.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T132 completed in server/src/test/unit/integrations/entraActions.directConnect.test.ts.
  • Added read-permission denial assertions for both status and mapping-preview actions to enforce system_settings.read requirements.
  • Validation command: cd server && npx vitest run src/test/unit/integrations/entraActions.directConnect.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T133 completed across entraActions.directConnect.test.ts and entraActions.startSync.test.ts.
  • Added update-permission denial assertions for mapping confirmation and manual sync starts; direct-connect update-permission denial remains covered by T031.
  • Validation commands: cd server && npx vitest run src/test/unit/integrations/entraActions.directConnect.test.ts --coverage.enabled=false (pass), cd server && npx vitest run src/test/unit/integrations/entraActions.startSync.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T134 completed in server/src/test/unit/integrations/entraActions.directConnect.test.ts.
  • Added a full authorized-action contract flow covering direct connect, discovery route, mapping confirm (+optional initial sync start), and manual all-tenants sync start.
  • Validation command: cd server && npx vitest run src/test/unit/integrations/entraActions.directConnect.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T135 completed via docs contract test server/src/test/unit/docs/entraIntegrationGuide.contract.test.ts.
  • Verified guide includes both direct and CIPP setup paths plus explicit decision guidance for choosing connection type.
  • Validation command: cd server && npx vitest run src/test/unit/docs/entraIntegrationGuide.contract.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T136 completed in docs contract suite server/src/test/unit/docs/entraIntegrationGuide.contract.test.ts.
  • Verified documentation enumerates Entra secret names and explicitly notes secret-provider chain compatibility (env/filesystem/vault).
  • Validation command: cd server && npx vitest run src/test/unit/docs/entraIntegrationGuide.contract.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T137 completed in docs contract suite server/src/test/unit/docs/entraIntegrationGuide.contract.test.ts.
  • Confirmed guide explicitly documents additive/non-destructive sync defaults and field-sync toggle overwrite controls.
  • Validation command: cd server && npx vitest run src/test/unit/docs/entraIntegrationGuide.contract.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T138 completed in docs contract suite server/src/test/unit/docs/entraIntegrationGuide.contract.test.ts.
  • Verified documentation includes recommended feature-flag rollout ordering for pilot/internal tenants before broad enablement.
  • Validation command: cd server && npx vitest run src/test/unit/docs/entraIntegrationGuide.contract.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T139 completed in server/src/test/unit/integrations/entraActions.directConnect.test.ts.
  • Added flag-off assertion showing settings read path exits early with disabled response and does not touch Entra status/data route paths.
  • Validation command: cd server && npx vitest run src/test/unit/integrations/entraActions.directConnect.test.ts --coverage.enabled=false (pass).
  • (2026-02-20) T140 completed in packages/clients/src/components/clients/clientDetailsEntraSyncAction.test.ts.
  • Added client-flag-off contract assertion for hidden sync entrypoint and preserved run-id status representation helper behavior (non-destructive UI toggle path).
  • Validation command: cd packages/clients && npx vitest run src/components/clients/clientDetailsEntraSyncAction.test.ts (pass).