Skip to content

πŸ”§ Share the billing cron bootstrap preambleΒ #3997

Description

@PierreBrisorgueil

What β€” share the identical bootstrap preamble used by the five billing cron scripts.

Why β€” each cron repeats the same ~25-line block (a six-import Promise.all, an environment default, a config gate, and lock name/TTL). Adding a sixth cron means copying it again.

Scope β€” modules/billing/crons/billing.{weeklyReset,reconcile,extrasExpiration,referralReconcile,dunningSweep}.js. Add bootstrapCron() to modules/billing/lib/billing.cron-utils.js, which already exists and currently holds only applyJitter.

The gate is NOT uniform β€” this is the trap. Four crons gate on the meter-mode flag; billing.referralReconcile gates on the referral-enabled flag and logs a different message. Hardcoding one gate silently changes which flag disables that cron. The gate predicate and its log line must be parameters. Copy each cron's gate, log string and lock TTL from the file itself β€” do not infer them.

Two things the helper must return, or converted crons crash at runtime while unit tests still pass:

  • getCronJitterMaxMs β€” every cron calls it.
  • Everything else each cron currently destructures. Enumerate per file before writing the helper.

Also note the preamble includes a process.env.NODE_ENV default. If it moves into the helper, code that reads process.env.NODE_ENV directly still needs it set at the same point in the sequence.

Definition of done: existing cron unit tests pass, and each converted cron is smoke-run with its flag turned off, printing its original log line verbatim and exiting 0. Unit tests do not exercise the destructure β€” the smoke run is what catches a missing key.

Scope: validated 2026-07-28
Created via /dev:issue


Baseline: line numbers and counts here were verified against master @ c8049d69 (2026-07-28). Master moves β€” re-verify against current master before starting; the invariants above are what must hold regardless of where the code has drifted to.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions