@maverickcer/env-cap
    Preparing search index...

    Function parseRotationPeriodDays

    • Parses rotationPeriod (e.g. "90 days", "P90D", "6 months") into a whole number of days, or undefined when it isn't in either recognized grammar.

      Parameters

      • value: string

      Returns number | undefined

      rotationPeriod is documented (runtime/document.ts) as an organization-defined string much like retention -- but unlike retention, which is never parsed (a pure policy statement), computeRotationStatus() genuinely needs a numeric due date to compare against now. This function is the one place that tension is resolved: it recognizes two small, common, unambiguous grammars (a plain " " -- singular/plural/abbreviated, case-insensitive, with or without a space, e.g. "90 days"/"90day"/"12weeks" -- and ISO 8601's calendar-duration form, date components only (PnYnMnD, no T/time-of-day component since a rotation period is never meaningfully finer than a day; bare "P" is not a duration) rather than attempting to parse arbitrary prose ("quarterly", "every other release", ...) -- an org whose policy string doesn't fit either grammar still has it stored and rendered verbatim everywhere else, it just can't feed a computed due date, and computeRotationStatus() fails closed ("overdue") rather than guessing at one. Month/year are calendar approximations (30/365 days) -- acceptable for a rotation-compliance signal, not precise enough for anything billing/calendar-accurate.

      A computed total of zero days (e.g. "0 days", "P0D", "P0Y0M0D" -- the digit grammar can't produce a negative total, but zero is reachable) is treated the same as an unparseable string, not a real duration: it returns undefined rather than 0, so computeRotationStatus() falls into its own "declared but unverifiable" fail-closed path ("overdue") instead of computing a degenerate due date equal to lastRotatedAt itself -- a nonsensical "rotate every zero days" policy should read as un-computable, not silently produce a technically-correct-but-meaningless due date.

      Both patterns are inlined at their .exec() call site, deliberately not hoisted to a module-level const -- same precedent as source-position.ts's parsePositionCitation(): a module-level regex literal is a load-time-only ("static") mutation target, which Stryker's own perTest coverage analysis can't attribute to a specific covering test (see this package's own stryker.config.mjs), while an inline literal is re-evaluated -- and so mutation-tested -- on every call.