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

68 lines
5.0 KiB
Markdown

# Scratchpad — Contract Template Normalization
- Plan slug: `contract-template-normalization`
- Created: `2026-03-16`
## What This Is
Keep a lightweight, continuously-updated log of discoveries and decisions made while implementing this plan.
Prefer short bullets. Append new entries as you learn things, and also *update earlier notes* when a decision changes or an open question is resolved.
## Decisions
- (2026-03-16) Treat this as a new standalone ALGA plan rather than appending to `2026-03-16-client-owned-contracts-simplification`. The earlier plan is implementation-specific and already largely shipped; this work is a broader normalization/cutover effort.
- (2026-03-16) Sequence the work as runtime cutover first, API/UI separation second, schema cleanup last. Deleting legacy columns/rows before removing runtime fallback is unsafe.
- (2026-03-16) Treat template instantiation as the only legal transfer boundary between authoring data and runtime data. Existing contracts must be self-contained after instantiation, with no reverse sync from templates.
## Discoveries / Constraints
- (2026-03-16) `packages/billing/src/lib/billing/billingEngine.ts` still resolves live contract lines through `coalesce(cc.template_contract_id, cc.contract_id)` and discount joins still use `template_contract_id OR contract_id`. This is the primary runtime coupling to remove.
- (2026-03-16) `shared/billingClients/templateClone.ts` is already close to the target shape: it reads `contract_template*` tables and writes `contract_*` tables. The remaining question is whether template provenance should survive only as metadata.
- (2026-03-16) `packages/billing/src/actions/contractActions.ts` still maps template rows into `IContract`-shaped responses and falls back from contract lookup to template lookup.
- (2026-03-16) `packages/billing/src/models/contractTemplate.ts` template deletion still deletes from instantiated contract tables (`contract_lines`, `contract_line_service_*`, `contract_line_services`, `contract_line_service_defaults`). This is a hard coupling and a cleanup blocker.
- (2026-03-16) The strongest framing for this plan is not just “remove legacy template flags,” but “make templates authoring-only assets and instantiated contracts self-contained runtime facts.”
- (2026-03-16) `server/scripts/verify-template-migration.ts` currently validates parity between legacy template rows in `contracts` and canonical rows in `contract_templates`, which means the operational model still assumes duplicated storage exists.
- (2026-03-16) `server/scripts/contract-template-decoupling.ts` still preserves hybrid semantics by backfilling or relying on `template_contract_id`.
- (2026-03-16) Schema artifacts still present from the mixed model:
- `contracts.is_template`
- `contract_lines.is_template`
- `client_contracts.template_contract_id`
- (2026-03-16) Citus / distributed-FK constraints are part of the sequencing risk. Some migrations intentionally avoided strict FKs, so application/runtime cleanup cannot assume the database enforces the final invariant today.
## Commands / Runbooks
- (2026-03-16) Recon:
- `rg -n "is_template|template_contract_id|contract_templates|mapTemplateToContract|isTemplateContract\\(" packages/billing packages/clients server shared`
- `sed -n '520,590p' packages/billing/src/lib/billing/billingEngine.ts`
- `sed -n '1,220p' server/scripts/verify-template-migration.ts`
- `sed -n '1,240p' packages/billing/src/actions/contractActions.ts`
- `sed -n '120,210p' packages/billing/src/models/contractTemplate.ts`
- (2026-03-16) Plan validation:
- `python3 /Users/roberisaacs/.codex/skills/alga-plan/scripts/validate_plan.py ee/docs/plans/2026-03-16-contract-template-normalization`
## Links / References
- Prior related plan:
- `ee/docs/plans/2026-03-16-client-owned-contracts-simplification/`
- Key runtime files:
- `packages/billing/src/lib/billing/billingEngine.ts`
- `shared/billingClients/templateClone.ts`
- `packages/billing/src/actions/contractActions.ts`
- `packages/billing/src/models/contract.ts`
- `packages/billing/src/models/contractTemplate.ts`
- `packages/billing/src/repositories/contractLineRepository.ts`
- Key migration / ops files:
- `server/migrations/20251020090000_contract_templates_phase1.cjs`
- `server/migrations/20251020164500_backfill_contract_template_tables.cjs`
- `server/migrations/20251020180500_update_client_contract_template_foreign_keys.cjs`
- `server/migrations/20251028090000_remove_contract_line_mappings.cjs`
- `server/scripts/verify-template-migration.ts`
- `server/scripts/contract-template-decoupling.ts`
## Open Questions
- Should `client_contracts.template_contract_id` remain as immutable provenance metadata, or should provenance move to a different field/table before full removal?
- Are there production-only support or ops workflows still depending on legacy template rows living in `contracts`?
- Is there any externally consumed contract API that currently depends on template rows being presented as `IContract` and needs a transition path?