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

65 lines
3.6 KiB
Markdown

# 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)` in `contracts` (`is_system_managed_default=true`) with linked `client_contracts` assignment.
- 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 `effectiveDate` windows.
- 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_id` to 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_contract` parsing only where needed for migration-safe history reads.
## Historical Client-Cycle Bootstrap
- UI can provide an optional `billingHistoryStartDate` when 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.ts`
- `cd 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.