Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
11 KiB
PRD — Contract Auto-Renewal and Renewals Queue
- Slug:
contract-auto-renewal-and-renewals-queue - Date:
2026-02-21 - Status: Draft
Summary
Add first-class contract renewal management to Billing Contracts: renewal settings during contract setup, a dedicated actionable Renewals queue, and due-date automation that can create internal tickets. The system must support fixed-term and evergreen contracts, tenant defaults with optional per-contract override, and runtime compatibility for both on-prem (pg-boss) and hosted/EE (Temporal) automation execution.
Problem
MSPs currently rely on end_date awareness and ad-hoc process to decide whether to renew or terminate contracts. This creates avoidable revenue leakage, missed non-renewal notices, and inconsistent ownership of renewal decisions.
Current contract surfaces support start/end dates and expiration reporting, but they do not support:
- explicit renewal behavior on each contract assignment,
- a single operational queue for upcoming renewal decisions,
- standardized queue actions (
renewing,non-renewing,create draft,snooze), - configurable due-date automation (ticket creation) with assignment defaults.
Goals
- Capture renewal intent and notice-window behavior at contract creation/edit time.
- Compute and surface a single operational date (
decision_due_date) for renewal work. - Provide an actionable Renewals queue with 90-day triage buckets and owner/status workflows.
- Support tenant-level defaults with optional per-contract override.
- Automatically create internal renewal tickets at due date when configured.
- Support fixed-term contracts and evergreen annual-review flow in the same queue model.
- Ship as one cohesive release spanning wizard, queue, actions, and automation.
Non-goals
- Sending customer-facing renewal quote emails from queue actions.
- New billing/invoice pricing engines for renewal uplift or pro forma quoting.
- Full CLM/legal document lifecycle features.
- Replacing existing contract status model (
draft,active,terminated,expired) in this release. - New feature-flag infrastructure or rollout orchestration beyond normal release controls.
Users and Primary Flows
- Billing manager / account manager:
- sets renewal behavior during contract creation/edit,
- reviews upcoming decisions in queue,
- marks contracts renewing or non-renewing,
- snoozes decisions with explicit date.
- Service manager / coordinator:
- owns assigned renewal tasks,
- works queue by due-date buckets,
- opens renewal draft contracts from queue.
Primary flows:
- Create fixed-term contract with end date, choose renewal behavior and notice period.
- Create evergreen contract (no end date) with annual-review configuration.
- Review queue by
0-30,31-60,61-90decision windows. - Mark
renewingand auto-create next-term draft contract. - Mark
non-renewingand close renewal work item. - Snooze and assign renewal work item.
- Due-date automation creates internal ticket when configured.
UX / UI Notes
Contract Basicsstep (ContractWizard) gets a conditionalRenewal Settingscard:
- if
end_dateexists: fixed-term renewal settings. - if
end_dateabsent: evergreen annual review settings.
- Billing gets a new top-level
Renewalstab/page:
- queue table with filters + action menu,
- default horizon 90 days,
- bucket presets and owner filters.
Client Contractstab gets anUpcoming Renewalssummary widget:
- count by 0-30 / 31-60 / 61-90,
- quick entry into Renewals queue.
- Queue actions in v1:
Mark renewing(auto-create renewal draft and open editor),Mark non-renewing,Create renewal draft,Snooze.
- Queue primary sort key is
decision_due_date(not raw contract end date).
Requirements
Functional Requirements
FR1 — Contract Setup and Renewal Configuration
- Capture renewal settings on client contract assignments in the contract wizard and edit flows.
- Support renewal modes:
none,manual,auto. - If fixed-term (
end_dateset), capture notice period and renewal term behavior. - If evergreen (
end_datenull), capture annual-review cadence and notice period. - Validate incompatible states in UI and server (e.g., auto-renew with missing term strategy when required).
FR2 — Tenant Defaults and Contract-Level Overrides
- Add tenant defaults for renewal behavior and due-date automation target.
- Support per-contract override toggle (
use tenant defaultsvs explicit override values). - Preserve deterministic fallback behavior when override values are partially unset.
FR3 — Renewal Decision Date Engine
- Compute
decision_due_datefor each active client contract. - Fixed-term formula:
decision_due_date = end_date - notice_period_days. - Evergreen formula: derive next anniversary window and subtract notice period days.
- Recompute decision dates when contract dates/settings change.
- Prevent duplicate active work items for the same contract renewal cycle.
FR4 — Renewals Queue and Dashboard Entry Points
- Add
RenewalsBilling tab and queue page. - Add
Upcoming Renewalswidget inClient Contractstab. - Queue must support filters: horizon, bucket, owner, status, renewal mode, fixed/evergreen.
- Queue must show due-date centric columns and actions.
FR5 — Queue Actions and Renewal Workflow
- Add queue statuses:
pending,renewing,non_renewing,snoozed,completed. - Implement action transitions with actor + timestamp + optional note.
Mark renewingmust auto-create draft renewal contract (per chosen product decision).Create renewal draftmust be available as explicit independent action.Snoozemust require a future target date.
FR6 — Automation and Ticket Creation
- At
decision_due_date, create/update queue work item if unresolved. - When tenant/contract policy says
create internal ticket, create one ticket idempotently. - Store linkage from renewal work item to created ticket.
- Ticket defaults (board/status/priority/assignee) must come from renewal automation settings.
FR7 — Evergreen Annual Review Flow
- Include evergreen contracts in queue using annual review cycle date.
- Support the same status/actions as fixed-term contracts.
- After a cycle is completed, prepare next evergreen cycle work item.
FR8 — Reporting and Existing Surface Alignment
- Align existing contract expiration reporting with renewal decision model.
- Preserve existing expiration semantics while adding decision-due visibility.
- Avoid regressions in existing
Contract Expiration Reportconsumers.
FR9 — Runtime Compatibility (On-prem PG Boss vs Hosted/EE Temporal)
- Renewal automation job path must support on-prem
pg-bossruntime. - Renewal automation job path must support hosted/EE
Temporalruntime. - Ensure behavior parity regardless of runtime (idempotency, ticket creation, retry semantics).
- Respect existing runtime selection and fallback patterns (
JobRunnerFactory).
FR10 — Permissions, Security, and Auditability
- Restrict queue mutations to authorized billing users.
- Ensure tenant isolation in all queue queries and actions.
- Record auditable state transitions and key actor metadata.
Non-functional Requirements
- Queue list queries for default 90-day horizon should complete within existing Billing table UX expectations.
- Renewal work-item creation and ticket automation must be idempotent across retries.
- Runtime-independent behavior parity must be verified between
pg-bossandTemporalpaths. - All date handling must use existing date-only conventions for contract dates to avoid timezone drift.
Data / API / Integrations
Data model additions
client_contractsadditions (assignment-level settings):
renewal_mode(none|manual|auto)notice_period_days(int)renewal_term_months(nullable int)use_tenant_renewal_defaults(bool)- evergreen cycle metadata (as needed for annual review computation)
default_billing_settingsadditions (tenant defaults):
- default renewal mode
- default notice period
- due-date action policy (
queue_onlyorcreate_ticket) - default ticket routing fields (board/status/priority/assignee)
- New queue table (recommended):
client_contract_renewal_work_items:
- work item identity + tenant + client_contract_id
decision_due_date,cycle_start,cycle_endstatus,assigned_to,snoozed_untilcreated_ticket_id,created_draft_contract_idlast_action,last_action_by,last_action_at, note/reason fields
API / action surfaces
- Extend
ClientContractWizardSubmissionand related actions to include renewal settings. - New renewal queue actions:
- list/query queue
- mark renewing
- mark non-renewing
- create renewal draft
- snooze
- assign owner
- Integrate with existing ticket creation action path (
tickets.create) for automation side effects.
Integrations
- Billing dashboard/tab composition.
- Contract wizard basics step.
- Existing event bus + workflow runtime event model.
- On-prem scheduled jobs via
pg-boss. - Hosted/EE automation via
Temporal.
Security / Permissions
- Read queue: billing read permission.
- Mutate queue actions: billing update permission.
- Tenant defaults changes: billing settings update permission.
- Ticket automation execution: system/service actor with tenant-scoped permission enforcement.
Observability
No net-new observability framework is required for v1. Reuse existing audit/event patterns and existing job/runtime failure reporting surfaces. Track enough state in renewal work items to diagnose retries and failures without adding a separate telemetry subsystem.
Rollout / Migration
- Add schema migrations for new contract renewal columns, default settings fields, and queue table.
- Backfill existing active fixed-term contracts with deterministic defaults (
manual, default notice period, tenant default usage). - Do not auto-create queue/tickets for historical expired/terminated contracts.
- Stage rollout sequence:
- deploy schema + read-compatible code,
- deploy write paths and queue UI,
- enable scheduled automation processing.
Open Questions
- Should renewal automation ticket defaults be separate from inbound-ticket defaults, or reuse them where unspecified?
- What is the canonical evergreen anniversary anchor for contracts with manually edited start dates over time?
- Do we require a hard block against activating renewal drafts until the original contract is marked renewing/non-renewing, or allow parallel status transitions?
Acceptance Criteria (Definition of Done)
- Contract wizard supports fixed-term and evergreen renewal settings and persists them per client contract assignment.
- Billing has a functional Renewals queue tab with 90-day buckets and required actions.
Client Contractsincludes upcoming-renewals summary widget linked to queue.Mark renewingauto-creates and links a renewal draft contract.- Due-date automation creates at most one ticket per renewal cycle when policy is enabled.
- On-prem (
pg-boss) and hosted/EE (Temporal) execute equivalent renewal automation behavior. - Existing contract expiration report remains functional and reflects decision-date semantics where applicable.
- Features/tests checklists are populated and traceable to this PRD.