import { ContentItem } from '../../content/content.type'; /** `catalog_revision` — bundle CT. ONE row = ONE atomic revision of the * whole access catalog. DS1: published-immutable + atomic publish+supersede. * ✅ */ export interface PeopleCatalogRevisionData { revisionLabel: string; forkedFrom?: string | null; roles: Array<{ key: string; displayName?: string; permissions: string[]; scopeRefs: string[]; /** * Privileged flag (FEAT-008 v1.7 FR-008g): a privileged role cannot * be self-granted (actor == subject ⇒ PEOPLE_RA_PRIVILEGED_SELF_ * GRANT_BLOCKED) — must route through the FEAT-010 access-request. * Optional for pre-v1.7 rows (defaults false server-side). */ privileged?: boolean; }>; permissions: Array<{ key: string; description?: string; seedDomain?: string; configurable?: boolean; }>; scopeRules: Array<{ key: string; level: 'own' | 'team' | 'department' | 'all'; orgMapping?: unknown; }>; fieldAccessPolicies: Array<{ fieldGroup: 'identity' | 'contact' | 'employment' | 'contract' | 'finance-salary' | 'time-attendance'; view: { roleKeys: string[]; maskLevel: 'hidden' | 'partial' | 'full'; scopeRefs: string[]; }; approveLevel: 'L1' | 'L2' | 'L3' | 'L4'; l4Floor: boolean; }>; changelog?: string; validationResult?: { valid?: boolean; errors?: unknown[]; checkedAt?: string; }; state: 'draft' | 'published' | 'superseded' | 'discarded'; } export type PeopleCatalogRevision = ContentItem; /** `scope_exception` — subject-scoped (much higher change cadence than the * bundle). Created by the factory only (`grant_exception`) — see api_references * §3.4 + data-design §3.7b: `POST /content` for scope_exception starts a row * in `draft` with no activation API; the factory is the only admin path. * ✅ */ export interface PeopleScopeExceptionData { subjectRef: string; employmentRef?: string | null; effect: 'grant' | 'deny'; scopeKey: string; window: { effectiveFrom: string; effectiveTo: string; }; justification?: string; origin: 'admin' | 'system'; errorCode?: string | null; state: 'draft' | 'active' | 'expired' | 'revoked'; } export type PeopleScopeException = ContentItem; /** Manual-override marker — manual removal beats birthright (D2). */ export interface PeopleManualOverride { blockedRuleKey?: string; ruleVersionAtOverride?: number; clearedBy?: string; } /** `role_assignment` row payload (registry §3.21). */ export interface PeopleRoleAssignmentData { subjectRef: string; roleKey: string; /** Employment content ref (eaera-hr CT) — identity triple element. */ accessContextRef: string; /** * Access Context discriminator (FEAT-008 v1.7 — PM 8.3 boundary v1). * Only `employment` is allowed in v1; `restricted_admin` and * `hire_context` are reserved for a future boundary expansion. Kept * optional on the wire for backwards compatibility with pre-v1.7 * rows (grant() defaults it to `employment` server-side). */ accessContextType?: 'employment' | 'restricted_admin' | 'hire_context'; /** * Access-context lifecycle state at grant time (RA11 — read by the * reconcile sweep from the ROW to decide `prepared` → `active`). * The grant action re-validates server-side; the row copy keeps the * sweep honest (no default-to-active promotion of guard-rejected * drafts). FEAT-008 §3.4 record_decision / reconcile contract. */ accessContextState?: 'active' | 'scheduled' | 'ended'; assignmentType: 'manual' | 'birthright' | 'requested' | 'emergency'; purpose?: 'standard' | 'acting'; effectiveFrom?: string; effectiveTo?: string | null; justification?: string; /** Emergency only. */ ticketRef?: string; /** Birthright provenance. */ originRuleRef?: string; originRuleVersion?: number; manualOverride?: PeopleManualOverride | null; /** Event dedupe — NO_OP audit PEOPLE_IDEM_DUPLICATE. */ idempotencyKey?: string; sodWarnings?: unknown[]; /** Lifecycle timestamps (engine-written). */ activatedAt?: string; revokedAt?: string | null; amendedAt?: string | null; revokeReason?: string | null; state: 'prepared' | 'active' | 'inactive' | 'revoked' | 'archived'; } export type PeopleRoleAssignment = ContentItem; /** `assignment_rule` row payload (registry §3.22). */ export interface PeopleAssignmentRuleData { ruleKey: string; version?: number; match?: { positions?: string[]; orgUnits?: string[]; legalEntities?: string[]; }; actions?: Array<{ effect: 'grant' | 'remove'; roleKey: string; }>; lastValidated?: string; evaluationStats?: { assignmentsGenerated?: number; lastRunAt?: string; }; state: 'draft' | 'published' | 'superseded' | 'discarded'; } export type PeopleAssignmentRule = ContentItem; /** One structured review item inside a campaign (no own workflow). */ export interface PeopleReviewCampaignItem { managerRef: string; memberRef: string; assignmentRefs: string[]; decision?: 'keep' | 'revoke' | null; reason?: string | null; reviewedAt?: string | null; reviewedBy?: string | null; status: 'pending' | 'done' | 'escalated'; } /** `access_review_campaign` row payload (registry §3.23). */ export interface PeopleAccessReviewCampaignData { cycleConfig?: Record; deadlineAt: string; items?: PeopleReviewCampaignItem[]; escalatedTo?: string; completionReport?: Record | null; state: 'draft' | 'active' | 'completed' | 'cancelled'; } export type PeopleAccessReviewCampaign = ContentItem; //# sourceMappingURL=ct.types.d.ts.map