Skip to content

feat(admin): assign existing upstreams to pools - #167

Closed
erwill2 wants to merge 1 commit into
icoretech:mainfrom
erwill2:feat/admin-assign-upstream-pool
Closed

feat(admin): assign existing upstreams to pools#167
erwill2 wants to merge 1 commit into
icoretech:mainfrom
erwill2:feat/admin-assign-upstream-pool

Conversation

@erwill2

@erwill2 erwill2 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a complete admin workflow for attaching an existing upstream identity to a Pool, and fixes account reactivation so a newly attached pending Pool assignment can become operational.

These changes are combined because they share the same assignment lifecycle invariant: an existing Pool/identity slot must be safely promoted to an active, eligible assignment rather than duplicated or left pending.

Operator workflow

  • Unfiltered Upstreams view now includes non-deleted identities available to Pool management, including identities with no active Pool assignment.
  • An explicit Pool filter continues to show only accounts assigned to that Pool; this is based on the filter value rather than Pool-count equality, so it is correct even when the instance has only one Pool.
  • Adds an Assign to Pool card action and an accessible dialog using the existing admin dialog/footer/action primitives.
  • The identity is held in server-side LiveView state and the submitted Pool ID must resolve through the operator's currently visible Pool list.
  • The mutation is routed through a scoped admin workflow that rechecks pool.operate capability and current identity visibility at execution time.

Assignment lifecycle and race handling

  • Creates a new assignment directly as active / active health / eligible.
  • Reuses an existing active assignment idempotently.
  • Promotes an existing pending row instead of leaving the new attachment non-operational.
  • Restores a soft-deleted row in the same Pool/identity slot rather than violating the unique key.
  • Rejects deleted upstream identities.
  • Serializes assignment through an upstream-identity row lock and locks an existing assignment row FOR UPDATE, preventing concurrent admin clicks or delete/reactivate overlap from producing duplicate/stale outcomes.
  • Clears cooldown and disabled timestamps when restoring an assignment.

Coordinated side effects

The scoped workflow also:

  • records upstream_account.assign_pool in the audit log;
  • broadcasts an upstream_assignment_assigned invalidation event;
  • best-effort enqueues a manual catalog sync so the target Pool does not retain a stale model catalog;
  • logs only a sanitized enqueue failure code if catalog scheduling fails.

Reactivation fix

Account reactivation now treats a pending Pool assignment as reactivatable. This covers the attach-after-detach sequence where the preserved/source assignment was removed and the newly attached target assignment is still pending. Deleted assignments remain deleted.

Validation

  • mix compile --warnings-as-errors - passed
  • Focused workflow/lifecycle/LiveView command - 5 passed, 0 failures
    • scoped authorization, audit event, broadcast, and catalog enqueue
    • denied target-Pool access has no database/job/audit side effects
    • active/deleted/pending assignment reuse and deleted-identity rejection
    • pending assignment promotion during account reactivation
    • unassigned account visibility, explicit Pool-filter exclusion, dialog, and database assignment
  • mix test test/codex_pooler/audit_test.exs - 4 passed, 0 failures
  • Strict Credo on all changed source and test files - no issues
  • git diff --check - passed

Scope boundaries

  • No database migration is required.
  • No production deployment or data cleanup was performed.
  • Partial catalog-sync resilience and stale-refreshing recovery are separate PRs.
  • The proposed gateway side_effects.ex Oban-state change is intentionally excluded; duplicate gateway reconciliation is tracked separately in issue Bug: investigate duplicate gateway reconciliation and token-refresh runs #166.
  • Routing-details/circuit-state UI and other unrelated admin changes are excluded.

@erwill2

erwill2 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

cleaning this up to resolve conflicts

@erwill2
erwill2 force-pushed the feat/admin-assign-upstream-pool branch from e670518 to 911ce31 Compare July 14, 2026 18:02
masterkain added a commit that referenced this pull request Aug 13, 2026
Make each manageable Pool assignment lane open the shared Pool editor in place on its Upstreams step, with the whole lane as the shiny interaction target.

Keep Pool editing and invite creation URL-backed on the Upstreams page, preserve filters and permissions, and cover assignment removal plus permalink behavior with focused LiveView specs.

refs #167

Co-authored-by: erwill2 <wrumph@gmail.com>
@masterkain

Copy link
Copy Markdown
Member

thanks @erwill2 for the proposal in PR #167

we independently re-verified the underlying usability gap against the current admin UI

since this PR was opened, Pool management has moved into a dedicated editor and the Upstreams cards now expose their Pool assignments, so we did not retain the direct assignment controls from this branch

the retained direction landed independently in commit 79f5fa5b:

  • the whole Pool lane on an Upstream card opens the existing Pool editor in place on the Upstreams step
  • the canonical editor handles both adding and removing assignments with the existing pool.manage authorization
  • URL-backed dialog state preserves filters and supports direct links plus browser Back/Forward
  • Invite creation now also opens in place on /admin/upstreams

we are closing this PR without merging its branch

attribution for the original finding and direction remains with you, and the implementation commit includes you as a co-author

@masterkain masterkain closed this Aug 13, 2026
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.

2 participants