Split inactive profile state

Replace the binary profile ACTIVE/INACTIVE model with PENDING, ACTIVE,
and DEACTIVATED so invited-but-not-yet-activated members remain
assignable to assets, data, and risks instead of being treated like
deactivated users.

Add activated_at/deactivated_at timestamps and Mark* lifecycle helpers,
and update every transition (create, invite/re-invite, activation,
archive, SCIM, SAML, sessions, compliance-portal grant) to the new
states. Expose a multi-state states[] filter across coredata, GraphQL,
MCP, and the console owner pickers, which now request ACTIVE and
PENDING members.

A migration renames the membership_state enum, classifies existing
inactive profiles as PENDING from recent invitation activity, and
backfills the new timestamp columns.

Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
Émile Ré
2026-07-28 17:03:52 +02:00
parent 6b3913b189
commit 4a276e3ef7
29 changed files with 261 additions and 64 deletions

View File

@@ -184,8 +184,9 @@ components:
ProfileState:
type: string
enum:
- PENDING
- ACTIVE
- INACTIVE
- DEACTIVATED
go.probo.inc/mcpgen/type: go.probo.inc/probo/pkg/coredata.ProfileState
ProfileKind:
@@ -526,7 +527,7 @@ components:
description: Profile source (MANUAL, SCIM, or SAML)
state:
$ref: "#/components/schemas/ProfileState"
description: Profile state (ACTIVE or INACTIVE)
description: Profile state (PENDING, ACTIVE, or DEACTIVATED)
position:
type:
- string
@@ -578,7 +579,12 @@ components:
description: Filter by contract status. True returns only users with ended contracts, false returns only users with active or no contract.
state:
$ref: "#/components/schemas/ProfileState"
description: Filter by profile state (ACTIVE or INACTIVE)
description: Filter by profile state (PENDING, ACTIVE, or DEACTIVATED)
states:
type: array
items:
$ref: "#/components/schemas/ProfileState"
description: Filter by profile states (PENDING, ACTIVE, or DEACTIVATED)
query:
type: string
description: Search by full name, email address, or position