/**
 * URL parameter validation for route handlers.
 *
 * Handlers were passing raw path segments straight into database predicates.
 * `parseInt("abc", 10)` yields NaN, and a NaN or malformed-UUID comparison
 * makes Postgres raise, which surfaces as a 500. So /:owner/:repo/issues/abc
 * crashed while /:owner/:repo/issues/99999999 correctly 404'd — a hand-typed
 * or stale URL returned a server error instead of "not found".
 *
 * Found by the authz-matrix gate, which probes every repo-scoped route with a
 * placeholder id: eight routes answered 5xx (issues, pulls, milestones,
 * agents and claude sessions).
 */

/**
 * A positive integer path segment (issue/PR numbers), or null when the
 * segment is not one. Rejects NaN, zero, negatives, floats, and numeric
 * strings with trailing junk ("12abc") that parseInt would happily truncate.
 */
export function parseIdNumber(raw: string | undefined): number | null {
  if (!raw || !/^\d+$/.test(raw)) return null;
  const n = Number(raw);
  if (!Number.isSafeInteger(n) || n <= 0) return null;
  return n;
}

/**
 * A UUID path segment, or null. Postgres raises `invalid input syntax for
 * type uuid` on anything else, which the global error handler turns into a
 * 500 — so this must be checked before the value reaches a query.
 */
export function parseIdUuid(raw: string | undefined): string | null {
  if (!raw) return null;
  return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(raw)
    ? raw
    : null;
}
