Skip to content

feat(state): declarative org members with deferred backfill (issue #94)#277

Merged
DerDennisOP merged 3 commits into
mainfrom
fix/state-org-members-94
May 26, 2026
Merged

feat(state): declarative org members with deferred backfill (issue #94)#277
DerDennisOP merged 3 commits into
mainfrom
fix/state-org-members-94

Conversation

@DerDennisOP
Copy link
Copy Markdown
Member

@DerDennisOP DerDennisOP commented May 26, 2026

Summary

  • Adds state.organizations.<name>.members = [{ user, role }] (Nix + JSON) so operators can manage org membership declaratively.
  • Missing users are skipped silently at apply time and backfilled the instant they register via POST /user or first-log-in via OIDC.
  • When members is non-empty, it is the source of truth — drift reconciliation removes memberships no longer in the list (cache-style). Empty members preserves legacy behavior (created_by auto-added as Admin).
  • Roles can be built-in (Admin/Write/View) or a state-managed custom org role declared under state.roles for the same organization.

Closes #94.

Implementation notes

  • Split apply_organizations into apply_organizations_without_members (runs early) and apply_organization_members (runs after apply_roles) so custom org roles inserted in the same apply pass are resolvable.
  • New PendingOrgMemberships map returned from load_and_apply_state, stashed on ServerState, drained per-username by the new apply_pending_org_memberships helper invoked from both the registration endpoint and OIDC first-login (inside the existing OIDC transaction so user creation and membership stay atomic).

Test plan

  • cargo check --workspace --all-targets
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo clippy --workspace --tests -- -D warnings
  • CI runs the new state-mod tests:
    • state_org_members_serde_round_trip, state_org_members_default_empty
    • validator: accepts_builtin_role, accepts_custom_org_role, rejects_unknown_role, ignores_unknown_user, rejects_duplicate_user
    • pending_membership_tests::apply_pending_returns_zero_for_unknown_user
  • Manual: apply a state file listing an unregistered member, register that user via POST /user, verify the organization_user row appears.

@DerDennisOP DerDennisOP merged commit 9e70a1d into main May 26, 2026
8 checks passed
@DerDennisOP DerDennisOP deleted the fix/state-org-members-94 branch May 26, 2026 07:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Quality] StateOrganization has no members field - operators can't manage org membership via state config

1 participant