-- Part 3: competing consumers with optional per-key guard
-- Compose after: 01-claim-loop/source.sql or content/series/durable-work-postgres/source/schema.sql.
-- This replaces the simple claim query when multiple workers compete.

WITH candidates AS (
  SELECT i.id
  FROM inbox i
  WHERE i.status = 'pending'
    AND i.available_at <= now()
    AND NOT EXISTS (
      SELECT 1
      FROM inbox busy
      WHERE busy.partition_key = i.partition_key
        AND busy.status = 'processing'
    )
  ORDER BY i.partition_key, i.created_at, i.id
  LIMIT 25
  FOR UPDATE SKIP LOCKED
)
UPDATE inbox i
SET status = 'processing',
    claimed_by = $1,
    lease_expires_at = now() + interval '90 seconds',
    lease_generation = i.lease_generation + 1,
    attempts = i.attempts + 1
FROM candidates c
WHERE i.id = c.id
RETURNING i.*;
