Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

2.7 KiB

Recurring Service-Period Backfill

F244 defines the parity-safe initialization rule for tenants that already have recurring invoice history before the persisted service-period ledger exists.

This checkpoint is still additive:

  • it initializes future persisted rows for existing recurring obligations
  • it does not rewrite historical invoices or synthesize historical persisted rows just to mirror already-billed coverage
  • it does define how billed-history boundaries fence off future backfill so the later runtime cutover can start from a clean future ledger

Historical Boundary

Backfill now resolves one explicit historical cutoff:

  • legacyBilledThroughEnd
  • or, if persisted billed rows already exist, the latest servicePeriod.end among billed / linked records

shared/billingClients/backfillRecurringServicePeriods.ts treats that date as the billed-history boundary.

The rules are:

  • candidate periods ending on or before the boundary are skipped
  • candidate periods starting on or after the boundary remain eligible for insertion
  • a candidate that overlaps the boundary is rejected instead of being silently clipped or split

That overlap rejection is deliberate. Backfill must not invent partial historical rewrites just to make a future ledger fit.

Initialization Policy

Future candidates are normalized onto explicit backfill provenance:

  • provenance.kind = generated
  • provenance.reasonCode = backfill_materialization
  • sourceRuleVersion and sourceRunKey reflect the backfill run, not the earlier materializer placeholder

This keeps initialized rows distinguishable from first-day greenfield materialization while still saying they are untouched generated schedule rows.

Existing Future Rows

Backfill must also be safe when a tenant already has some persisted future rows from an earlier partial rollout or retry.

The v1 rule is:

  • billed historical rows are retained unchanged
  • equivalent future rows are retained unchanged
  • untouched generated future rows that disagree with the current candidate schedule are regenerated with reasonCode = backfill_realignment
  • user-edited, repair, locked, and billed rows still follow the existing preservation rules from RECURRING_SERVICE_PERIOD_REGENERATION.md

This means backfill can reconcile future schedule drift without mutating billed history or trampling explicit overrides.

Deliberate Boundary

This checkpoint still does not define:

  • invoice-time due selection from persisted rows
  • historical persisted-row backfill for already-billed invoices
  • UI or API listing/editing surfaces for future persisted periods
  • bulk repair tooling for overlap conflicts discovered during backfill

Those remain sequenced behind F245-F267.