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
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
2.4 KiB
2.4 KiB
Recurring Service-Period Regeneration
Purpose
F238 and F239 define the first regeneration algorithm for persisted future recurring service periods.
The v1 rule is intentionally conservative:
- untouched generated future rows may be refreshed when source recurrence rules change
- user-edited or repair-driven future rows must not be silently overwritten
- replaced untouched rows become
superseded - newly regenerated rows keep the logical slot identity by reusing the prior
periodKeyand incrementingrevision
Authoritative Helper Surface
The shared v1 regeneration helper now lives in:
shared/billingClients/regenerateRecurringServicePeriods.tsregenerateRecurringServicePeriods(...)
Regeneration Rules
The helper applies the following slot-order policy to future active rows on one schedule:
- Sort existing active rows and new candidate rows by service-period order.
- Preserve override rows instead of overwriting them.
Override rows are currently:
provenance.kind = user_editedprovenance.kind = repair- lifecycle states
edited,locked, orbilled
- For untouched generated rows:
- if the candidate row is equivalent, keep the existing row as-is
- if the candidate row changed, write a new
regeneratedrow that:- reuses
scheduleKey - reuses
periodKey - increments
revision - points
supersedesRecordIdat the prior row
- reuses
- mark the prior row as
superseded
- If an untouched existing future row no longer has any candidate slot, supersede it.
- If new candidate slots remain after existing future rows are exhausted, keep them as new generated rows.
Override-Preservation Rule
The first-cut override rule is explicit:
- regeneration must not silently replace user-edited future rows
- regeneration must not silently replace repair rows
- candidate rows that would have occupied those preserved slots are discarded until a later explicit conflict-handling flow exists
This keeps v1 safe before the later conflict-resolution work in F249.
Deliberate Non-Goals For F238/F239
This checkpoint does not yet define:
- operator-facing conflict queues when preserved overrides and new source rules diverge materially
- bulk conflict resolution
- per-field merge behavior between a user edit and a regenerated candidate
Those remain later follow-on work after the first preservation-safe regeneration path.