import { ContentItem } from '../../content/content.type'; /** `provider_config` (FEAT-009). Secrets encrypted at CT level (D2). ✅ */ export interface PeopleProviderConfigData { providerKey: string; providerType: 'entra' | 'github' | 'google_workspace' | 'm365' | 'scim_generic' | 'slack'; capabilities?: Record; bindingPolicy?: 'account_per_employment' | 'shared_per_person'; retryPolicy?: { maxAttempts?: number; backoffBaseSeconds?: number; respectRetryAfter?: boolean; }; healthWindowMinutes?: number; /** CT-level encrypted fields (`clientSecret`, `refreshToken`) live here; * write-only — the FE never renders secrets. Plaintext: tenantId, * clientId, endpointBase. */ connection: Record; resourcePolicies?: Array>; deprovisionRef?: string | null; /** Derived — written by `probe`. NEVER a lifecycle state. */ probeState?: { lastProbeAt?: string; lastResult?: string; latencyMs?: number; }; state: 'draft' | 'active' | 'disabled' | 'discarded'; } export type PeopleProviderConfig = ContentItem; /** `provisioning_item` (FEAT-009). Unit of Desired-State Contribution per * (employment × resource) AND unit of execution (independent per item, D1). * ✅ */ export interface PeopleProvisioningItemData { employmentRef: string; bindingRef?: string | null; providerRef: string; resourceType: string; resourceKey: string; desired: { state: 'enabled' | 'disabled' | 'removed' | 'retained_shared' | 'delegated'; attrs?: unknown; }; origin: { type: 'package' | 'override' | 'milestone'; ref: string; version?: string; }; timing?: { prepareAt?: string; effectiveAt?: string; activatedAt?: string; }; attempt?: { count: number; max: number; nextRetryAt?: string | null; lastError?: string | null; retryAfterRespected?: boolean; }; /** Command Result ≠ Security Outcome ≠ Aggregate Result (PM 9.11.3/6). */ commandResult?: 'accepted' | 'succeeded' | 'failed' | 'unsupported'; securityOutcome?: 'verified' | 'pending_propagation' | 'unverifiable' | null; aggregateResult?: 'completed' | 'completed_with_limitation' | 'manual_resolution' | 'failed' | null; idempotencyKey?: string; contributesUntil?: string | null; state: 'planned' | 'provisioning' | 'prepared' | 'effective' | 'updating' | 'releasing' | 'released' | 'failed' | 'retrying' | 'manual_resolution' | 'cancelled' | 'superseded'; } export type PeopleProvisioningItem = ContentItem; /** `external_binding` (FEAT-009). Managed provider account ⇄ canonical person. ✅ */ export interface PeopleExternalBindingData { providerRef: string; externalAccountId?: string; canonicalPersonRef: string; bindingPolicy?: 'account_per_employment' | 'shared_per_person'; deletedAt?: string | null; providerOperationReference?: string | null; lastReconcile?: Record; resolutionLog?: Array>; state: 'draft' | 'active' | 'suspended' | 'retained' | 'pending_deletion' | 'deleted_verified' | 'manual_resolution' | 'disputed' | 'closed_no_object' | 'released_from_management'; } export type PeopleExternalBinding = ContentItem; /** `drift_finding` (FEAT-009). Desired ≠ Actual; coverage `partial` ≠ clean. ✅ */ export interface PeopleDriftFindingData { providerRef: string; bindingRef?: string | null; findingType: 'missing' | 'extra_unmanaged' | 'mismatch' | 'reappeared' | 'unknown_unreachable' | 'execution'; resourceType?: string; resourceKey?: string; expected?: Record; actual?: Record; severity: 'info' | 'warning' | 'critical'; desiredVersion?: string; coverage?: 'full' | 'partial' | 'unavailable'; detectedAt?: string; sourceRun?: string; resolution?: Record; escalatedTo?: string; suppressedUntil?: string; state: 'open' | 'acknowledged' | 'resolved' | 'accepted_exception' | 'escalated' | 'closed_stale' | 'reactivated'; } export type PeopleDriftFinding = ContentItem; /** `deprovision_plan` (FEAT-009). row-per-version; milestone guard * `sourcePlanVersion == currentValidPlanVersion` (PR23). ✅ */ export interface PeopleDeprovisionPlanData { employmentRef: string; endingPlanRef: string; endingPlanFacts: { lwd: string; endEffectiveAt: string; timezone: string; }; policyRef?: string | null; policyVersion?: string | null; planVersion: number; milestones?: Array<{ milestoneKey: 'pre_lwd' | 'lwd' | 'end_effective' | 'post_lwd_retention' | 'deletion_eligibility'; dueAt?: string; items?: string[]; sourcePlanVersion?: number; status: 'pending' | 'due' | 'executing' | 'done' | 'failed' | 'skipped_obsolete'; executedAt?: string; requiredOutcomesResult?: Record; }>; restoration?: Record; outcomeSummary?: Record; state: 'draft' | 'active' | 'executing' | 'completed' | 'partially_completed' | 'failed' | 'superseded' | 'cancelled'; } export type PeopleDeprovisionPlan = ContentItem; /** `import_changeset` (PIP-004 Track D) — reviewable inbound-directory * import draft; nothing applies until `apply_import_changeset`. */ export interface PeopleImportChangesetData { providerRef: string; runRef: string; source?: 'manual' | 'cron'; directoryUsers?: Array<{ externalAccountId: string; email?: string; displayName?: string; jobTitle?: string; department?: string; manager?: string; teams?: string[]; directoryRoles?: string[]; enabled?: boolean; }>; matches?: Array<{ externalAccountId: string; personRef: string; matchBy: 'email' | 'upn' | 'external_binding'; email?: string; jobTitle?: string; department?: string; teams?: string[]; directoryRoles?: string[]; action: 'link' | 'update'; }>; candidates?: Array<{ externalAccountId: string; email?: string; displayName?: string; jobTitle?: string; department?: string; teams?: string[]; suggestedAction: 'create_person' | 'ignore'; }>; orgMapping?: Record; stats?: { directoryCount?: number; matched?: number; candidates?: number; orgUnitsCreated?: number; positionsCreated?: number; personsLinked?: number; appliedAt?: string; }; state: 'draft' | 'confirmed' | 'discarded'; } export type PeopleImportChangeset = ContentItem; //# sourceMappingURL=ct.types.d.ts.map