/**
 * Shared helper for building a parameterized SQL `IN (...)` clause — one
 * bound placeholder per id, never a joined/interpolated value list (CWE-89).
 * First introduced for the report services' optional account
 * (`transactions.source_id`) filter (Issue #273); reused by every service
 * that accepts an `accountIds?: number[]` filter so the placeholder
 * bookkeeping (start index, one `$N` per id) lives in exactly one place.
 *
 * Returns `null` when `ids` is empty/undefined so callers can skip adding the
 * clause entirely — that is the "no filter" case, and the query must stay
 * byte-identical to how it read before the filter existed.
 */
export function inPlaceholders(ids: number[] | undefined, startIndex: number): string | null {
  if (!ids || ids.length === 0) return null;
  return ids.map((_, i) => `$${startIndex + i}`).join(", ");
}
