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
3.6 KiB
3.6 KiB
Developer Runbook: System-Managed Default Contract
Purpose
Reference for engineers touching contract assignment, due-work generation, and recurring invoice flows after default-contract cutover.
Lifecycle Semantics
- Identity: one system-managed default contract per
(tenant, client)incontracts(is_system_managed_default=true) with linkedclient_contractsassignment. - Creation policy: lazy/on-demand only through billing-configuration touchpoints.
- Deletion policy: client/billing-config cleanup must remove assignment artifacts and avoid dangling references.
- Manual mutation policy: identity fields are server-guarded (
is_system_managed_default,owner_client_id) and not user-editable. - Attribution-shell policy: system-managed defaults are non-authorable and should never be used as recurring/service-period schedule authorities.
Routing Semantics
- Resolver entry points (billing + scheduling) evaluate eligible lines by
effectiveDatewindows. - Decision outcomes:
explicit: one eligible line.default: one bucket-overlay-preferred fallback line.ambiguous_or_unresolved: none or multiple unresolved matches.
- Resolver logs use event
contract_line_resolver.routing.
Reconciliation Semantics
- Unresolved due-work pass routes through billing-engine reconciliation.
- Deterministic single-match rows write back
contract_line_idto source records with null-check guards. - Ambiguous/no-match rows remain unresolved and visible for manual handling.
- Reconciliation logs use event
billing_engine.reconcile.unresolved.
Automatic Invoicing Semantics
- Grouped rows carry attribution metadata:
- explicit contract
- system-managed default contract
- unresolved
- Missing required attribution metadata hard-blocks generation for affected grouped candidates.
- Selection-key compatibility supports legacy
non_contractparsing only where needed for migration-safe history reads.
Historical Client-Cycle Bootstrap
- UI can provide an optional
billingHistoryStartDatewhen saving client billing schedule. - Shared schedule domain normalizes that date to the containing cycle boundary before regeneration.
- Regeneration only mutates uninvoiced cycles from the normalized boundary onward.
- Bootstrap requests earlier than earliest invoiced cycle boundary are blocked with explicit user-facing copy.
- Manual cycle bootstrap (
createNextBillingCycle(..., effectiveDate)) and schedule-save bootstrap use the same boundary-normalization contract.
Operational Verification
- Default ensure + lifecycle:
npx vitest run --config shared/vitest.config.ts shared/__tests__/billingSettings.defaultContract.ensure.test.ts
- Resolver + reconciliation + grouped selection:
cd server && npx vitest run src/test/unit/billing/billingEngine.unresolvedReconciliation.test.ts src/test/unit/billing/automaticInvoices.nonContractSelection.ui.test.tsx
- Observability wiring:
cd server && npx vitest run src/test/unit/billing/defaultContractObservability.wiring.test.ts
- Historical bootstrap + attribution-shell routing:
npx vitest run --config shared/vitest.config.ts shared/__tests__/billingSchedule.historyBootstrap.test.tscd server && npx vitest run src/test/unit/billing/defaultContractHistoricalBootstrapAndBillingRoute.wiring.test.ts src/test/unit/billing/systemManagedDefaultRecurringExclusion.wiring.test.ts
Guardrails For Future Changes
- Do not add eager default-contract creation at client-create time.
- Do not bypass action-level guards for system-managed identity fields.
- Do not remove compatibility parsing until rollout stages explicitly permit fallback retirement.