---
title: Fix processed poach hiding the protect menu item
type: task
status: planned
description: >-
  status.eligible.protect reads the raw get_poaches_for_current_league map, which retains processed
  poaches, so a processed poach hides the Designate Protected menu item for a player the server
  would protect.
base_uri: user:task/league/fix-processed-poach-hides-protect-menu-item.md
created_at: '2026-09-08T17:07:30.539Z'
entity_id: 53b436eb-dd8c-4db5-9ec5-c39d5cc7f9c6
owner_identity_uri: █████████████████████████
priority: Low
public_read: true
relations:
  - relates [[user:repository/active/league]]
tags:
  - user:tag/league-xo-football.md
  - user:tag/software-task.md
updated_at: '2026-09-08T17:07:30.539Z'
visibility_analyzed_at: '2026-11-05T23:49:27.356Z'
---

## Problem

`status.eligible.protect` in `app/core/selectors.js` gates on `!leaguePoaches.has(playerId)`, where `leaguePoaches` is `get_poaches_for_current_league` — the RAW map, which retains poaches that have already been processed. `get_poach_players_for_current_league` in the same file deletes processed rows by hand, which is the tell that the raw map is not safe to read directly.

So a practice squad player whose poach was already processed loses the `Designate Protected` item in the row context menu, even though the server would accept the protect: `libs-server/submit-practice-squad-protection.mjs` queries `poaches` with `.whereNull('processed')`.

## Scope

One condition in `getPlayerStatus`. The batch path is already correct — `get_protect_eligible_practice_squad_pids` filters processed poaches — so this is only the single-player row menu.

## Plan

- [ ] Filter processed poaches in the `status.eligible.protect` condition, matching `get_protect_eligible_practice_squad_pids`.
  - Consider having both read one helper rather than repeating the predicate, since they must not drift apart.
  - Verify: with a processed poach seeded against a PS player, the row menu offers `Designate Protected` and the server accepts it.
