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
153 KiB
153 KiB
Scratchpad — Contract Auto-Renewal and Renewals Queue
- Plan slug:
contract-auto-renewal-and-renewals-queue - Created:
2026-02-21
What This Is
Rolling implementation memory for renewal settings + actionable renewals queue + automation ticketing.
Decisions
- (2026-02-21) Build an actionable queue (not read-only report).
- (2026-02-21) Ship both dashboard entry and full queue page (
Client Contractswidget +Renewalstab). - (2026-02-21) Primary operational date is renewal decision due date.
- (2026-02-21) Due-date behavior is configurable with tenant defaults + optional per-contract override.
- (2026-02-21) Default automation target at due date: create internal ticket.
- (2026-02-21) Minimum queue actions for v1:
Mark renewing,Mark non-renewing,Create renewal draft,Snooze. - (2026-02-21) Default queue horizon: 90 days, grouped
0-30,31-60,61-90. - (2026-02-21) Queue includes fixed-term + evergreen anniversaries.
- (2026-02-21)
Mark renewingshould auto-create renewal draft and open it. - (2026-02-21) Release approach: single release scope.
- (2026-02-21) Automation runtime note: support pg-boss for on-prem and Temporal for hosted/EE.
Discoveries / Constraints
- (2026-02-21) Runtime selection already exists in
server/src/lib/jobs/JobRunnerFactory.tswith config/env-based choice and fallback behavior; default is pg-boss unless configured otherwise. - (2026-02-21) Existing scheduled jobs in
server/src/lib/jobs/initializeScheduledJobs.tsexplicitly branch for enterprise/temporal behavior in some paths; renewal automation should follow same compatibility pattern. - (2026-02-21) Contract lifecycle already emits
CONTRACT_CREATEDandCONTRACT_RENEWAL_UPCOMINGin bothpackages/clients/src/actions/clientContractActions.tsandpackages/billing/src/actions/contractWizardActions.ts. - (2026-02-21)
CONTRACT_RENEWAL_UPCOMINGcomputation today is window-based (DEFAULT_CONTRACT_RENEWAL_UPCOMING_WINDOW_DAYS = 30) inshared/workflow/streams/domainEventBuilders/contractEventBuilders.ts; queue design requires broader 90-day horizon and due-date semantics. - (2026-02-21) Existing contract expiration report is currently
end_date-driven (packages/billing/src/actions/contractReportActions.ts,server/src/lib/reports/definitions/contracts/expiration.ts). - (2026-02-21) Billing settings already provide tenant defaults in
default_billing_settingswith client override pattern inclient_billing_settings; actions inpackages/billing/src/actions/billingSettingsActions.tsand shared helpers inshared/billingClients/billingSettings.tsare reusable design patterns. - (2026-02-21) Billing UI insertion points are clear:
- tabs config:
packages/billing/src/components/billing-dashboard/billingTabsConfig.ts - tab content host:
packages/billing/src/components/billing-dashboard/BillingDashboard.tsx - queue/widget host:
packages/billing/src/components/billing-dashboard/contracts/ClientContractsTab.tsx - wizard basics:
packages/billing/src/components/billing-dashboard/contracts/wizard-steps/ContractBasicsStep.tsx
- tabs config:
- (2026-02-21) Contract assignment data shape in
server/src/interfaces/contract.interfaces.tsis assignment-level and suitable for renewal metadata onIClientContract.
Commands / Runbooks
- (2026-02-21) Inspect billing dashboard contract files:
rg -n "ContractWizard|ClientContractsTab|billingTabsConfig|ContractBasicsStep" packages/billing/src/components/billing-dashboard
- (2026-02-21) Inspect runtime selection + scheduling:
rg -n "JobRunnerFactory|initializeScheduledJobs|EDITION|JOB_RUNNER_TYPE" server/src/lib/jobs
- (2026-02-21) Inspect contract renewal event publishing:
rg -n "CONTRACT_RENEWAL_UPCOMING|computeContractRenewalUpcoming" packages/billing packages/clients shared/workflow
- (2026-02-21) Validate plan artifacts:
python3 /Users/roberisaacs/.codex/skills/alga-plan/scripts/validate_plan.py ee/docs/plans/2026-02-21-contract-auto-renewal-and-renewals-queue
Links / References
- Key plan path:
ee/docs/plans/2026-02-21-contract-auto-renewal-and-renewals-queue - Runtime selection:
server/src/lib/jobs/JobRunnerFactory.ts - Scheduled job init:
server/src/lib/jobs/initializeScheduledJobs.ts - Job scheduler infra:
server/src/lib/jobs/jobScheduler.ts - Renewal event builders:
shared/workflow/streams/domainEventBuilders/contractEventBuilders.ts - Contract wizard save path:
packages/billing/src/actions/contractWizardActions.ts - Client contract actions:
packages/clients/src/actions/clientContractActions.ts - Billing settings actions:
packages/billing/src/actions/billingSettingsActions.ts - Billing settings shared helpers:
shared/billingClients/billingSettings.ts - Billing dashboard tabs host:
packages/billing/src/components/billing-dashboard/BillingDashboard.tsx - Client contracts tab:
packages/billing/src/components/billing-dashboard/contracts/ClientContractsTab.tsx - Wizard basics step:
packages/billing/src/components/billing-dashboard/contracts/wizard-steps/ContractBasicsStep.tsx
Implementation Log
- (2026-02-21) Completed
F001.- Added renewal fields to
ContractWizardDatainpackages/billing/src/components/billing-dashboard/contracts/ContractWizard.tsx:renewal_mode?: 'none' | 'manual' | 'auto'notice_period_days?: numberrenewal_term_months?: numberuse_tenant_renewal_defaults?: boolean
- Rationale: establish typed wizard-state shape early so subsequent UI rendering, defaults/hydration, validation, and submission features can build on stable field names.
- Added renewal fields to
- (2026-02-21) Completed
T001.- Added
packages/billing/src/components/billing-dashboard/contracts/ContractWizard.renewalFields.test.ts. - Test covers type-level contract for the four renewal fields and validates the allowed
renewal_modedomain values. - Runbook:
npx vitest run packages/billing/src/components/billing-dashboard/contracts/ContractWizard.renewalFields.test.ts
- Added
- (2026-02-21) Completed
F002.- Added
createDefaultContractWizardData()inpackages/billing/src/components/billing-dashboard/contracts/ContractWizard.tsx. - Renewal defaults for new contracts now initialize as:
renewal_mode: 'manual'notice_period_days: 30renewal_term_months: undefineduse_tenant_renewal_defaults: true
- Updated wizard initialization/reset paths to use the shared factory, keeping default behavior deterministic across first render, open/reset, and edit-merge flows.
- Added
- (2026-02-21) Completed
T002.- Extended
packages/billing/src/components/billing-dashboard/contracts/ContractWizard.renewalFields.test.tswith default-state assertions usingcreateDefaultContractWizardData(). - Validates default renewal state for new contracts: mode
manual, notice30, no term months, tenant-default toggle enabled.
- Extended
- (2026-02-21) Completed
F003.- Extended
DraftContractWizardDatainpackages/billing/src/actions/contractWizardActions.tswith renewal fields. - Updated
getDraftContractForResumeto hydrate renewal settings fromclient_contracts:- normalized
renewal_mode(none|manual|auto) - sanitized integer
notice_period_days(non-negative) - sanitized positive integer
renewal_term_months - hydrated
use_tenant_renewal_defaultswhen boolean
- normalized
- Rationale: resumed drafts now carry renewal metadata into
editingContractso wizard state merge can restore renewal settings.
- Extended
- (2026-02-21) Completed
T003.- Added
packages/billing/src/actions/contractWizardActions.renewalDraftResumeWiring.test.ts. - Test validates:
- renewal fields are present on
DraftContractWizardData, getDraftContractForResumereturns hydrated renewal values,- numeric renewal values are sanitized before payload return.
- renewal fields are present on
- Added
- (2026-02-21) Completed
F004.- Added
buildInitialContractWizardData(editingContract)inpackages/billing/src/components/billing-dashboard/contracts/ContractWizard.tsx. - Edit-mode initialization now explicitly normalizes renewal fields during hydration:
- validates
renewal_modedomain, - normalizes non-negative
notice_period_days, - normalizes positive
renewal_term_months, - preserves explicit boolean
use_tenant_renewal_defaults.
- validates
- Wired both initial state and open-effect initialization to use this shared edit-hydration path.
- Added
- (2026-02-21) Completed
T004.- Extended
packages/billing/src/components/billing-dashboard/contracts/ContractWizard.renewalFields.test.ts. - Added assertions proving edit hydration path uses
buildInitialContractWizardData(editingContract)and renewal normalization helpers for mode/notice/term.
- Extended
- (2026-02-21) Completed
F005.- Added a fixed-term renewal UI container to
packages/billing/src/components/billing-dashboard/contracts/wizard-steps/ContractBasicsStep.tsx. - New
Renewal Settingscard renders only whendata.end_dateis present (data-automation-id=\"renewal-settings-fixed-term-card\").
- Added a fixed-term renewal UI container to
- (2026-02-21) Completed
T005.- Added
packages/billing/src/components/billing-dashboard/contracts/wizard-steps/ContractBasicsStep.renewalCards.test.ts. - Test asserts fixed-term card conditional wiring on
data.end_dateand verifies the automation id/heading token.
- Added
- (2026-02-21) Completed
F006.- Added evergreen variant UI in
packages/billing/src/components/billing-dashboard/contracts/wizard-steps/ContractBasicsStep.tsx. - New
Evergreen Review Settingscard renders whendata.end_dateis absent (data-automation-id=\"renewal-settings-evergreen-card\").
- Added evergreen variant UI in
- (2026-02-21) Completed
T006.- Extended
packages/billing/src/components/billing-dashboard/contracts/wizard-steps/ContractBasicsStep.renewalCards.test.tswith evergreen-card assertions. - Verifies absent-end-date branch and
renewal-settings-evergreen-cardwiring.
- Extended
- (2026-02-21) Completed
F007.- Added renewal mode selector UI to both fixed-term and evergreen renewal cards in
packages/billing/src/components/billing-dashboard/contracts/wizard-steps/ContractBasicsStep.tsx. - Options now explicitly include
none,manual, andauto, bound todata.renewal_mode.
- Added renewal mode selector UI to both fixed-term and evergreen renewal cards in
- (2026-02-21) Completed
T007.- Extended
packages/billing/src/components/billing-dashboard/contracts/wizard-steps/ContractBasicsStep.renewalCards.test.ts. - Added assertions for
renewalModeOptionsvalues (none|manual|auto) andupdateDatabinding back torenewal_mode.
- Extended
- (2026-02-21) Completed
F008.- Added
Notice Period (Days)input to both renewal cards inpackages/billing/src/components/billing-dashboard/contracts/wizard-steps/ContractBasicsStep.tsx. - Input is conditionally rendered only when renewal mode is enabled (
manualorauto), with non-negative integer coercion on change.
- Added
- (2026-02-21) Completed
T008.- Extended
packages/billing/src/components/billing-dashboard/contracts/wizard-steps/ContractBasicsStep.renewalCards.test.tswith notice-period assertions. - Confirms
isRenewalEnabledgate and both notice input IDs (fixedandevergreen) are present in the renewal-enabled branch.
- Extended
- (2026-02-21) Completed
F009.- Added auto-renew specific
Renewal Term (Months)inputs to fixed-term and evergreen renewal cards inpackages/billing/src/components/billing-dashboard/contracts/wizard-steps/ContractBasicsStep.tsx. - Input is gated by
isAutoRenewand writes sanitized positive integer values torenewal_term_months.
- Added auto-renew specific
- (2026-02-21) Completed
F010.- Confirmed auto-renew term controls are hidden unless
effectiveRenewalMode === 'auto'viaisAutoRenewconditional rendering inContractBasicsStep.tsx.
- Confirmed auto-renew term controls are hidden unless
- (2026-02-21) Completed
T009.- Extended
packages/billing/src/components/billing-dashboard/contracts/wizard-steps/ContractBasicsStep.renewalCards.test.tswith auto-term wiring assertions. - Verifies both term input IDs and positive-integer assignment path for
renewal_term_months.
- Extended
- (2026-02-21) Completed
T010.- Added explicit
isAutoRenewgating assertions inContractBasicsStep.renewalCards.test.ts. - Verifies auto-specific term controls are conditionally rendered only in
automode.
- Added explicit
- (2026-02-21) Completed
F011.- Added step-0 wizard validation in
packages/billing/src/components/billing-dashboard/contracts/ContractWizard.tsx:- if
end_dateis set andrenewal_modeis missing, progression is blocked with inline error.
- if
- Added step-0 wizard validation in
- (2026-02-21) Completed
F012.- Added notice-period validation bounds in
ContractWizard.tsx(MIN_NOTICE_PERIOD_DAYS=0,MAX_NOTICE_PERIOD_DAYS=3650). - Step-0 validation now requires notice period to be an integer and within bounds whenever renewal mode is enabled.
- Added notice-period validation bounds in
- (2026-02-21) Completed
F013.- Added step-0 validation rule in
ContractWizard.tsxrequiringrenewal_term_monthsto be a positive integer when provided.
- Added step-0 validation rule in
- (2026-02-21) Completed
F014.- Renewal validation errors from step-0 rules (
F011-F013) now surface through the wizard’s existing inline step error panel before progression.
- Renewal validation errors from step-0 rules (
- (2026-02-21) Completed
T011.- Extended
packages/billing/src/components/billing-dashboard/contracts/ContractWizard.renewalFields.test.tswith assertions for required renewal mode whenend_dateis set.
- Extended
- (2026-02-21) Completed
T012.- Marked covered by the same
ContractWizard.renewalFields.test.tsadditions that assert notice-period integer/bounds validation wiring.
- Marked covered by the same
- (2026-02-21) Completed
T013.- Marked covered by existing
ContractWizard.renewalFields.test.tsassertions for positive renewal-term validation when value is provided.
- Marked covered by existing
- (2026-02-21) Completed
T014.- Marked covered by existing
ContractWizard.renewalFields.test.tsassertion that inline step error rendering (errors[currentStep]) is present for renewal validation failures.
- Marked covered by existing
- (2026-02-21) Completed
F015.- Extended
ContractBasicsStepsummary alert to include renewal preview fields:- renewal mode label,
- notice period (for renewal-enabled modes),
- renewal term months (auto-renew mode).
- Extended
- (2026-02-21) Completed
F016.- Extended
ReviewContractStep“Contract Basics” card to preview renewal fields before submit:- renewal mode,
- notice period,
- renewal term (auto mode).
- Extended
- (2026-02-21) Completed
F017.- Added renewal fields to
ClientContractWizardSubmission(packages/billing/src/actions/contractWizardActions.ts). - Updated
buildSubmissionData()inContractWizard.tsxto include renewal mode, notice period, renewal term, and tenant-default toggle in outgoing wizard payload.
- Added renewal fields to
- (2026-02-21) Completed
F018.- Updated
createClientContractFromWizardinsert path forclient_contractsto persist renewal fields. - Added schema-compat guards (
hasColumn) so renewal columns are written when available without breaking pre-migration environments.
- Updated
- (2026-02-21) Completed
T015.- Extended
ContractBasicsStep.renewalCards.test.tsto assert renewal mode/notice/term rows are present in the Contract Basics summary preview.
- Extended
- (2026-02-21) Completed
T016.- Added
packages/billing/src/components/billing-dashboard/contracts/wizard-steps/ReviewContractStep.renewalPreview.test.ts. - Test covers renewal preview rows and mode-gated rendering conditions in the review step.
- Added
- (2026-02-21) Completed
T017.- Extended
ContractWizard.renewalFields.test.tsto assertbuildSubmissionData()includes all renewal fields in outgoing wizard payload.
- Extended
- (2026-02-21) Completed
T018.- Extended
contractWizardActions.renewalDraftResumeWiring.test.tsto assert draft/client save path writes renewal fields intoclient_contractswith schema-guardedhasColumnchecks.
- Extended
- (2026-02-21) Completed
F019.- Extended tenant default billing settings model surface in
packages/billing/src/actions/billingSettingsActions.tsandserver/src/interfaces/billing.interfaces.tswith renewal-default fields (including default renewal mode) using schema-guarded writes for compatibility.
- Extended tenant default billing settings model surface in
- (2026-02-21) Completed
F020.- Included
defaultNoticePeriodDaysmapping (default_notice_period_days) in tenant default billing settings model and guarded write path.
- Included
- (2026-02-21) Completed
F021.- Included
renewalDueDateActionPolicymapping (renewal_due_date_action_policy) with normalized fallback in tenant billing settings model.
- Included
- (2026-02-21) Completed
F022.- Included tenant default renewal ticket board field mapping (
renewal_ticket_board_id) in billing settings model/read-write path.
- Included tenant default renewal ticket board field mapping (
- (2026-02-21) Completed
F023.- Included tenant default renewal ticket status field mapping (
renewal_ticket_status_id) in billing settings model/read-write path.
- Included tenant default renewal ticket status field mapping (
- (2026-02-21) Completed
F024.- Included tenant default renewal ticket priority field mapping (
renewal_ticket_priority) in billing settings model/read-write path.
- Included tenant default renewal ticket priority field mapping (
- (2026-02-21) Completed
F025.- Included tenant default renewal ticket assignee field mapping (
renewal_ticket_assignee_id) in billing settings model/read-write path.
- Included tenant default renewal ticket assignee field mapping (
- (2026-02-21) Completed
F026.getDefaultBillingSettingsnow returns renewal default fields (mode, notice days, due-date policy, ticket routing defaults) with deterministic fallbacks.
- (2026-02-21) Completed
F027.updateDefaultBillingSettingsnow writes renewal default fields via schema-guarded update/insert payloads.
- (2026-02-21) Completed
T019.- Added
packages/billing/src/actions/billingSettingsActions.renewalDefaultsWiring.test.tsand marked renewal-mode model coverage.
- Added
- (2026-02-21) Completed
T020.- Covered by existing
billingSettingsActions.renewalDefaultsWiring.test.tsassertions fordefaultNoticePeriodDays.
- Covered by existing
- (2026-02-21) Completed
T021.- Covered by existing
billingSettingsActions.renewalDefaultsWiring.test.tsassertions forrenewalDueDateActionPolicy.
- Covered by existing
- (2026-02-21) Completed
T022.- Covered by existing
billingSettingsActions.renewalDefaultsWiring.test.tsassertions forrenewalTicketBoardId.
- Covered by existing
- (2026-02-21) Completed
T023.- Covered by existing
billingSettingsActions.renewalDefaultsWiring.test.tsassertions forrenewalTicketStatusId.
- Covered by existing
- (2026-02-21) Completed
T024.- Covered by existing
billingSettingsActions.renewalDefaultsWiring.test.tsassertions forrenewalTicketPriority.
- Covered by existing
- (2026-02-21) Completed
T025.- Covered by existing
billingSettingsActions.renewalDefaultsWiring.test.tsassertions forrenewalTicketAssigneeId.
- Covered by existing
- (2026-02-21) Completed
T026.- Covered by existing
billingSettingsActions.renewalDefaultsWiring.test.tsassertions forgetDefaultBillingSettingsrenewal default response mapping.
- Covered by existing
- (2026-02-21) Completed
T027.- Covered by existing
billingSettingsActions.renewalDefaultsWiring.test.tsassertions for schema-guarded renewal default persistence in update writes.
- Covered by existing
- (2026-02-21) Completed
T028.- Extended renewal UI/source tests to assert
Use Tenant Renewal Defaultstoggle controls and payload field wiring (use_tenant_renewal_defaults).
- Extended renewal UI/source tests to assert
- (2026-02-21) Completed
T029.- Covered by
ContractWizard.renewalFields.test.tsassertions that tenant defaults are applied in submission resolution when toggle is enabled.
- Covered by
- (2026-02-21) Completed
T030.- Covered by
packages/billing/src/components/billing-dashboard/contracts/ContractWizard.renewalFields.test.tsassertion:prefers explicit contract override values when tenant defaults are disabled.
- Validation run:
cd server && npx vitest run --coverage.enabled=false ../packages/billing/src/components/billing-dashboard/contracts/ContractWizard.renewalFields.test.ts
- Covered by
- (2026-02-21) Completed
T031.- Covered by
packages/billing/src/components/billing-dashboard/contracts/ContractWizard.renewalFields.test.tsassertion:uses deterministic fallback precedence for partial override/default state.
- Validation run:
cd server && npx vitest run --coverage.enabled=false ../packages/billing/src/components/billing-dashboard/contracts/ContractWizard.renewalFields.test.ts
- Covered by
- (2026-02-21) Completed
F028.- Added explicit
Use Tenant Renewal Defaultstoggle controls to both fixed-term and evergreen renewal settings cards inContractBasicsStep.tsx, bound touse_tenant_renewal_defaults.
- Added explicit
- (2026-02-21) Completed
F029.- Updated
buildSubmissionData()inContractWizard.tsxto resolve renewal mode + notice period from tenant defaults whenuse_tenant_renewal_defaultsis enabled.
- Updated
- (2026-02-21) Completed
F030.- Submission resolution now prefers explicit contract-level renewal values when
use_tenant_renewal_defaultsis disabled.
- Submission resolution now prefers explicit contract-level renewal values when
- (2026-02-21) Completed
F031.- Implemented deterministic renewal fallback order in submission resolution:
- explicit contract values (when overrides enabled),
- tenant defaults,
- hard defaults (
manual,30).
- Implemented deterministic renewal fallback order in submission resolution:
- (2026-02-21) Completed
F032.- Extended contract-assignment read APIs to expose normalized/effective renewal settings in both shared and clients data-access layers:
shared/billingClients/clientContracts.tspackages/clients/src/models/clientContract.ts
- Added schema-guarded tenant-default joins (
default_billing_settings) for read paths and computed:effective_renewal_modeeffective_notice_period_days
- Added type surface fields on
IClientContractin:packages/types/src/interfaces/contract.interfaces.tsserver/src/interfaces/contract.interfaces.ts
- Validation run:
npm -w @alga-psa/shared run typechecknpm -w @alga-psa/clients run typechecknpm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/clientContractEffectiveRenewalSettings.test.ts
- Extended contract-assignment read APIs to expose normalized/effective renewal settings in both shared and clients data-access layers:
- (2026-02-21) Completed
F033.- Added fixed-term
decision_due_datecomputation in assignment normalization paths:shared/billingClients/clientContracts.tspackages/clients/src/models/clientContract.ts
- Formula implemented with date-only semantics for fixed-term contracts:
decision_due_date = end_date - effective_notice_period_days
- Added
decision_due_dateto contract interfaces:packages/types/src/interfaces/contract.interfaces.tsserver/src/interfaces/contract.interfaces.ts
- Expanded test coverage in
packages/billing/tests/clientContractEffectiveRenewalSettings.test.ts.
- Added fixed-term
- (2026-02-21) Completed
F034.- Added evergreen annual-review anchor computation based on contract start-date anniversary rules.
- New shared helper:
computeNextEvergreenReviewAnchorDateinshared/billingClients/clientContracts.ts
- Exposed normalized field on active evergreen assignments:
evergreen_review_anchor_date
- Mirrored logic in clients model read normalization for parity:
packages/clients/src/models/clientContract.ts
- Expanded tests in
packages/billing/tests/clientContractEffectiveRenewalSettings.test.ts.
- (2026-02-21) Completed
F035.- Added evergreen
decision_due_datecomputation from annual anchor minus effective notice period. - New shared helper:
computeEvergreenDecisionDueDateinshared/billingClients/clientContracts.ts
- Applied in both read normalization paths (shared + clients model) so evergreen assignments now expose date-only
decision_due_date. - Expanded deterministic date-math coverage in
packages/billing/tests/clientContractEffectiveRenewalSettings.test.ts.
- Added evergreen
- (2026-02-21) Completed
F036.- Confirmed and codified date-only normalization for
decision_due_datemath usingnormalizeDateOnly+ UTC midnight subtraction paths. - Added regression test proving timestamp
end_dateinputs are normalized to date-only before subtraction:packages/billing/tests/clientContractEffectiveRenewalSettings.test.ts
- Confirmed and codified date-only normalization for
- (2026-02-21) Completed
F037.- Confirmed
decision_due_daterecalculates from current assignment state when fixed-termend_datechanges. - Added regression coverage:
recomputes fixed-term decision_due_date when end_date changes- in
packages/billing/tests/clientContractEffectiveRenewalSettings.test.ts
- Confirmed
- (2026-02-21) Completed
F038.- Confirmed fixed-term
decision_due_daterecalculates when notice period changes. - Added regression coverage:
recomputes fixed-term decision_due_date when notice period changes- in
packages/billing/tests/clientContractEffectiveRenewalSettings.test.ts
- Confirmed fixed-term
- (2026-02-21) Completed
F039.- Made
decision_due_dategeneration renewal-mode-aware in read normalization:- mode
nonesuppresses due date generation for non-evergreen entries.
- mode
- Added regression coverage for mode transitions:
recomputes decision_due_date when renewal mode changes between none/manual/auto- in
packages/billing/tests/clientContractEffectiveRenewalSettings.test.ts
- Made
- (2026-02-21) Completed
F040.- Confirmed evergreen
decision_due_daterecomputes when anniversary anchor basis changes (start-date basis change). - Added deterministic coverage:
recomputes evergreen decision_due_date when anniversary anchor basis changes- in
packages/billing/tests/clientContractEffectiveRenewalSettings.test.ts
- Confirmed evergreen
- (2026-02-21) Completed
F041.- Added lifecycle suppression in due-date normalization:
- no
decision_due_dategeneration for inactive, terminated, or expired assignment/contract lifecycle state.
- no
- Included
contract_statusfrom joined contract reads in shared/clients assignment APIs to enforce lifecycle gating. - Added regression test:
skips decision_due_date generation for inactive/terminated assignments- in
packages/billing/tests/clientContractEffectiveRenewalSettings.test.ts
- Added lifecycle suppression in due-date normalization:
- (2026-02-21) Completed
F042.- Verified suppression path for
renewal_mode = nonewhen no evergreen anchor is available (e.g. fixed-term assignment) remains enforced. - Covered by existing regression test:
recomputes decision_due_date when renewal mode changes between none/manual/auto- in
packages/billing/tests/clientContractEffectiveRenewalSettings.test.ts
- Verified suppression path for
- (2026-02-21) Completed
F043.- Added derived per-cycle dedupe key in read normalization:
renewal_cycle_key(fixed-term:<end_date>orevergreen:<anchor_date>)
- Exposed in both shared and clients assignment APIs plus contract interfaces.
- Added regression coverage:
creates one renewal_cycle_key per computed contract cycle for deduplication- in
packages/billing/tests/clientContractEffectiveRenewalSettings.test.ts
- Added derived per-cycle dedupe key in read normalization:
- (2026-02-21) Completed
F044.- Added deterministic dedupe guard for active assignment rows by composite key:
tenant + client_contract_id + renewal_cycle_key
- Applied dedupe in list read APIs:
shared/billingClients/clientContracts.tspackages/clients/src/models/clientContract.ts
- Added regression test:
deduplicates active rows by tenant + client_contract_id + renewal_cycle_key- in
packages/billing/tests/clientContractEffectiveRenewalSettings.test.ts
- Added deterministic dedupe guard for active assignment rows by composite key:
- (2026-02-21) Completed
F045.- Added explicit cycle boundary fields in normalization:
renewal_cycle_startrenewal_cycle_end
- Fixed-term boundaries map directly to assignment
start_date/end_date. - Evergreen boundaries now use annual cycle bounds helper:
computeEvergreenCycleBoundsinshared/billingClients/clientContracts.ts
- Added deterministic coverage in
packages/billing/tests/clientContractEffectiveRenewalSettings.test.ts.
- Added explicit cycle boundary fields in normalization:
- (2026-02-21) Completed
F046.- Added derived
days_until_duefield to assignment normalization and contract interfaces. - New date-only helper:
computeDaysUntilDateinshared/billingClients/clientContracts.ts
- Added deterministic coverage for positive/negative day deltas and normalized row field presence in:
packages/billing/tests/clientContractEffectiveRenewalSettings.test.ts
- Added derived
- (2026-02-21) Completed
F047.- Added clamp bounds to
days_until_duederivation to preserve overdue visibility while preventing extreme negative/positive corruption:MAX_ABSOLUTE_DAYS_UNTIL_DUE = 36500
- Applied in shared and clients normalization helpers.
- Added deterministic clamp coverage in:
packages/billing/tests/clientContractEffectiveRenewalSettings.test.ts
- Added clamp bounds to
- (2026-02-21) Completed
F048.- Added
renewalstab value to billing tab union/config metadata in:packages/billing/src/components/billing-dashboard/billingTabsConfig.ts
- Added tab definition (
label=Renewals,href=/msp/billing?tab=renewals) and icon mapping. - Added coverage:
packages/billing/tests/billingTabsConfig.renewals.test.ts
- Added
- (2026-02-21) Completed
F049.- Added
Tabs.Content value=\"renewals\"route to billing dashboard tab host in:packages/billing/src/components/billing-dashboard/BillingDashboard.tsx
- Added initial placeholder content for the renewals route host.
- Added route-wiring coverage:
packages/billing/tests/BillingDashboard.renewalsRoute.test.ts
- Added
- (2026-02-21) Completed
F050.- Added dedicated renewals queue page component:
packages/billing/src/components/billing-dashboard/contracts/RenewalsQueueTab.tsx
- Updated
BillingDashboardrenewals route to render<RenewalsQueueTab />. - Added component + wiring coverage:
packages/billing/tests/RenewalsQueueTab.component.test.tspackages/billing/tests/BillingDashboard.renewalsRoute.test.ts
- Added dedicated renewals queue page component:
- (2026-02-21) Completed
F051.- Added server action to load renewal queue rows:
packages/billing/src/actions/renewalsQueueActions.ts
- Renewals page now calls
listRenewalQueueRows()on mount viauseEffectand renders loading/empty/error/data states. - Exported renewals queue actions via:
packages/billing/src/actions/index.ts
- Added wiring coverage:
packages/billing/tests/renewalsQueueActions.wiring.test.tspackages/billing/tests/RenewalsQueueTab.component.test.ts
- Added server action to load renewal queue rows:
- (2026-02-21) Completed
F052.- Added default 90-day horizon behavior to renewals queue loading:
DEFAULT_RENEWALS_HORIZON_DAYS = 90inrenewalsQueueActions.ts- server-side filtering for
days_until_duein range[0, horizonDays]
- Updated renewals UI copy to indicate default horizon window.
- Extended wiring coverage in:
packages/billing/tests/renewalsQueueActions.wiring.test.tspackages/billing/tests/RenewalsQueueTab.component.test.ts
- Added default 90-day horizon behavior to renewals queue loading:
- (2026-02-21) Completed
F053.- Added renewals queue bucket quick filters in
RenewalsQueueTab:All,0-30 Days,31-60 Days,61-90 Days
- Implemented client-side bucket filtering against
days_until_due. - Extended component coverage in:
packages/billing/tests/RenewalsQueueTab.component.test.ts
- Added renewals queue bucket quick filters in
- (2026-02-21) Completed
F054.- Added owner filter UI + behavior in
RenewalsQueueTab:- owner options derive from queue row
assigned_tovalues withunassignedfallback.
- owner options derive from queue row
- Extended queue row shape from server action with
assigned_to. - Added wiring coverage updates in:
packages/billing/tests/RenewalsQueueTab.component.test.tspackages/billing/tests/renewalsQueueActions.wiring.test.ts
- Added owner filter UI + behavior in
- (2026-02-21) Completed
F055.- Added queue status mapping + filter support for:
pending,renewing,non_renewing,snoozed,completed
- Added status filter UI + filtering behavior in
RenewalsQueueTab. - Extended action/component wiring coverage in:
packages/billing/tests/renewalsQueueActions.wiring.test.tspackages/billing/tests/RenewalsQueueTab.component.test.ts
- Added queue status mapping + filter support for:
- (2026-02-21) Completed
F056.- Added renewal mode filter support in queue UI for:
none,manual,auto
- Queue row mapping already includes
effective_renewal_mode; UI filtering now applies this dimension. - Extended action/component wiring coverage in:
packages/billing/tests/renewalsQueueActions.wiring.test.tspackages/billing/tests/RenewalsQueueTab.component.test.ts
- Added renewal mode filter support in queue UI for:
- (2026-02-21) Completed
F057.- Added contract type filter support in queue UI for:
fixed-term,evergreen
- Filter operates on queue row
contract_type. - Extended component wiring coverage in:
packages/billing/tests/RenewalsQueueTab.component.test.ts
- Added contract type filter support in queue UI for:
- (2026-02-21) Completed
F058.- Enforced default queue sort by
decision_due_dateascending in renewals list action. - Sorting now occurs after normalization/horizon filtering in:
packages/billing/src/actions/renewalsQueueActions.ts
- Added wiring coverage update in:
packages/billing/tests/renewalsQueueActions.wiring.test.ts
- Enforced default queue sort by
- (2026-02-21) Completed
F059.- Added days-remaining visual badge state logic in queue rows:
overdue,due-soon,upcoming
- Rendering now surfaces overdue and due-soon emphasis states via row badge styles.
- Added component coverage update in:
packages/billing/tests/RenewalsQueueTab.component.test.ts
- Added days-remaining visual badge state logic in queue rows:
- (2026-02-21) Completed
F060.- Added
Upcoming Renewalssummary widget toClientContractsTabwith queue-derived total count. - Widget data source now loads via
listRenewalQueueRows()during tab fetch flow. - Added coverage:
packages/billing/tests/ClientContractsTab.upcomingRenewalsWidget.test.ts
- Added
- (2026-02-21) Completed
F061.- Updated
Upcoming Renewalswidget to display 90-day bucket counts:0-30,31-60,61-90
- Counts now derive from renewal queue row
days_until_due. - Added coverage update in:
packages/billing/tests/ClientContractsTab.upcomingRenewalsWidget.test.ts
- Updated
- (2026-02-21) Completed
F062.- Added widget-to-queue navigation with preserved bucket context in:
packages/billing/src/components/billing-dashboard/contracts/ClientContractsTab.tsx
- Bucket count badges now route to:
/msp/billing?tab=renewals&bucket=0-30|31-60|61-90
- Added queue hydration from URL bucket query param in:
packages/billing/src/components/billing-dashboard/contracts/RenewalsQueueTab.tsx
- Added/updated coverage in:
packages/billing/tests/ClientContractsTab.upcomingRenewalsWidget.test.tspackages/billing/tests/RenewalsQueueTab.component.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/ClientContractsTab.upcomingRenewalsWidget.test.ts tests/RenewalsQueueTab.component.test.ts
- Added widget-to-queue navigation with preserved bucket context in:
- (2026-02-21) Completed
F063.- Added queue-to-widget refresh wiring in billing dashboard:
packages/billing/src/components/billing-dashboard/BillingDashboard.tsx
BillingDashboardnow incrementsrenewalsQueueRefreshTriggerwhen renewals queue refreshes after mutation pathways.- Passed refresh trigger into
ClientContractsTabso upcoming renewals bucket counts are recomputed. RenewalsQueueTabnow acceptsonQueueMutationCompleteand emits it after successful queue row reloads:packages/billing/src/components/billing-dashboard/contracts/RenewalsQueueTab.tsx
- Added wiring coverage in:
packages/billing/tests/BillingDashboard.renewalsRoute.test.tspackages/billing/tests/RenewalsQueueTab.component.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/BillingDashboard.renewalsRoute.test.ts tests/RenewalsQueueTab.component.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts
- Added queue-to-widget refresh wiring in billing dashboard:
- (2026-02-21) Completed
F064.- Defined centralized renewal queue status enum in shared contract interfaces:
packages/types/src/interfaces/contract.interfaces.tsserver/src/interfaces/contract.interfaces.ts
- Added renewal work-item interface model (
IClientContractRenewalWorkItem) withstatus: RenewalWorkItemStatus. - Updated queue row model/status normalization to consume
RenewalWorkItemStatusfrom shared types:packages/billing/src/actions/renewalsQueueActions.ts
- Updated wiring coverage:
packages/billing/tests/renewalsQueueActions.wiring.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.wiring.test.ts tests/RenewalsQueueTab.component.test.tsnpm -w @alga-psa/server run typecheck(workspace alias not present in root workspaces)
- Defined centralized renewal queue status enum in shared contract interfaces:
- (2026-02-21) Completed
F065.- Added queue mutation action to transition pending work items to renewing:
markRenewalQueueItemRenewing(clientContractId)inpackages/billing/src/actions/renewalsQueueActions.ts
- Transition behavior:
- validates required
clientContractId - enforces tenant-scoped active row lookup
- requires current status to resolve as
pending - updates status to
renewingand writesupdated_at
- validates required
- Added mutation response payload shape:
RenewalQueueMutationResult
- Added/updated wiring coverage:
packages/billing/tests/renewalsQueueActions.wiring.test.tspackages/billing/tests/renewalsQueueActions.markRenewing.wiring.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.wiring.test.ts tests/renewalsQueueActions.markRenewing.wiring.test.ts
- Added queue mutation action to transition pending work items to renewing:
- (2026-02-21) Completed
F066.- Added queue mutation action to transition pending work items to non-renewing:
markRenewalQueueItemNonRenewing(clientContractId)inpackages/billing/src/actions/renewalsQueueActions.ts
- Transition behavior mirrors mark-renewing safeguards:
- validates required
clientContractId - verifies status column availability
- enforces tenant-scoped active row lookup
- requires current status to resolve as
pending - updates status to
non_renewingand writesupdated_at
- validates required
- Added wiring coverage:
packages/billing/tests/renewalsQueueActions.markNonRenewing.wiring.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.markRenewing.wiring.test.ts tests/renewalsQueueActions.markNonRenewing.wiring.test.ts
- Added queue mutation action to transition pending work items to non-renewing:
- (2026-02-21) Completed
F067.- Added renewal draft action for eligible queue entries:
createRenewalDraftForQueueItem(clientContractId)inpackages/billing/src/actions/renewalsQueueActions.ts
- Action behavior:
- requires non-empty
clientContractId - resolves eligible statuses to
pending|renewingonly - creates a new draft contract + draft client contract assignment
- reuses existing linked draft when
created_draft_contract_idis already present and valid - links original row via
created_draft_contract_idwhen column exists
- requires non-empty
- Added response type:
RenewalDraftCreationResult
- Added wiring coverage:
packages/billing/tests/renewalsQueueActions.createDraft.wiring.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.wiring.test.ts tests/renewalsQueueActions.markRenewing.wiring.test.ts tests/renewalsQueueActions.markNonRenewing.wiring.test.ts tests/renewalsQueueActions.createDraft.wiring.test.ts
- Added renewal draft action for eligible queue entries:
- (2026-02-21) Completed
F068.- Added snooze mutation action:
snoozeRenewalQueueItem(clientContractId, snoozedUntil)inpackages/billing/src/actions/renewalsQueueActions.ts
- Action behavior:
- validates required
clientContractId+snoozedUntil - verifies
status+snoozed_untilcolumns exist - normalizes
snoozed_untilto date-only (YYYY-MM-DD) - blocks snoozing from terminal statuses (
completed,non_renewing) - updates status to
snoozedand returnsRenewalSnoozeResult
- validates required
- Added wiring coverage:
packages/billing/tests/renewalsQueueActions.snooze.wiring.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.snooze.wiring.test.ts tests/renewalsQueueActions.markRenewing.wiring.test.ts tests/renewalsQueueActions.markNonRenewing.wiring.test.ts tests/renewalsQueueActions.createDraft.wiring.test.ts
- Added snooze mutation action:
- (2026-02-21) Completed
F069.- Added assign-owner mutation action:
assignRenewalQueueItemOwner(clientContractId, assignedTo)inpackages/billing/src/actions/renewalsQueueActions.ts
- Action behavior:
- validates required
clientContractId - allows
assignedToas user id string ornull(unassign) - verifies
status+assigned_tocolumns exist - updates
assigned_towith tenant-scoped row filtering - returns
RenewalAssignmentResultwith current status + updated timestamp
- validates required
- Added wiring coverage:
packages/billing/tests/renewalsQueueActions.assignOwner.wiring.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.assignOwner.wiring.test.ts tests/renewalsQueueActions.snooze.wiring.test.ts tests/renewalsQueueActions.createDraft.wiring.test.ts
- Added assign-owner mutation action:
- (2026-02-21) Completed
F070.- Added automatic unsnooze transition during queue list refresh in:
packages/billing/src/actions/renewalsQueueActions.ts
- Behavior:
- checks
status+snoozed_untilcolumns - moves eligible rows from
snoozedtopendingwhensnoozed_until <= today - clears
snoozed_untiland updatesupdated_at
- checks
- Added wiring coverage:
packages/billing/tests/renewalsQueueActions.unsnooze.wiring.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.unsnooze.wiring.test.ts tests/renewalsQueueActions.wiring.test.ts tests/renewalsQueueActions.snooze.wiring.test.ts
- Added automatic unsnooze transition during queue list refresh in:
- (2026-02-21) Completed
F071.- Added actor audit persistence helper flow in renewal queue actions:
resolveActorUserId(user)withActionActor(updateData, hasLastActionByColumn, actorUserId)
- User-initiated queue mutations now persist
last_action_bywhen column exists:markRenewalQueueItemRenewingmarkRenewalQueueItemNonRenewingcreateRenewalDraftForQueueItemsnoozeRenewalQueueItemassignRenewalQueueItemOwner
- Added wiring coverage:
packages/billing/tests/renewalsQueueActions.actorAudit.wiring.test.ts
- Updated wiring expectations for mark actions:
packages/billing/tests/renewalsQueueActions.markRenewing.wiring.test.tspackages/billing/tests/renewalsQueueActions.markNonRenewing.wiring.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.actorAudit.wiring.test.ts tests/renewalsQueueActions.markRenewing.wiring.test.ts tests/renewalsQueueActions.markNonRenewing.wiring.test.ts tests/renewalsQueueActions.createDraft.wiring.test.ts tests/renewalsQueueActions.snooze.wiring.test.ts tests/renewalsQueueActions.assignOwner.wiring.test.ts
- Added actor audit persistence helper flow in renewal queue actions:
- (2026-02-21) Completed
F072.- Added timestamp audit persistence helper in renewal queue actions:
withActionTimestamp(updateData, hasLastActionAtColumn, actionAt)
- User-initiated queue mutations now persist
last_action_atwhen column exists:markRenewalQueueItemRenewingmarkRenewalQueueItemNonRenewingcreateRenewalDraftForQueueItemsnoozeRenewalQueueItemassignRenewalQueueItemOwner
- Added wiring coverage:
packages/billing/tests/renewalsQueueActions.timestampAudit.wiring.test.ts
- Updated wiring expectations for mark/actor tests:
packages/billing/tests/renewalsQueueActions.markRenewing.wiring.test.tspackages/billing/tests/renewalsQueueActions.markNonRenewing.wiring.test.tspackages/billing/tests/renewalsQueueActions.actorAudit.wiring.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.timestampAudit.wiring.test.ts tests/renewalsQueueActions.actorAudit.wiring.test.ts tests/renewalsQueueActions.markRenewing.wiring.test.ts tests/renewalsQueueActions.markNonRenewing.wiring.test.ts tests/renewalsQueueActions.createDraft.wiring.test.ts tests/renewalsQueueActions.snooze.wiring.test.ts tests/renewalsQueueActions.assignOwner.wiring.test.ts
- Added timestamp audit persistence helper in renewal queue actions:
- (2026-02-21) Completed
F073.- Added optional queue action note support across mutation actions:
markRenewalQueueItemRenewing(..., note?)markRenewalQueueItemNonRenewing(..., note?)createRenewalDraftForQueueItem(..., note?)snoozeRenewalQueueItem(..., note?)assignRenewalQueueItemOwner(..., note?)
- Added note helpers:
normalizeActionNote(note)withActionNote(updateData, hasLastActionNoteColumn, note)
- Mutations now persist
last_action_notewhen column exists and note is non-empty. - Added wiring coverage:
packages/billing/tests/renewalsQueueActions.noteAudit.wiring.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.noteAudit.wiring.test.ts tests/renewalsQueueActions.timestampAudit.wiring.test.ts tests/renewalsQueueActions.actorAudit.wiring.test.ts tests/renewalsQueueActions.markRenewing.wiring.test.ts tests/renewalsQueueActions.markNonRenewing.wiring.test.ts tests/renewalsQueueActions.createDraft.wiring.test.ts tests/renewalsQueueActions.snooze.wiring.test.ts tests/renewalsQueueActions.assignOwner.wiring.test.ts
- Added optional queue action note support across mutation actions:
- (2026-02-21) Completed
F074.- Added explicit completed-status guard in automatic unsnooze pending-transition path:
packages/billing/src/actions/renewalsQueueActions.ts
- Unsnooze update now includes:
.andWhereNot('status', 'completed')
- This ensures completed work items never implicitly transition back to pending without an explicit reopen flow.
- Updated coverage:
packages/billing/tests/renewalsQueueActions.unsnooze.wiring.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.unsnooze.wiring.test.ts tests/renewalsQueueActions.noteAudit.wiring.test.ts tests/renewalsQueueActions.timestampAudit.wiring.test.ts
- Added explicit completed-status guard in automatic unsnooze pending-transition path:
- (2026-02-21) Completed
F075.- Added explicit override guard to renewing transition:
markRenewalQueueItemRenewingnow rejectspreviousStatus === 'non_renewing'with an override-required error.
- This preserves strict non-renewal intent unless a dedicated override flow is implemented.
- Updated wiring coverage:
packages/billing/tests/renewalsQueueActions.markRenewing.wiring.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.markRenewing.wiring.test.ts tests/renewalsQueueActions.markNonRenewing.wiring.test.ts
- Added explicit override guard to renewing transition:
- (2026-02-21) Completed
F076.- Added future-date enforcement for snooze action validation:
snoozeRenewalQueueItemnow rejectssnoozedUntil <= today
- Added explicit error path:
Snooze target date must be in the future
- Updated wiring coverage:
packages/billing/tests/renewalsQueueActions.snooze.wiring.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.snooze.wiring.test.ts tests/renewalsQueueActions.unsnooze.wiring.test.ts
- Added future-date enforcement for snooze action validation:
- (2026-02-21) Completed
F077.- Added row-level action availability model based on effective queue status:
RenewalQueueActionuniongetAvailableActionsForStatus(status)inpackages/billing/src/actions/renewalsQueueActions.ts
listRenewalQueueRowsnow returnsavailable_actionsfor each row.- Renewals queue UI now surfaces available actions per row:
Actions: {row.available_actions.join(', ')}inpackages/billing/src/components/billing-dashboard/contracts/RenewalsQueueTab.tsx
- Updated coverage:
packages/billing/tests/renewalsQueueActions.wiring.test.tspackages/billing/tests/RenewalsQueueTab.component.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.wiring.test.ts tests/RenewalsQueueTab.component.test.ts
- Added row-level action availability model based on effective queue status:
- (2026-02-21) Completed
F078.- Added queue row action controls for:
Mark renewingMark non-renewing
- Implemented optimistic in-flight UI behavior in
RenewalsQueueTab:- per-row pending state map (
pendingRowActions) - immediate optimistic status/action updates before server response
- in-row pending indicator (
Updating action...) - action buttons disabled while row mutation is in-flight
- per-row pending state map (
- Mutation handlers call server actions:
markRenewalQueueItemRenewingmarkRenewalQueueItemNonRenewing
- Updated coverage:
packages/billing/tests/RenewalsQueueTab.component.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/RenewalsQueueTab.component.test.ts tests/renewalsQueueActions.wiring.test.ts
- Added queue row action controls for:
- (2026-02-21) Completed
F079.- Added targeted row refresh helper after successful mutation responses:
refreshQueueRowFromServer(clientContractId)inRenewalsQueueTab
- Success path now refreshes only the affected row from server state:
await refreshQueueRowFromServer(rowId)
- Fallback path still supports full refresh when row cannot be resolved.
- Updated coverage:
packages/billing/tests/RenewalsQueueTab.component.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/RenewalsQueueTab.component.test.ts
- Added targeted row refresh helper after successful mutation responses:
- (2026-02-21) Completed
F080.- Extended renewal queue row model with draft linkage:
created_draft_contract_id?: string | nullinRenewalQueueRow
- Queue list action now maps draft linkage field from row source:
created_draft_contract_id: (row as any).created_draft_contract_id ?? null
- Renewals queue UI now shows linked draft id when present:
Draft contract: {row.created_draft_contract_id}
- Updated coverage:
packages/billing/tests/renewalsQueueActions.wiring.test.tspackages/billing/tests/RenewalsQueueTab.component.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.wiring.test.ts tests/RenewalsQueueTab.component.test.ts tests/renewalsQueueActions.createDraft.wiring.test.ts
- Extended renewal queue row model with draft linkage:
- (2026-02-21) Completed
F081.- Extended renewal queue row model with ticket linkage:
created_ticket_id?: string | nullinRenewalQueueRow
- Queue list action now maps ticket linkage:
created_ticket_id: (row as any).created_ticket_id ?? null
- Renewals queue UI now shows linked ticket id when present:
Ticket: {row.created_ticket_id}
- Updated coverage:
packages/billing/tests/renewalsQueueActions.wiring.test.tspackages/billing/tests/RenewalsQueueTab.component.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.wiring.test.ts tests/RenewalsQueueTab.component.test.ts
- Extended renewal queue row model with ticket linkage:
- (2026-02-21) Completed
F082.- Added activation-confirmed completion action:
completeRenewalQueueItemForActivation(clientContractId, activatedContractId?, note?)- in
packages/billing/src/actions/renewalsQueueActions.ts
- Completion rules:
- source work item must be
renewing - target renewal contract must exist with
status = active - on success, work item transitions to
completedwith audit metadata
- source work item must be
- Added result type:
RenewalCompletionResult
- Added wiring coverage:
packages/billing/tests/renewalsQueueActions.completeOnActivation.wiring.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.completeOnActivation.wiring.test.ts tests/renewalsQueueActions.markRenewing.wiring.test.ts tests/renewalsQueueActions.createDraft.wiring.test.ts
- Added activation-confirmed completion action:
- (2026-02-21) Completed
F083.- Added non-renewal finalization completion action:
completeRenewalQueueItemForNonRenewal(clientContractId, note?)- in
packages/billing/src/actions/renewalsQueueActions.ts
- Completion rules:
- source work item must be
non_renewing - on success, work item transitions to
completedwith audit metadata
- source work item must be
- Added wiring coverage:
packages/billing/tests/renewalsQueueActions.completeNonRenewal.wiring.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.completeNonRenewal.wiring.test.ts tests/renewalsQueueActions.completeOnActivation.wiring.test.ts
- Added non-renewal finalization completion action:
- (2026-02-21) Completed
F084.- Added a scheduled renewal queue processor job handler:
processRenewalQueueHandler(data)inserver/src/lib/jobs/handlers/processRenewalQueueHandler.ts- scans active contracts whose
decision_due_datefalls withintoday..horizonDays - defaults horizon to
90days and validatestenantId
- Registered new job name and scheduling helpers:
- pg-boss handler registration in
server/src/lib/jobs/index.ts - recurring scheduling helper
scheduleRenewalQueueProcessingJob(...) - tenant startup scheduling hook in
server/src/lib/jobs/initializeScheduledJobs.ts(daily at0 5 * * *) - abstraction-layer handler registration + available handler list in
server/src/lib/jobs/registerAllHandlers.ts
- pg-boss handler registration in
- Added wiring test under included Vitest paths:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npm run typecheckcd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- Added a scheduled renewal queue processor job handler:
- (2026-02-21) Completed
F085.- Extended renewal queue processor to upsert work-item state for newly eligible cycles:
- processor now loads active contract assignments, normalizes effective renewal state, and filters by computed
decision_due_datewithintoday..horizon - upserts
decision_due_date,renewal_cycle_start,renewal_cycle_end, andrenewal_cycle_keywhen drift/new cycle is detected - resets cycle-scoped linkage fields (
created_ticket_id,created_draft_contract_id) when cycle key rolls - normalizes unknown/invalid statuses (or cycle changes) back to
pending
- processor now loads active contract assignments, normalizes effective renewal state, and filters by computed
- Updated wiring coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npm run typecheckcd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- Extended renewal queue processor to upsert work-item state for newly eligible cycles:
- (2026-02-21) Completed
F086.- Scheduled renewal processing now explicitly resolves tenant default due-date action policy:
- reads
default_billing_settings.renewal_due_date_action_policywhen available - normalizes policy (
queue_only | create_ticket) with deterministic fallback tocreate_ticket
- reads
- During upsert, processor applies tenant policy to work-item rows when contract-level policy column exists:
- updates
client_contracts.renewal_due_date_action_policyto tenant effective value - tracks policy distribution in logs (
queueOnlyPolicyCount,createTicketPolicyCount)
- updates
- Updated wiring coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npm run typecheckcd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- Scheduled renewal processing now explicitly resolves tenant default due-date action policy:
- (2026-02-21) Completed
F087.- Scheduled renewal processing now applies contract-level due-date policy overrides with deterministic precedence:
- resolve
use_tenant_renewal_defaults(defaulttrue) - resolve contract-level policy from
client_contracts.renewal_due_date_action_policywhen valid - compute effective policy as:
- tenant policy when
use_tenant_renewal_defaults = true - contract override when defaults are disabled and explicit contract policy exists
- tenant fallback when override is missing/invalid
- tenant policy when
- resolve
- Processor now logs override utilization:
contractOverridePolicyCount
- Updated wiring coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npm run typecheckcd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- Scheduled renewal processing now applies contract-level due-date policy overrides with deterministic precedence:
- (2026-02-21) Completed
F088.- Added due-date ticket automation execution in renewal processor:
- computes
shouldCreateTicketAtDueDatefor eligible rows where:- effective policy is
create_ticket - decision due date is due (
<= today) - no
created_ticket_idis already linked
- effective policy is
- builds renewal-context title/description payloads
- uses configured renewal routing defaults (board/status/priority/assignee) when present
- computes
- Processor now persists ticket linkage on success:
updates.created_ticket_id = createdTicketId
- Added direct ticket-creation fallback path for resilience when workflow action execution is unavailable.
- Updated wiring coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npm run typecheckcd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- Added due-date ticket automation execution in renewal processor:
- (2026-02-21) Completed
F089.- Integrated renewal ticket automation with workflow runtime business action path:
- initializes runtime v2 action registry (
initializeWorkflowRuntimeV2) - resolves and invokes
tickets.create@v1fromgetActionRegistryV2 - validates both input and output schemas via registered action definitions
- initializes runtime v2 action registry (
- Retained direct-ticket fallback path when runtime action execution is unavailable/fails to keep automation robust.
- Updated wiring coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npm run typecheckcd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- Integrated renewal ticket automation with workflow runtime business action path:
- (2026-02-21) Completed
F090.- Added renewal ticket title builder with explicit client + contract context:
buildRenewalTicketTitle(row, decisionDueDate)- title shape:
Renewal Decision Due {date}: {clientName} / {contractName}
- Renewal automation now uses this title for both workflow-action and direct-fallback ticket creation paths.
- Updated wiring coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npm run typecheckcd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- Added renewal ticket title builder with explicit client + contract context:
- (2026-02-21) Completed
F091.- Added renewal ticket description builder with due-date + renewal-settings context:
buildRenewalTicketDescription(row, normalized, decisionDueDate)- includes decision due date, effective renewal mode, effective notice period, and cycle key metadata
- Renewal automation now uses this description for workflow-action and direct-fallback ticket creation paths.
- Updated wiring coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npm run typecheckcd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- Added renewal ticket description builder with due-date + renewal-settings context:
- (2026-02-21) Completed
F092.- Renewal ticket routing now uses effective defaults with tenant/contract precedence:
- tenant defaults from
default_billing_settings:renewal_ticket_board_idrenewal_ticket_status_idrenewal_ticket_priorityrenewal_ticket_assignee_id
- optional contract-level overrides from
client_contractsare applied whenuse_tenant_renewal_defaults = false - deterministic fallback to tenant defaults for any missing contract-level routing values
- tenant defaults from
- Added processor visibility metric:
routingOverrideAppliedCount
- Updated wiring coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npm run typecheckcd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- Renewal ticket routing now uses effective defaults with tenant/contract precedence:
- (2026-02-21) Completed
F093.- Renewal processor now persists ticket linkage on successful automation:
- captures ticket id from workflow-action/direct-fallback creation result
- writes
created_ticket_idon the client-contract renewal work item update payload
- This makes ticket linkage visible in queue APIs/UI and supports downstream idempotency checks.
- Updated wiring coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npm run typecheckcd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- Renewal processor now persists ticket linkage on successful automation:
- (2026-02-21) Completed
F094.- Added deterministic renewal ticket idempotency key builder:
- shape:
renewal-ticket:{tenantId}:{clientContractId}:{cycleKey}
- shape:
- Processor now uses this idempotency key for:
- workflow runtime
tickets.createinvocation input (idempotency_key) - direct fallback ticket attributes (
idempotency_key) for duplicate-detection context
- workflow runtime
- Updated wiring coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npm run typecheckcd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- Added deterministic renewal ticket idempotency key builder:
- (2026-02-21) Completed
F095.- Added duplicate-prevention lookup before renewal ticket creation:
- checks existing
ticketsrows for matchingattributes.idempotency_key - if found, links existing ticket id to work item and skips create path
- checks existing
- Both workflow and direct ticket creation paths now receive shared ticket attributes including idempotency metadata.
- Added processor metric:
duplicateTicketSkipCount
- Updated wiring coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npm run typecheckcd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- Added duplicate-prevention lookup before renewal ticket creation:
- (2026-02-21) Completed
F096.- Renewal processor now records automation failures on work items when ticket creation fails:
- reads optional
client_contracts.automation_errorcolumn - writes failure reason on create-path errors
- records missing-routing-defaults as explicit automation error for
create_ticketpolicy - clears
automation_errorwhen ticket creation succeeds
- reads optional
- Added processor metric:
automationErrorCount
- Updated wiring coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npm run typecheckcd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- Renewal processor now records automation failures on work items when ticket creation fails:
- (2026-02-21) Completed
F097.- Added manual retry queue action for failed renewal ticket automation:
retryRenewalQueueTicketCreation(clientContractId)inpackages/billing/src/actions/renewalsQueueActions.ts
- Retry action behavior:
- validates work item + due-date eligibility
- resolves effective due-date policy and routing defaults with tenant/contract precedence
- reuses cycle idempotency key to avoid duplicates
- links existing idempotent ticket when present
- otherwise re-attempts ticket creation and updates
created_ticket_id/automation_error
- Exposed
automation_errorin renewal queue row payload model. - Updated coverage:
packages/billing/tests/renewalsQueueActions.retryTicket.wiring.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.retryTicket.wiring.test.ts tests/renewalsQueueActions.wiring.test.ts
- Added manual retry queue action for failed renewal ticket automation:
- (2026-02-21) Completed
F098.- Queue-only policy behavior is enforced in both automation paths:
- scheduled processor only enters ticket-create path when
effectiveDueDateActionPolicy === 'create_ticket' - manual retry action returns without creating tickets when effective policy is
queue_only
- scheduled processor only enters ticket-create path when
- This preserves queue visibility/workflow without forcing ticket side effects.
- Updated coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.tspackages/billing/tests/renewalsQueueActions.retryTicket.wiring.test.ts
- Validation:
cd server && npm run typecheckcd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=falsenpm -w @alga-psa/billing run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.retryTicket.wiring.test.ts tests/renewalsQueueActions.wiring.test.ts
- Queue-only policy behavior is enforced in both automation paths:
- (2026-02-21) Completed
F099.- Updated contract renewal-upcoming domain-event builders/schemas for queue-compatible semantics:
- expanded default window from 30 to 90 days
computeContractRenewalUpcomingnow supports decision-due date and renewal cycle key inputs- payload now includes:
decisionDueDatedaysUntilDecisionDuerenewalCycleKey
- Updated event publishers in:
packages/billing/src/actions/contractWizardActions.tspackages/clients/src/actions/clientContractActions.ts
CONTRACT_RENEWAL_UPCOMINGidempotency keys now prefer cycle-key/decision-due identity where available.- Added wiring coverage:
packages/billing/tests/contractRenewalUpcomingEvent.wiring.test.ts
- Validation:
npm -w @alga-psa/billing run typechecknpm -w @alga-psa/clients run typechecknpm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/renewalsQueueActions.retryTicket.wiring.test.ts
- Note:
- direct execution of
shared/workflow/streams/domainEventBuilders/__tests__/contractEventBuilders.test.tsunder current Vitest include globs returned “No test files found”; wiring assertions were added in billing tests to cover this change.
- direct execution of
- Updated contract renewal-upcoming domain-event builders/schemas for queue-compatible semantics:
- (2026-02-21) Completed
F100.- Confirmed evergreen renewal queue generation path in scheduled processor:
- processor normalizes each contract with
normalizeClientContract(which computes evergreen annual-cycle decision dates) - upserts normalized cycle boundaries and cycle key:
renewal_cycle_startrenewal_cycle_endrenewal_cycle_key
- includes evergreen entries whenever computed decision due date is within the processing horizon
- processor normalizes each contract with
- Updated coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npm run typecheckcd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- Confirmed evergreen renewal queue generation path in scheduled processor:
- (2026-02-21) Completed
F101.- Added explicit per-row contract type badge rendering in Renewals queue UI:
- evergreen rows now show
Evergreenbadge - fixed-term rows show
Fixed-termbadge
- evergreen rows now show
- Implemented in:
packages/billing/src/components/billing-dashboard/contracts/RenewalsQueueTab.tsx
- Added component wiring assertions:
packages/billing/tests/RenewalsQueueTab.component.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/RenewalsQueueTab.component.test.ts --coverage=falsenpm -w @alga-psa/billing run typecheck
- Added explicit per-row contract type badge rendering in Renewals queue UI:
- (2026-02-21) Completed
F102.- Added evergreen cycle anchor detail to renewal queue rows.
- Queue row model now surfaces:
evergreen_cycle_anchor_date(fromevergreen_review_anchor_date, fallbackrenewal_cycle_end)
- UI now renders evergreen-only row detail:
Evergreen anchor: <date>
- Updated wiring coverage:
packages/billing/tests/RenewalsQueueTab.component.test.tspackages/billing/tests/renewalsQueueActions.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/RenewalsQueueTab.component.test.ts tests/renewalsQueueActions.wiring.test.ts --coverage=falsenpm -w @alga-psa/billing run typecheck
- (2026-02-21) Completed
F103.- Confirmed evergreen entries share the same mark-renewing transition path as fixed-term entries:
- queue action availability is status-driven (
pendingincludesmark_renewing) - mark-renewing mutation path has no contract-type/end-date gate
- queue action availability is status-driven (
- Added dedicated wiring coverage:
packages/billing/tests/renewalsQueueActions.markRenewingEvergreen.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.markRenewing.wiring.test.ts tests/renewalsQueueActions.markRenewingEvergreen.wiring.test.ts --coverage=falsenpm -w @alga-psa/billing run typecheck
- Confirmed evergreen entries share the same mark-renewing transition path as fixed-term entries:
- (2026-02-21) Completed
F104.- Confirmed evergreen entries share the same mark-non-renewing transition path as fixed-term entries:
- queue action availability remains status-driven
- mark-non-renewing mutation path has no contract-type/end-date gate
- Added dedicated wiring coverage:
packages/billing/tests/renewalsQueueActions.markNonRenewingEvergreen.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.markNonRenewing.wiring.test.ts tests/renewalsQueueActions.markNonRenewingEvergreen.wiring.test.ts --coverage=falsenpm -w @alga-psa/billing run typecheck
- Confirmed evergreen entries share the same mark-non-renewing transition path as fixed-term entries:
- (2026-02-21) Completed
F105.- Confirmed create-renewal-draft action supports evergreen entries:
- mutation eligibility is status-driven (
pending/renewing) - draft assignment creation logic supports null
end_date(evergreen) while preserving start-date semantics
- mutation eligibility is status-driven (
- Added dedicated wiring coverage:
packages/billing/tests/renewalsQueueActions.createDraftEvergreen.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.createDraft.wiring.test.ts tests/renewalsQueueActions.createDraftEvergreen.wiring.test.ts --coverage=falsenpm -w @alga-psa/billing run typecheck
- Confirmed create-renewal-draft action supports evergreen entries:
- (2026-02-21) Completed
F106.- Confirmed evergreen cycle rollover semantics in scheduled renewal processing:
- when cycle key advances, processor treats it as a new cycle (
cycleChanged) - status normalization reopens work item to
pending - updated cycle key is persisted and cycle-change counters increment
- when cycle key advances, processor treats it as a new cycle (
- Added explicit rollover wiring coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=falsecd server && npm run typecheck
- Confirmed evergreen cycle rollover semantics in scheduled renewal processing:
- (2026-02-21) Completed
F107.- Added cycle-level deduplication guard in scheduled renewal processing to prevent duplicate handling of the same contract/cycle period:
- dedupe identity:
client_contract_id + cycleKey(fallback todecision_due_date) - duplicate entries are skipped and counted in processor metrics
- dedupe identity:
- This hardens evergreen annual-cycle processing against duplicate row inputs from upstream query/join behavior.
- Updated coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=falsecd server && npm run typecheck
- Added cycle-level deduplication guard in scheduled renewal processing to prevent duplicate handling of the same contract/cycle period:
- (2026-02-21) Completed
F108.- Added regression coverage confirming evergreen decision due date uses contract-level notice-period override when tenant defaults are disabled.
- Covered both branches:
- tenant defaults enabled => tenant notice period drives evergreen decision date
- tenant defaults disabled => contract override notice period drives evergreen decision date
- Updated coverage:
packages/billing/tests/clientContractEffectiveRenewalSettings.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/clientContractEffectiveRenewalSettings.test.ts --coverage=falsenpm -w @alga-psa/billing run typecheck
- (2026-02-21) Completed
F109.- Updated
ClientContractsTabupcoming-renewals widget bucketing to explicitly include both contract types:fixed-termevergreen
- Added explicit widget wiring coverage to ensure evergreen entries are included in bucket counts.
- Updated files:
packages/billing/src/components/billing-dashboard/contracts/ClientContractsTab.tsxpackages/billing/tests/ClientContractsTab.upcomingRenewalsWidget.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=falsenpm -w @alga-psa/billing run typecheck
- Updated
- (2026-02-21) Completed
F110.- Extended expiration-report action payload to include
decision_due_datealongsideend_datewhen present. - Updated
ContractExpirationtype and query mapping in:packages/billing/src/actions/contractReportActions.ts
- Added wiring coverage:
packages/billing/tests/contractReportActions.expiration.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/contractReportActions.expiration.wiring.test.ts --coverage=falsenpm -w @alga-psa/billing run typecheck
- Extended expiration-report action payload to include
- (2026-02-21) Completed
F111.- Extended expiration-report rows to include
renewal_mode. - Updated report contract type in:
packages/billing/src/actions/contractReportActions.ts
- Expanded wiring coverage:
packages/billing/tests/contractReportActions.expiration.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/contractReportActions.expiration.wiring.test.ts --coverage=falsenpm -w @alga-psa/billing run typecheck
- Extended expiration-report rows to include
- (2026-02-21) Completed
F112.- Extended expiration-report rows to include renewal queue state when present (
queue_statusfromclient_contracts.status). - Updated files:
packages/billing/src/actions/contractReportActions.tspackages/billing/tests/contractReportActions.expiration.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/contractReportActions.expiration.wiring.test.ts --coverage=falsenpm -w @alga-psa/billing run typecheck
- Extended expiration-report rows to include renewal queue state when present (
- (2026-02-21) Completed
F113.- Preserved existing fixed-term expiration inclusion semantics while adding renewal metadata:
- expiration rows still key off
end_datepresence - no hard requirement for
renewal_modeto be set
- expiration rows still key off
- Added explicit compatibility coverage in:
packages/billing/tests/contractReportActions.expiration.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/contractReportActions.expiration.wiring.test.ts --coverage=falsenpm -w @alga-psa/billing run typecheck
- Preserved existing fixed-term expiration inclusion semantics while adding renewal metadata:
- (2026-02-21) Completed
F114.- Preserved expiration-report sort compatibility for existing consumers:
- primary ordering remains
cc.end_date ASC - dedupe key remains based on contract/client/end-date identity
- primary ordering remains
- Added explicit compatibility assertions in:
packages/billing/tests/contractReportActions.expiration.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/contractReportActions.expiration.wiring.test.ts --coverage=falsenpm -w @alga-psa/billing run typecheck
- Preserved expiration-report sort compatibility for existing consumers:
- (2026-02-21) Completed
F115.- Extended report summary payload with
atRiskDecisionCountfor dashboard consumption. - At-risk metric now counts active client-contract assignments with
decision_due_datein the next 90 days. - Updated files:
packages/billing/src/actions/contractReportActions.tspackages/billing/tests/contractReportActions.summary.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/contractReportActions.summary.wiring.test.ts tests/contractReportActions.expiration.wiring.test.ts --coverage=falsenpm -w @alga-psa/billing run typecheck
- Extended report summary payload with
- (2026-02-21) Completed
F116.- Updated Contract Reports expiration tab copy to reference renewal decisions in addition to expirations.
- Updated UX copy in:
packages/billing/src/components/billing-dashboard/reports/ContractReports.tsx
- Added wiring coverage:
packages/billing/tests/ContractReports.expirationCopy.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/ContractReports.expirationCopy.wiring.test.ts tests/contractReportActions.summary.wiring.test.ts tests/contractReportActions.expiration.wiring.test.ts --coverage=falsenpm -w @alga-psa/billing run typecheck
- (2026-02-21) Completed
F117.- Updated expiration-report row construction so legacy
auto_renewdisplay derives from effective renewal mode values. - Effective renewal mode now resolves with tenant-default precedence logic:
- honors
use_tenant_renewal_defaults - falls back deterministically between contract/tenant/default (
manual)
- honors
auto_renewnow maps toeffectiveRenewalMode === 'auto'.- Updated files:
packages/billing/src/actions/contractReportActions.tspackages/billing/tests/contractReportActions.expiration.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/contractReportActions.expiration.wiring.test.ts tests/contractReportActions.summary.wiring.test.ts tests/ContractReports.expirationCopy.wiring.test.ts --coverage=falsenpm -w @alga-psa/billing run typecheck
- Updated expiration-report row construction so legacy
- (2026-02-21) Completed
F118.- Confirmed renewal scheduled processor registration in the on-prem pg-boss scheduled initialization path:
- tenant loop schedules
process-renewal-queueviascheduleRenewalQueueProcessingJob(tenantId, 90, cron) - includes both first-schedule and singleton-already-scheduled handling logs
- tenant loop schedules
- Updated coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=falsecd server && npm run typecheck
- Confirmed renewal scheduled processor registration in the on-prem pg-boss scheduled initialization path:
- (2026-02-21) Completed
F119.- Added Temporal runner coverage proving renewal scheduled processing can be registered as a recurring Temporal workflow:
- schedules
process-renewal-queuewith tenant + horizon payload - validates Temporal schedule action carries renewal job name/data
- schedules
- Updated coverage:
ee/server/src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts
- Validation:
cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts
- Note:
npm --prefix ee/server run test:unit -- src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.tsexecutes the full unit suite in this workspace and currently surfaces unrelated pre-existing failures in other unit files; targeted execution of the modified test passes.
- Added Temporal runner coverage proving renewal scheduled processing can be registered as a recurring Temporal workflow:
- (2026-02-21) Completed
F120.- Confirmed renewal processing uses a shared core handler callable from both runtime adapters:
- legacy pg-boss registration path (
index.ts) callsprocessRenewalQueueHandler - centralized handler registry (
registerAllHandlers.ts) also calls the same handler for Temporal/runner abstraction execution initializeJobRunner.tsbridges registered handlers into runner implementations
- legacy pg-boss registration path (
- Updated coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=falsecd server && npm run typecheck
- Confirmed renewal processing uses a shared core handler callable from both runtime adapters:
- (2026-02-21) Completed
F121.- Added parity coverage confirming queue-creation payload shape is equivalent across runner paths:
- pg-boss scheduling uses
process-renewal-queuewith{ tenantId, horizonDays } - Temporal recurring workflow action forwards
jobName,tenantId, anddatathroughgenericJobWorkflow
- pg-boss scheduling uses
- Updated coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=falsecd server && npm run typecheck
- Added parity coverage confirming queue-creation payload shape is equivalent across runner paths:
- (2026-02-21) Completed
F122.- Added runtime-parity coverage confirming ticket idempotency behavior is shared across runner paths because both execute the same renewal processor core:
- shared idempotency key construction
- duplicate-ticket lookup by idempotency attribute
- shared duplicate-skip semantics
- Updated coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=falsecd server && npm run typecheck
- Added runtime-parity coverage confirming ticket idempotency behavior is shared across runner paths because both execute the same renewal processor core:
- (2026-02-21) Completed
F123.- Added wiring coverage confirming runtime selection stays in
JobRunnerFactoryand renewal business logic remains runner/edition agnostic:- runner type resolution via config/env (
JOB_RUNNER_TYPE) - renewal processor contains no edition/runtime branching
- runner type resolution via config/env (
- Updated coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=falsecd server && npm run typecheck
- Added wiring coverage confirming runtime selection stays in
Open Questions
- Should renewal ticket defaults be a brand-new billing settings card, or an extension of existing default ticket settings patterns?
- Should evergreen annual review use contract start-date anniversary or configurable anchor date in v1?
- Should renewal status transitions hard-lock contract activation behavior, or remain advisory with warnings in v1?
- (2026-02-21) Completed
F124.- Added explicit runtime-fallback coverage confirming Temporal bootstrap failures gracefully fall back to pg-boss when fallback is enabled.
- Assertions verify:
- Temporal path attempted first for EE/runtime selection
- fallback gate checks
config?.fallbackToPgBoss !== false - fallback execution calls
createPgBossRunner(config) - Temporal bootstrap/import failures remain surfaced and handled by fallback branch
- Updated coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- (2026-02-21) Completed
F125.- Added tenant-scope parity coverage across pg-boss and Temporal renewal runtime paths.
- Assertions verify:
- scheduler payload requires and forwards tenant id for renewal processing
- renewal processor enforces tenant id and scopes reads/writes by tenant
- Temporal runner enforces tenant id in job data and propagates tenant scope into workflow/job persistence
- Updated coverage:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- (2026-02-21) Completed
F126.- Enforced billing read authorization on renewals queue list endpoint.
listRenewalQueueRowsnow gates access viahasPermission(user, 'billing', 'read')and throwsPermission denied: Cannot read renewals queuewhen unauthorized.- Updated files:
packages/billing/src/actions/renewalsQueueActions.tspackages/billing/tests/renewalsQueueActions.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.wiring.test.ts --coverage=false
- (2026-02-21) Completed
F127.- Enforced billing update authorization on all renewals queue mutation endpoints.
- Added shared guard
requireBillingUpdatePermission(user)and applied it to:markRenewalQueueItemRenewingmarkRenewalQueueItemNonRenewingcreateRenewalDraftForQueueItemsnoozeRenewalQueueItemassignRenewalQueueItemOwnercompleteRenewalQueueItemForActivationcompleteRenewalQueueItemForNonRenewalretryRenewalQueueTicketCreation
- Updated files:
packages/billing/src/actions/renewalsQueueActions.tspackages/billing/tests/renewalsQueueActions.permissions.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.wiring.test.ts tests/renewalsQueueActions.permissions.wiring.test.ts --coverage=false
- (2026-02-21) Completed
F128.- Enforced billing settings update authorization on renewal default writes.
updateDefaultBillingSettingsnow requireshasPermission(user, 'billing_settings', 'update')and rejects unauthorized callers.- Updated files:
packages/billing/src/actions/billingSettingsActions.tspackages/billing/tests/billingSettingsActions.renewalPermissions.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/billingSettingsActions.renewalPermissions.wiring.test.ts --coverage=false
- (2026-02-21) Completed
F129.- Added explicit wiring coverage that renewal work-item read paths are tenant-scoped by default.
- Coverage asserts tenant filtering across list/read query builders in renewals queue actions.
- Updated file:
packages/billing/tests/renewalsQueueActions.tenantReads.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.tenantReads.wiring.test.ts --coverage=false
- (2026-02-21) Completed
F130.- Added wiring coverage that renewal work-item mutation/write paths remain tenant-filtered by default.
- Coverage checks tenant-scoped update/insert/lookup clauses in renewals queue action writes.
- Updated file:
packages/billing/tests/renewalsQueueActions.tenantWrites.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.tenantWrites.wiring.test.ts --coverage=false
- (2026-02-21) Completed
F131.- Enhanced renewal transition auditing to capture action metadata (
last_action) alongside actor/timestamp/note. - Added
withActionLabel(...)andlast_actioncolumn checks across mutation paths so transitions now record action labels such as:mark_renewing,mark_non_renewing,create_renewal_draft,snooze,assign_owner,complete_after_activation,complete_after_non_renewal
- Updated files:
packages/billing/src/actions/renewalsQueueActions.tspackages/billing/tests/renewalsQueueActions.transitionAudit.wiring.test.tspackages/billing/tests/renewalsQueueActions.actorAudit.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.transitionAudit.wiring.test.ts tests/renewalsQueueActions.actorAudit.wiring.test.ts tests/renewalsQueueActions.timestampAudit.wiring.test.ts tests/renewalsQueueActions.noteAudit.wiring.test.ts --coverage=false
- Enhanced renewal transition auditing to capture action metadata (
- (2026-02-21) Completed
F132.- Added automation-linkage audit metadata in renewal processor when due-date ticket linkage succeeds.
- When a ticket is linked, handler now records (when columns exist):
last_action = 'system_ticket_automation_linked'last_action_by = null(system actor)last_action_at = nowIso
- Updated files:
server/src/lib/jobs/handlers/processRenewalQueueHandler.tsserver/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- (2026-02-21) Completed
F133.- Added explicit draft-linkage audit coverage ensuring renewal draft creation linkage persists with actor/timestamp metadata.
- Coverage validates draft link persistence and action metadata chain (
withActionLabel+withActionActor+withActionTimestamp). - Updated file:
packages/billing/tests/renewalsQueueActions.createDraftAudit.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.createDraft.wiring.test.ts tests/renewalsQueueActions.createDraftAudit.wiring.test.ts --coverage=false
- (2026-02-21) Completed
F134.- Added explicit cross-tenant identifier rejection in queue mutation validation:
- owner assignment now rejects
assignedTouser IDs found only in another tenant - activation completion now rejects
activatedContractIdvalues belonging to another tenant
- owner assignment now rejects
- Added explicit error paths for cross-tenant and not-in-tenant owner identifiers.
- Updated files:
packages/billing/src/actions/renewalsQueueActions.tspackages/billing/tests/renewalsQueueActions.crossTenantValidation.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.crossTenantValidation.wiring.test.ts tests/renewalsQueueActions.assignOwner.wiring.test.ts tests/renewalsQueueActions.completeOnActivation.wiring.test.ts --coverage=false
- Added explicit cross-tenant identifier rejection in queue mutation validation:
- (2026-02-21) Completed
F135.- Added note sanitization prior to persistence/render for renewal queue action notes.
normalizeActionNotenow sanitizes input by stripping HTML tags, removing angle brackets/control chars, normalizing whitespace, and trimming.- Updated files:
packages/billing/src/actions/renewalsQueueActions.tspackages/billing/tests/renewalsQueueActions.noteSanitization.wiring.test.ts
- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.noteAudit.wiring.test.ts tests/renewalsQueueActions.noteSanitization.wiring.test.ts --coverage=false
- (2026-02-21) Completed
T032.- Verified effective renewal settings exposure in contract assignment read paths.
- Validation:
npm -w @alga-psa/billing exec vitest run tests/clientContractEffectiveRenewalSettings.test.ts --coverage=false
- (2026-02-21) Completed
T033.- Validation:
npm -w @alga-psa/billing exec vitest run tests/clientContractEffectiveRenewalSettings.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T034.- Validation:
npm -w @alga-psa/billing exec vitest run tests/clientContractEffectiveRenewalSettings.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T035.- Validation:
npm -w @alga-psa/billing exec vitest run tests/clientContractEffectiveRenewalSettings.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T036.- Validation:
npm -w @alga-psa/billing exec vitest run tests/clientContractEffectiveRenewalSettings.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T037.- Validation:
npm -w @alga-psa/billing exec vitest run tests/clientContractEffectiveRenewalSettings.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T038.- Validation:
npm -w @alga-psa/billing exec vitest run tests/clientContractEffectiveRenewalSettings.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T039.- Validation:
npm -w @alga-psa/billing exec vitest run tests/clientContractEffectiveRenewalSettings.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T040.- Validation:
npm -w @alga-psa/billing exec vitest run tests/clientContractEffectiveRenewalSettings.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T041.- Validation:
npm -w @alga-psa/billing exec vitest run tests/clientContractEffectiveRenewalSettings.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T042.- Validation:
npm -w @alga-psa/billing exec vitest run tests/clientContractEffectiveRenewalSettings.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T043.- Validation:
npm -w @alga-psa/billing exec vitest run tests/clientContractEffectiveRenewalSettings.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T044.- Validation:
npm -w @alga-psa/billing exec vitest run tests/clientContractEffectiveRenewalSettings.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T045.- Validation:
npm -w @alga-psa/billing exec vitest run tests/clientContractEffectiveRenewalSettings.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T046.- Validation:
npm -w @alga-psa/billing exec vitest run tests/clientContractEffectiveRenewalSettings.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T047.- Validation:
npm -w @alga-psa/billing exec vitest run tests/clientContractEffectiveRenewalSettings.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T048.- Validation:
npm -w @alga-psa/billing exec vitest run tests/billingTabsConfig.renewals.test.ts tests/BillingDashboard.renewalsRoute.test.ts tests/RenewalsQueueTab.component.test.ts tests/renewalsQueueActions.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T049.- Validation:
npm -w @alga-psa/billing exec vitest run tests/billingTabsConfig.renewals.test.ts tests/BillingDashboard.renewalsRoute.test.ts tests/RenewalsQueueTab.component.test.ts tests/renewalsQueueActions.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T050.- Validation:
npm -w @alga-psa/billing exec vitest run tests/billingTabsConfig.renewals.test.ts tests/BillingDashboard.renewalsRoute.test.ts tests/RenewalsQueueTab.component.test.ts tests/renewalsQueueActions.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T051.- Validation:
npm -w @alga-psa/billing exec vitest run tests/billingTabsConfig.renewals.test.ts tests/BillingDashboard.renewalsRoute.test.ts tests/RenewalsQueueTab.component.test.ts tests/renewalsQueueActions.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T052.- Validation:
npm -w @alga-psa/billing exec vitest run tests/billingTabsConfig.renewals.test.ts tests/BillingDashboard.renewalsRoute.test.ts tests/RenewalsQueueTab.component.test.ts tests/renewalsQueueActions.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T053.- Validation:
npm -w @alga-psa/billing exec vitest run tests/billingTabsConfig.renewals.test.ts tests/BillingDashboard.renewalsRoute.test.ts tests/RenewalsQueueTab.component.test.ts tests/renewalsQueueActions.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T054.- Validation:
npm -w @alga-psa/billing exec vitest run tests/billingTabsConfig.renewals.test.ts tests/BillingDashboard.renewalsRoute.test.ts tests/RenewalsQueueTab.component.test.ts tests/renewalsQueueActions.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T055.- Validation:
npm -w @alga-psa/billing exec vitest run tests/billingTabsConfig.renewals.test.ts tests/BillingDashboard.renewalsRoute.test.ts tests/RenewalsQueueTab.component.test.ts tests/renewalsQueueActions.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T056.- Validation:
npm -w @alga-psa/billing exec vitest run tests/billingTabsConfig.renewals.test.ts tests/BillingDashboard.renewalsRoute.test.ts tests/RenewalsQueueTab.component.test.ts tests/renewalsQueueActions.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T057.- Validation:
npm -w @alga-psa/billing exec vitest run tests/billingTabsConfig.renewals.test.ts tests/BillingDashboard.renewalsRoute.test.ts tests/RenewalsQueueTab.component.test.ts tests/renewalsQueueActions.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T058.- Validation:
npm -w @alga-psa/billing exec vitest run tests/billingTabsConfig.renewals.test.ts tests/BillingDashboard.renewalsRoute.test.ts tests/RenewalsQueueTab.component.test.ts tests/renewalsQueueActions.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T059.- Validation:
npm -w @alga-psa/billing exec vitest run tests/billingTabsConfig.renewals.test.ts tests/BillingDashboard.renewalsRoute.test.ts tests/RenewalsQueueTab.component.test.ts tests/renewalsQueueActions.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T060.- Validation:
npm -w @alga-psa/billing exec vitest run tests/ClientContractsTab.upcomingRenewalsWidget.test.ts tests/BillingDashboard.renewalsRoute.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T061.- Validation:
npm -w @alga-psa/billing exec vitest run tests/ClientContractsTab.upcomingRenewalsWidget.test.ts tests/BillingDashboard.renewalsRoute.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T062.- Validation:
npm -w @alga-psa/billing exec vitest run tests/ClientContractsTab.upcomingRenewalsWidget.test.ts tests/BillingDashboard.renewalsRoute.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T063.- Validation:
npm -w @alga-psa/billing exec vitest run tests/ClientContractsTab.upcomingRenewalsWidget.test.ts tests/BillingDashboard.renewalsRoute.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T064.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T065.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T066.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T067.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T068.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T069.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T070.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T071.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T072.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T073.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T074.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T075.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T076.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T077.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T078.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T079.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T080.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T081.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T082.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T083.- Validation:
cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T084.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T085.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T086.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T087.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T088.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T089.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T090.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T091.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T092.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T093.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T094.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T095.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T096.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T097.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T098.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T099.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T100.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T101.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T102.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T103.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T104.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T105.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T106.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T107.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T108.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T109.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts;cd packages/billing && npx vitest run $(rg --files tests | rg 'renewalsQueueActions') tests/RenewalsQueueTab.component.test.ts --coverage=false;npm -w @alga-psa/billing exec vitest run tests/contractRenewalUpcomingEvent.wiring.test.ts tests/clientContractEffectiveRenewalSettings.test.ts tests/ClientContractsTab.upcomingRenewalsWidget.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T110.- Validation:
npm -w @alga-psa/billing exec vitest run tests/contractReportActions.expiration.wiring.test.ts tests/contractReportActions.summary.wiring.test.ts tests/ContractReports.expirationCopy.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T111.- Validation:
npm -w @alga-psa/billing exec vitest run tests/contractReportActions.expiration.wiring.test.ts tests/contractReportActions.summary.wiring.test.ts tests/ContractReports.expirationCopy.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T112.- Validation:
npm -w @alga-psa/billing exec vitest run tests/contractReportActions.expiration.wiring.test.ts tests/contractReportActions.summary.wiring.test.ts tests/ContractReports.expirationCopy.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T113.- Validation:
npm -w @alga-psa/billing exec vitest run tests/contractReportActions.expiration.wiring.test.ts tests/contractReportActions.summary.wiring.test.ts tests/ContractReports.expirationCopy.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T114.- Validation:
npm -w @alga-psa/billing exec vitest run tests/contractReportActions.expiration.wiring.test.ts tests/contractReportActions.summary.wiring.test.ts tests/ContractReports.expirationCopy.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T115.- Validation:
npm -w @alga-psa/billing exec vitest run tests/contractReportActions.expiration.wiring.test.ts tests/contractReportActions.summary.wiring.test.ts tests/ContractReports.expirationCopy.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T116.- Validation:
npm -w @alga-psa/billing exec vitest run tests/contractReportActions.expiration.wiring.test.ts tests/contractReportActions.summary.wiring.test.ts tests/ContractReports.expirationCopy.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T117.- Validation:
npm -w @alga-psa/billing exec vitest run tests/contractReportActions.expiration.wiring.test.ts tests/contractReportActions.summary.wiring.test.ts tests/ContractReports.expirationCopy.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T118.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts
- Validation:
- (2026-02-21) Completed
T119.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts
- Validation:
- (2026-02-21) Completed
T120.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts
- Validation:
- (2026-02-21) Completed
T121.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts
- Validation:
- (2026-02-21) Completed
T122.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts
- Validation:
- (2026-02-21) Completed
T123.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts
- Validation:
- (2026-02-21) Completed
T124.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts
- Validation:
- (2026-02-21) Completed
T125.- Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false;cd ee/server && npx vitest run src/__tests__/unit/temporalJobRunner.scheduleRecurringJob.test.ts
- Validation:
- (2026-02-21) Completed
T126.- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.permissions.wiring.test.ts tests/billingSettingsActions.renewalPermissions.wiring.test.ts tests/renewalsQueueActions.tenantReads.wiring.test.ts tests/renewalsQueueActions.tenantWrites.wiring.test.ts tests/renewalsQueueActions.transitionAudit.wiring.test.ts tests/renewalsQueueActions.createDraftAudit.wiring.test.ts tests/renewalsQueueActions.crossTenantValidation.wiring.test.ts tests/renewalsQueueActions.noteSanitization.wiring.test.ts tests/renewalsQueueActions.actorAudit.wiring.test.ts tests/renewalsQueueActions.timestampAudit.wiring.test.ts tests/renewalsQueueActions.noteAudit.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T127.- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.permissions.wiring.test.ts tests/billingSettingsActions.renewalPermissions.wiring.test.ts tests/renewalsQueueActions.tenantReads.wiring.test.ts tests/renewalsQueueActions.tenantWrites.wiring.test.ts tests/renewalsQueueActions.transitionAudit.wiring.test.ts tests/renewalsQueueActions.createDraftAudit.wiring.test.ts tests/renewalsQueueActions.crossTenantValidation.wiring.test.ts tests/renewalsQueueActions.noteSanitization.wiring.test.ts tests/renewalsQueueActions.actorAudit.wiring.test.ts tests/renewalsQueueActions.timestampAudit.wiring.test.ts tests/renewalsQueueActions.noteAudit.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T128.- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.permissions.wiring.test.ts tests/billingSettingsActions.renewalPermissions.wiring.test.ts tests/renewalsQueueActions.tenantReads.wiring.test.ts tests/renewalsQueueActions.tenantWrites.wiring.test.ts tests/renewalsQueueActions.transitionAudit.wiring.test.ts tests/renewalsQueueActions.createDraftAudit.wiring.test.ts tests/renewalsQueueActions.crossTenantValidation.wiring.test.ts tests/renewalsQueueActions.noteSanitization.wiring.test.ts tests/renewalsQueueActions.actorAudit.wiring.test.ts tests/renewalsQueueActions.timestampAudit.wiring.test.ts tests/renewalsQueueActions.noteAudit.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T129.- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.permissions.wiring.test.ts tests/billingSettingsActions.renewalPermissions.wiring.test.ts tests/renewalsQueueActions.tenantReads.wiring.test.ts tests/renewalsQueueActions.tenantWrites.wiring.test.ts tests/renewalsQueueActions.transitionAudit.wiring.test.ts tests/renewalsQueueActions.createDraftAudit.wiring.test.ts tests/renewalsQueueActions.crossTenantValidation.wiring.test.ts tests/renewalsQueueActions.noteSanitization.wiring.test.ts tests/renewalsQueueActions.actorAudit.wiring.test.ts tests/renewalsQueueActions.timestampAudit.wiring.test.ts tests/renewalsQueueActions.noteAudit.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T130.- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.permissions.wiring.test.ts tests/billingSettingsActions.renewalPermissions.wiring.test.ts tests/renewalsQueueActions.tenantReads.wiring.test.ts tests/renewalsQueueActions.tenantWrites.wiring.test.ts tests/renewalsQueueActions.transitionAudit.wiring.test.ts tests/renewalsQueueActions.createDraftAudit.wiring.test.ts tests/renewalsQueueActions.crossTenantValidation.wiring.test.ts tests/renewalsQueueActions.noteSanitization.wiring.test.ts tests/renewalsQueueActions.actorAudit.wiring.test.ts tests/renewalsQueueActions.timestampAudit.wiring.test.ts tests/renewalsQueueActions.noteAudit.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T131.- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.permissions.wiring.test.ts tests/billingSettingsActions.renewalPermissions.wiring.test.ts tests/renewalsQueueActions.tenantReads.wiring.test.ts tests/renewalsQueueActions.tenantWrites.wiring.test.ts tests/renewalsQueueActions.transitionAudit.wiring.test.ts tests/renewalsQueueActions.createDraftAudit.wiring.test.ts tests/renewalsQueueActions.crossTenantValidation.wiring.test.ts tests/renewalsQueueActions.noteSanitization.wiring.test.ts tests/renewalsQueueActions.actorAudit.wiring.test.ts tests/renewalsQueueActions.timestampAudit.wiring.test.ts tests/renewalsQueueActions.noteAudit.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T132.- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.permissions.wiring.test.ts tests/billingSettingsActions.renewalPermissions.wiring.test.ts tests/renewalsQueueActions.tenantReads.wiring.test.ts tests/renewalsQueueActions.tenantWrites.wiring.test.ts tests/renewalsQueueActions.transitionAudit.wiring.test.ts tests/renewalsQueueActions.createDraftAudit.wiring.test.ts tests/renewalsQueueActions.crossTenantValidation.wiring.test.ts tests/renewalsQueueActions.noteSanitization.wiring.test.ts tests/renewalsQueueActions.actorAudit.wiring.test.ts tests/renewalsQueueActions.timestampAudit.wiring.test.ts tests/renewalsQueueActions.noteAudit.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T133.- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.permissions.wiring.test.ts tests/billingSettingsActions.renewalPermissions.wiring.test.ts tests/renewalsQueueActions.tenantReads.wiring.test.ts tests/renewalsQueueActions.tenantWrites.wiring.test.ts tests/renewalsQueueActions.transitionAudit.wiring.test.ts tests/renewalsQueueActions.createDraftAudit.wiring.test.ts tests/renewalsQueueActions.crossTenantValidation.wiring.test.ts tests/renewalsQueueActions.noteSanitization.wiring.test.ts tests/renewalsQueueActions.actorAudit.wiring.test.ts tests/renewalsQueueActions.timestampAudit.wiring.test.ts tests/renewalsQueueActions.noteAudit.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T134.- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.permissions.wiring.test.ts tests/billingSettingsActions.renewalPermissions.wiring.test.ts tests/renewalsQueueActions.tenantReads.wiring.test.ts tests/renewalsQueueActions.tenantWrites.wiring.test.ts tests/renewalsQueueActions.transitionAudit.wiring.test.ts tests/renewalsQueueActions.createDraftAudit.wiring.test.ts tests/renewalsQueueActions.crossTenantValidation.wiring.test.ts tests/renewalsQueueActions.noteSanitization.wiring.test.ts tests/renewalsQueueActions.actorAudit.wiring.test.ts tests/renewalsQueueActions.timestampAudit.wiring.test.ts tests/renewalsQueueActions.noteAudit.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T135.- Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.permissions.wiring.test.ts tests/billingSettingsActions.renewalPermissions.wiring.test.ts tests/renewalsQueueActions.tenantReads.wiring.test.ts tests/renewalsQueueActions.tenantWrites.wiring.test.ts tests/renewalsQueueActions.transitionAudit.wiring.test.ts tests/renewalsQueueActions.createDraftAudit.wiring.test.ts tests/renewalsQueueActions.crossTenantValidation.wiring.test.ts tests/renewalsQueueActions.noteSanitization.wiring.test.ts tests/renewalsQueueActions.actorAudit.wiring.test.ts tests/renewalsQueueActions.timestampAudit.wiring.test.ts tests/renewalsQueueActions.noteAudit.wiring.test.ts --coverage=false
- Validation:
- (2026-02-21) Completed
T136.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T137.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T138.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T139.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T140.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T141.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T142.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T143.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T144.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T145.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T146.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T147.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T148.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T149.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T150.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T151.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T152.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T153.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T154.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T155.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T156.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T157.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T158.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T159.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T160.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T161.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T162.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T163.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T164.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T165.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T166.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T167.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T168.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T169.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T170.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T171.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T172.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T173.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T174.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T175.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T176.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T177.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T178.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T179.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T180.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T181.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T182.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T183.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T184.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T185.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T186.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T187.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T188.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T189.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T190.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T191.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T192.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T193.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T194.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T195.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T196.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T197.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T198.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T199.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T200.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T201.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T202.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T203.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T204.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T205.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T206.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T207.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T208.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T209.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T210.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T211.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T212.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T213.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T214.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T215.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T216.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T217.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T218.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T219.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T220.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T221.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T222.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T223.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T224.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T225.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T226.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T227.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T228.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T229.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T230.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T231.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T232.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T233.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T234.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T235.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T236.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T237.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T238.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T239.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T240.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T241.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T242.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
T243.- Validation: consolidated renewal billing/server/ee suites executed and passing in this session.
- (2026-02-21) Completed
F136.- Added migration:
server/migrations/202602211100_add_contract_renewal_queue_status_audit_columns.cjs
- Migration adds renewal queue status/audit columns on
client_contracts:status,snoozed_until,assigned_to,last_action,last_action_by,last_action_at,last_action_note
- Added queue-status check constraint:
client_contracts_renewal_status_check(pending|renewing|non_renewing|snoozed|completed)
- Added tenant-scoped actor FKs (null-on-delete):
client_contracts_assigned_to_fkey(tenant,assigned_to) ->users(tenant, user_id)client_contracts_last_action_by_fkey(tenant,last_action_by) ->users(tenant, user_id)
- Migration is idempotent and Citus-safe (
ensureSequentialMode, guarded column/constraint checks). - Validation:
node -c server/migrations/202602211100_add_contract_renewal_queue_status_audit_columns.cjs
- Added migration:
- (2026-02-21) Completed
F137.- Added migration:
server/migrations/202602211105_add_contract_renewal_cycle_columns.cjs
- Migration adds renewal-cycle fields on
client_contracts:decision_due_daterenewal_cycle_startrenewal_cycle_endrenewal_cycle_key
- Migration remains idempotent and Citus-safe with guarded column checks.
- Validation:
node -c server/migrations/202602211105_add_contract_renewal_cycle_columns.cjs
- Added migration:
- (2026-02-21) Completed
F138.- Added migration:
server/migrations/202602211110_add_contract_renewal_automation_columns.cjs
- Migration adds renewal automation linkage/policy columns on
client_contracts:created_ticket_id,automation_error,renewal_due_date_action_policyrenewal_ticket_board_id,renewal_ticket_status_id,renewal_ticket_priority,renewal_ticket_assignee_idcreated_draft_contract_id
- Added policy check constraint:
client_contracts_renewal_due_date_action_policy_check(queue_only|create_ticket)
- Migration remains idempotent and Citus-safe with guarded column/constraint checks.
- Validation:
node -c server/migrations/202602211110_add_contract_renewal_automation_columns.cjs
- Added migration:
- (2026-02-21) Completed
F139.- Added migration:
server/migrations/202602211115_add_contract_renewal_config_columns.cjs
- Migration adds renewal configuration columns on
client_contracts:renewal_mode,notice_period_days,renewal_term_months,use_tenant_renewal_defaults
- Added DB constraints aligned to wizard/server validation rules:
client_contracts_renewal_mode_check(none|manual|auto)client_contracts_notice_period_days_check(>= 0)client_contracts_renewal_term_months_check(NULL OR > 0)
- Migration remains idempotent and Citus-safe with guarded column/constraint checks.
- Validation:
node -c server/migrations/202602211115_add_contract_renewal_config_columns.cjs
- Added migration:
- (2026-02-21) Completed
F140.- Added migration:
server/migrations/202602211120_add_default_billing_renewal_columns.cjs
- Migration adds renewal defaults/policy columns on
default_billing_settings:default_renewal_mode,default_notice_period_days,renewal_due_date_action_policyrenewal_ticket_board_id,renewal_ticket_status_id,renewal_ticket_priority,renewal_ticket_assignee_id
- Added DB constraints for default value domains:
default_billing_settings_default_renewal_mode_checkdefault_billing_settings_default_notice_period_days_checkdefault_billing_settings_renewal_due_date_action_policy_check
- Migration remains idempotent and Citus-safe with guarded column/constraint checks.
- Validation:
node -c server/migrations/202602211120_add_default_billing_renewal_columns.cjs
- Added migration:
- (2026-02-21) Completed
F141.- Added backfill migration:
server/migrations/202602211125_backfill_active_client_contract_renewal_defaults.cjs
- Backfill scope:
- active fixed-term
client_contractsrows (is_active=true, joinedcontracts.status='active',end_date IS NOT NULL)
- active fixed-term
- Backfill behavior (only when target fields are missing):
- sets deterministic defaults:
renewal_mode='manual',notice_period_days=30,use_tenant_renewal_defaults=true - computes initial fixed-term cycle fields:
decision_due_date = end_date - notice_period_daysrenewal_cycle_start = start_date::daterenewal_cycle_end = end_date::daterenewal_cycle_key = fixed-term:<end_date>
- preserves existing non-null values via
COALESCEto avoid overwriting already-migrated data
- sets deterministic defaults:
- Migration is intentionally non-reversible (data backfill).
- Validation:
node -c server/migrations/202602211125_backfill_active_client_contract_renewal_defaults.cjs
- Added backfill migration:
- (2026-02-21) Completed
F142.- Added migration:
server/migrations/202602211130_add_contract_renewal_indexes_constraints.cjs
- Added renewal queue performance indexes on
client_contractsfor common filters/sorts:idx_client_contracts_renewal_due_status(tenant,decision_due_date,status) partial active+due-date-not-nullidx_client_contracts_renewal_owner_status(tenant,assigned_to,status) partial activeidx_client_contracts_renewal_mode_type(tenant,renewal_mode,end_date) partial activeidx_client_contracts_renewal_snooze(tenant,status,snoozed_until) partial active
- Added cycle dedupe uniqueness index:
ux_client_contracts_active_cycle_key(tenant,client_contract_id,renewal_cycle_key) partial active+cycle-key-not-null
- Migration remains Citus-safe and guarded by column existence checks.
- Validation:
node -c server/migrations/202602211130_add_contract_renewal_indexes_constraints.cjs
- Added migration:
- (2026-02-21) Completed
F143.- Added renewal schema-readiness guard in queue actions:
packages/billing/src/actions/renewalsQueueActions.tsassertRenewalSchemaReady(knex)now validates required renewal columns on:client_contractsdefault_billing_settings
- all renewals queue endpoints now fail fast with actionable migration guidance when required schema is missing.
- Added renewal schema-readiness enforcement in scheduled automation:
server/src/lib/jobs/handlers/processRenewalQueueHandler.ts- processor now throws actionable error listing missing renewal columns/tables instead of silently skipping.
- Validation:
npm -w @alga-psa/billing run typecheckcd server && npm run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.wiring.test.ts --coverage=falsecd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- Added renewal schema-readiness guard in queue actions:
- (2026-02-21) Completed
F144.- Removed required-column compatibility branching in strict migrated-schema paths:
packages/billing/src/actions/renewalsQueueActions.ts- queue list/load now uses direct migrated-schema fields for unsnooze + tenant-default joins.
- queue mutation/update helpers now write action audit fields directly (no per-column optional branch).
- retry-ticket flow now uses direct migrated-schema policy/routing fields.
server/src/lib/jobs/handlers/processRenewalQueueHandler.ts- post-guard processing now assumes migrated columns exist and applies direct policy/cycle/ticket updates.
- direct tenant-default selection list + default settings join used in all renewal processor reads.
- Updated strict-mode wiring assertions:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Validation:
npm -w @alga-psa/billing run typecheckcd server && npm run typechecknpm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.wiring.test.ts --coverage=falsecd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- Removed required-column compatibility branching in strict migrated-schema paths:
- (2026-02-21) Completed
T244.- Added migration coverage for renewal queue status/audit columns on
client_contractsin:server/src/test/unit/migrations/contractRenewalMigrations.test.ts
- Assertions cover required status/audit columns and status domain constraint wiring from migration
202602211100_add_contract_renewal_queue_status_audit_columns.cjs. - Validation:
cd server && npx vitest run src/test/unit/migrations/contractRenewalMigrations.test.ts --coverage=false
- Added migration coverage for renewal queue status/audit columns on
- (2026-02-21) Completed
T245.- Extended migration coverage for renewal-cycle columns in:
server/src/test/unit/migrations/contractRenewalMigrations.test.ts
- Assertions verify
decision_due_date,renewal_cycle_start,renewal_cycle_end, andrenewal_cycle_keyadd/drop wiring in migration202602211105_add_contract_renewal_cycle_columns.cjs. - Validation:
cd server && npx vitest run src/test/unit/migrations/contractRenewalMigrations.test.ts --coverage=false
- Extended migration coverage for renewal-cycle columns in:
- (2026-02-21) Completed
T246.- Extended migration coverage for renewal automation/policy linkage columns on
client_contractsin:server/src/test/unit/migrations/contractRenewalMigrations.test.ts
- Assertions verify ticket link, routing override, automation error, and policy-check constraint wiring from
202602211110_add_contract_renewal_automation_columns.cjs. - Validation:
cd server && npx vitest run src/test/unit/migrations/contractRenewalMigrations.test.ts --coverage=false
- Extended migration coverage for renewal automation/policy linkage columns on
- (2026-02-21) Completed
T247.- Extended migration coverage for renewal default/policy columns on
default_billing_settingsin:server/src/test/unit/migrations/contractRenewalMigrations.test.ts
- Assertions verify default renewal mode/notice/policy columns, ticket-routing default fields, and policy/validation constraints from
202602211120_add_default_billing_renewal_columns.cjs. - Validation:
cd server && npx vitest run src/test/unit/migrations/contractRenewalMigrations.test.ts --coverage=false
- Extended migration coverage for renewal default/policy columns on
- (2026-02-21) Completed
T248.- Extended migration coverage for renewal backfill behavior in:
server/src/test/unit/migrations/contractRenewalMigrations.test.ts
- Assertions verify data backfill SQL initializes deterministic renewal defaults/cycle fields and scopes updates to active fixed-term rows joined to active contracts.
- Validation:
cd server && npx vitest run src/test/unit/migrations/contractRenewalMigrations.test.ts --coverage=false
- Extended migration coverage for renewal backfill behavior in:
- (2026-02-21) Completed
T249.- Added strict-schema integration wiring test for renewals queue listing in:
packages/billing/tests/renewalsQueueActions.schemaReadiness.integration.test.ts
- Coverage verifies
listRenewalQueueRowsenforcesassertRenewalSchemaReady(knex)and uses migrated-schema query path without legacy missing-column fallback branches. - Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.schemaReadiness.integration.test.ts --coverage=false
- Constraint note:
- runtime-import action tests currently hit workspace package entry-resolution failures for
@alga-psa/db; migration/strict-schema integration coverage is therefore implemented via source-level wiring assertions (same style as existing renewal wiring suites).
- runtime-import action tests currently hit workspace package entry-resolution failures for
- Added strict-schema integration wiring test for renewals queue listing in:
- (2026-02-21) Completed
T250.- Extended strict-schema integration wiring coverage for snooze mutation in:
packages/billing/tests/renewalsQueueActions.schemaReadiness.integration.test.ts
- Assertions verify migrated-schema snooze path writes
status='snoozed',snoozed_until, and action audit metadata (last_action/actor/timestamp/note chain). - Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.schemaReadiness.integration.test.ts --coverage=false
- Extended strict-schema integration wiring coverage for snooze mutation in:
- (2026-02-21) Completed
T251.- Extended strict-schema integration wiring coverage for mark-renewing mutation in:
packages/billing/tests/renewalsQueueActions.schemaReadiness.integration.test.ts
- Assertions verify pending-only transition to
renewingplus actor/timestamp audit persistence in migrated-schema path. - Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.schemaReadiness.integration.test.ts --coverage=false
- Extended strict-schema integration wiring coverage for mark-renewing mutation in:
- (2026-02-21) Completed
T252.- Extended renewal job integration wiring coverage in:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Added assertions that
processRenewalQueueHandlercomputes/persistsdecision_due_date,renewal_cycle_start,renewal_cycle_end, andrenewal_cycle_keyfor eligible rows. - Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- Extended renewal job integration wiring coverage in:
- (2026-02-21) Completed
T253.- Extended renewal job integration wiring coverage in:
server/src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts
- Added assertions that ticket automation under
create_ticketuses tenant+contract+cycle idempotency identity and duplicate lookup/linking so at most one ticket is linked per cycle. - Validation:
cd server && npx vitest run src/lib/jobs/tests/renewalQueueScheduling.wiring.test.ts --coverage=false
- Extended renewal job integration wiring coverage in:
- (2026-02-21) Completed
T254.- Extended strict-schema integration wiring coverage for guard-failure path in:
packages/billing/tests/renewalsQueueActions.schemaReadiness.integration.test.ts
- Assertions verify
assertRenewalSchemaReadyfails fast with actionable missing-column error text instructing migration execution. - Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.schemaReadiness.integration.test.ts --coverage=false
- Extended strict-schema integration wiring coverage for guard-failure path in:
- (2026-02-21) Completed
T255.- Extended strict-schema integration wiring coverage for guard-pass operational path in:
packages/billing/tests/renewalsQueueActions.schemaReadiness.integration.test.ts
- Assertions verify all renewals queue endpoints invoke
assertRenewalSchemaReady(knex)and no longer rely on legacy missing-column fallback branches in strict migrated-schema mode. - Validation:
npm -w @alga-psa/billing exec vitest run tests/renewalsQueueActions.schemaReadiness.integration.test.ts --coverage=false
- Extended strict-schema integration wiring coverage for guard-pass operational path in: