@buzzr/dfs-engine
    Preparing search index...

    Function applyLegDnp

    • Mark a single leg as DNP and return the new bet shape (legs + multiplier

      • potential payout). Pure: caller persists the result.

      Mirrors bet-service.ts:markLegDnp's transition logic so the Deno settlement watcher's pre-game DNP path produces the same column writes as the RN UI's manual DNP override. The actual void column values (status='void', actual_payout=stake, etc.) are applied by the caller when isVoided=true — see bet-service.ts:399-433.

      MAINTAINED PAIR: applyLegDnp (this file, used by the Deno watcher) and markLegDnp (bet-service.ts, used by the RN UI) implement the same transition twice. Future cleanup: extract computeDnpTransition that returns the full intended column-write object so both call sites collapse to thin transport wrappers. The void-branch contract pin in tests/unit/lib/dfs-pregame-dnp.test.ts catches drift between the two.

      KNOWN LIMITATION: passing currentMultiplier (post-prior-DNP) instead of the slip's original placed multiplier is mathematically equivalent by chain rule — recalc results match across multi-DNP modulo 4-decimal rounding. The semantic loss is the link back to slip-at-placement, which becomes load-bearing for Wave 4 G.write (stat-correction reversal needs to recompute from original) and dispute explainability. Fix: persist slip_original_multiplier at create time, immutable; multiplier remains current state. Deferred until reconciliation forces the issue.

      Idempotency: if the target leg is already 'dnp', returns alreadyDnp=true and the caller should skip writes.

      Caller is responsible for:

      • Re-asserting bet status='pending' in the WHERE clause to guard against manual-override races.
      • Writing the void columns when isVoided=true.
      • Writing the post-DNP grading-snapshot/log row.

      Type Parameters

      Parameters

      • opts: {
            app: DfsApp;
            currentMultiplier: number;
            legIdToMark: string;
            legs: L[];
            playType: DfsPlayType;
            stake: number;
        }
        • app: DfsApp
        • currentMultiplier: number

          bet.multiplier as currently stored — passed straight to recalcMultiplierAfterDnp.

        • legIdToMark: string
        • legs: L[]
        • playType: DfsPlayType
        • stake: number

      Returns {
          alreadyDnp: boolean;
          isVoided: boolean;
          newMultiplier: number;
          newPotentialPayout: number;
          notFound: boolean;
          updatedLegs: L[];
      }