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
119 lines
25 KiB
JSON
119 lines
25 KiB
JSON
[
|
|
{ "id": "T001", "description": "Unit: due-work row builder returns stable execution identity for a client-cadence billing-cycle-backed recurring row.", "implemented": true, "featureIds": ["F001", "F002", "F004"] },
|
|
{ "id": "T002", "description": "Unit: due-work row builder returns stable execution identity for a contract-cadence recurring service-period row with no billing-cycle bridge.", "implemented": true, "featureIds": ["F001", "F002", "F003", "F013"] },
|
|
{ "id": "T003", "description": "Unit: due-work row builder exposes cadence-source metadata, service-period labels, and invoice-window labels for client-cadence rows.", "implemented": true, "featureIds": ["F005", "F006"] },
|
|
{ "id": "T004", "description": "Unit: due-work row builder exposes cadence-source metadata, service-period labels, and invoice-window labels for contract-cadence rows.", "implemented": true, "featureIds": ["F005", "F006", "F007"] },
|
|
{ "id": "T005", "description": "Unit: due-work row builder includes contract and contract-line context for contract-cadence recurring windows.", "implemented": true, "featureIds": ["F007"] },
|
|
{ "id": "T006", "description": "Unit: due-work selection excludes billed recurring service periods from the ready-to-invoice reader.", "implemented": true, "featureIds": ["F011", "F012"] },
|
|
{ "id": "T007", "description": "Unit: due-work selection excludes archived and superseded recurring service periods from the ready-to-invoice reader.", "implemented": true, "featureIds": ["F011", "F012"] },
|
|
{ "id": "T008", "description": "Unit: due-work selection includes a compatibility client-cadence row when no persisted recurring service-period row exists yet.", "implemented": true, "featureIds": ["F004", "F013"] },
|
|
{ "id": "T009", "description": "Integration: due-work reader returns mixed client-cadence and contract-cadence recurring rows for one tenant in a deterministic sort order.", "implemented": true, "featureIds": ["F003", "F004", "F005", "F013"] },
|
|
{ "id": "T010", "description": "Integration: due-work reader pagination remains stable when rows include a mix of bridged and unbridged recurring windows.", "implemented": true, "featureIds": ["F002", "F003", "F013"] },
|
|
{ "id": "T011", "description": "Integration: due-work reader search by client name works for contract-cadence rows with no client billing-cycle record.", "implemented": true, "featureIds": ["F003", "F013", "F028"] },
|
|
{ "id": "T012", "description": "Integration: due-work reader date filter operates on invoice-window dates rather than `client_billing_cycles.period_end_date` for contract-cadence rows.", "implemented": true, "featureIds": ["F003", "F006", "F028"] },
|
|
{ "id": "T013", "description": "Unit: recurring service-period backfill creates future active records for active recurring obligations with no existing rows.", "implemented": true, "featureIds": ["F014", "F072"] },
|
|
{ "id": "T014", "description": "Unit: recurring service-period replenishment reports missing-horizon state when future rows do not reach the configured target horizon.", "implemented": true, "featureIds": ["F015", "F022"] },
|
|
{ "id": "T015", "description": "Unit: recurring service-period regeneration preserves edited and billed override records while regenerating untouched future records.", "implemented": true, "featureIds": ["F016", "F067", "F068"] },
|
|
{ "id": "T016", "description": "Integration: recurring service-period regeneration updates active future rows after a cadence-owner or timing change and preserves billed history.", "implemented": true, "featureIds": ["F016", "F021", "F072"] },
|
|
{ "id": "T017", "description": "Migration: widening the recurring service-period participation model allows hourly recurring obligations to be represented in due-work selection.", "implemented": true, "featureIds": ["F017", "F019"] },
|
|
{ "id": "T018", "description": "Migration: widening the recurring service-period participation model allows usage recurring obligations to be represented in due-work selection.", "implemented": true, "featureIds": ["F018", "F019"] },
|
|
{ "id": "T019", "description": "Integration: billed recurring service periods link back to invoice charge detail rows after invoice creation for client-cadence recurring invoices.", "implemented": true, "featureIds": ["F020"] },
|
|
{ "id": "T020", "description": "Integration: billed recurring service periods link back to invoice charge detail rows after invoice creation for contract-cadence recurring invoices.", "implemented": true, "featureIds": ["F020", "F013"] },
|
|
{ "id": "T021", "description": "Integration: deleting a recurring invoice clears service-period invoice linkage and restores invoiceable lifecycle state for unbridged contract-cadence rows.", "implemented": true, "featureIds": ["F021", "F053", "F054"] },
|
|
{ "id": "T022", "description": "Integration: reversing a recurring invoice restores service-period state correctly for a bridged client-cadence row.", "implemented": true, "featureIds": ["F021", "F052", "F055"] },
|
|
{ "id": "T023", "description": "Unit: duplicate-prevention identity remains deterministic for a contract-cadence execution window with no billing-cycle bridge.", "implemented": true, "featureIds": ["F024"] },
|
|
{ "id": "T024", "description": "Integration: duplicate prevention prevents re-invoicing the same contract-cadence execution window even when there is no `billing_cycle_id`.", "implemented": true, "featureIds": ["F024", "F044", "F045"] },
|
|
{ "id": "T025", "description": "UI: AutomaticInvoices loads ready rows from the due-work reader instead of `getAvailableBillingPeriods(...)`.", "implemented": true, "featureIds": ["F025"] },
|
|
{ "id": "T026", "description": "UI: AutomaticInvoices renders a contract-cadence row that has no `billing_cycle_id`.", "implemented": true, "featureIds": ["F026", "F029", "F030"] },
|
|
{ "id": "T027", "description": "UI: AutomaticInvoices selection works for a mixed set of client-cadence and contract-cadence rows using execution identity keys.", "implemented": true, "featureIds": ["F027", "F031"] },
|
|
{ "id": "T028", "description": "UI: AutomaticInvoices pagination does not lose selection correctness when row identities are execution-window-based.", "implemented": true, "featureIds": ["F027", "F028"] },
|
|
{ "id": "T029", "description": "UI: AutomaticInvoices shows cadence-source, service-period, and invoice-window columns for contract-cadence rows.", "implemented": true, "featureIds": ["F029", "F030"] },
|
|
{ "id": "T030", "description": "UI: AutomaticInvoices shows contract-name context on contract-cadence rows and does not require a billing-cycle label fallback.", "implemented": true, "featureIds": ["F030"] },
|
|
{ "id": "T031", "description": "UI: AutomaticInvoices maps generation failures back to a contract-cadence row using execution identity when `billing_cycle_id` is null.", "implemented": true, "featureIds": ["F032", "F046"] },
|
|
{ "id": "T032", "description": "UI: AutomaticInvoices preview opens correctly for a client-cadence row through the selector-input preview path.", "implemented": true, "featureIds": ["F033", "F041", "F043"] },
|
|
{ "id": "T033", "description": "UI: AutomaticInvoices preview opens correctly for a contract-cadence row through the selector-input preview path.", "implemented": true, "featureIds": ["F033", "F041", "F043"] },
|
|
{ "id": "T034", "description": "UI: AutomaticInvoices batch generate submits selector-input execution windows for unbridged contract-cadence rows.", "implemented": true, "featureIds": ["F034", "F044"] },
|
|
{ "id": "T035", "description": "UI: AutomaticInvoices mixed batch generate submits billing-cycle-backed and unbridged selector-input rows together without losing identity.", "implemented": true, "featureIds": ["F031", "F034", "F037"] },
|
|
{ "id": "T036", "description": "UI: AutomaticInvoices batch PO-overage analysis resolves a contract-cadence row with no `billing_cycle_id`.", "implemented": true, "featureIds": ["F035", "F040", "F042"] },
|
|
{ "id": "T037", "description": "UI: AutomaticInvoices single-row preview generate path uses selector-input overage and generation for an unbridged contract-cadence row.", "implemented": true, "featureIds": ["F036", "F040", "F042", "F044"] },
|
|
{ "id": "T038", "description": "UI: preview state survives close/reopen for a selector-input recurring row without relying on `billing_cycle_id`.", "implemented": true, "featureIds": ["F039"] },
|
|
{ "id": "T039", "description": "UI: contract-cadence due rows show a clear badge or helper text indicating there is no client billing-cycle bridge.", "implemented": true, "featureIds": ["F038"] },
|
|
{ "id": "T040", "description": "UI: ready-to-invoice view still renders compatibility client-cadence rows during the cutover.", "implemented": true, "featureIds": ["F037"] },
|
|
{ "id": "T041", "description": "Unit: selector-input preview action validates invoice permissions the same way as the billing-cycle wrapper.", "implemented": true, "featureIds": ["F041", "F048"] },
|
|
{ "id": "T042", "description": "Integration: selector-input preview action returns the same recurring service-period details as billing-cycle preview for an equivalent client-cadence row.", "implemented": true, "featureIds": ["F041", "F043", "F047"] },
|
|
{ "id": "T043", "description": "Integration: selector-input preview action returns correct recurring service-period details for a contract-cadence row with no billing-cycle bridge.", "implemented": true, "featureIds": ["F041", "F043", "F047"] },
|
|
{ "id": "T044", "description": "Unit: selector-input PO-overage action returns null when the preview spans no PO-governed client contract.", "implemented": true, "featureIds": ["F042"] },
|
|
{ "id": "T045", "description": "Integration: selector-input PO-overage action computes overage correctly for a contract-cadence execution window.", "implemented": true, "featureIds": ["F042", "F048"] },
|
|
{ "id": "T046", "description": "Integration: recurring generation API accepts a selector-input execution window and creates an invoice with no `billing_cycle_id` bridge.", "implemented": true, "featureIds": ["F044", "F045", "F064"] },
|
|
{ "id": "T047", "description": "Integration: recurring generation API accepts a compatibility billing-cycle wrapper and routes internally through the selector-input pipeline.", "implemented": true, "featureIds": ["F044", "F064"] },
|
|
{ "id": "T048", "description": "Unit: preview and generate error payloads include execution identity for unbridged recurring windows.", "implemented": true, "featureIds": ["F046", "F070"] },
|
|
{ "id": "T049", "description": "Integration: preview and generate still enforce billing email validation for selector-input execution windows.", "implemented": true, "featureIds": ["F048"] },
|
|
{ "id": "T050", "description": "Integration: preview and generate still enforce PO-required contract validation for selector-input execution windows.", "implemented": true, "featureIds": ["F048"] },
|
|
{ "id": "T051", "description": "Integration: invoiced-history reader returns client-cadence recurring invoices with service-period metadata.", "implemented": true, "featureIds": ["F049", "F050", "F051"] },
|
|
{ "id": "T052", "description": "Integration: invoiced-history reader returns contract-cadence recurring invoices with service-period metadata and no billing-cycle bridge.", "implemented": true, "featureIds": ["F049", "F050", "F051"] },
|
|
{ "id": "T053", "description": "UI: invoiced recurring history view renders a contract-cadence invoice row and does not depend on `billing_cycle_id` for row actions.", "implemented": true, "featureIds": ["F049", "F050", "F051"] },
|
|
{ "id": "T054", "description": "Integration: reversing a contract-cadence recurring invoice updates invoiced history and restores service-period state.", "implemented": true, "featureIds": ["F052", "F054"] },
|
|
{ "id": "T055", "description": "Integration: hard-deleting a contract-cadence recurring invoice updates invoiced history and restores service-period state.", "implemented": true, "featureIds": ["F053", "F054"] },
|
|
{ "id": "T056", "description": "Integration: reversing a client-cadence compatibility invoice preserves the existing billing-cycle-backed behavior while updating service-period linkage.", "implemented": true, "featureIds": ["F052", "F055"] },
|
|
{ "id": "T057", "description": "Integration: hard-deleting a client-cadence compatibility invoice preserves the existing billing-cycle-backed behavior while updating service-period linkage.", "implemented": true, "featureIds": ["F053", "F055"] },
|
|
{ "id": "T058", "description": "UI: recurring invoice reverse/delete actions show correct copy for service-period-backed contract-cadence invoices.", "implemented": true, "featureIds": ["F056"] },
|
|
{ "id": "T059", "description": "Schema: invoice preview request schema accepts selector-input execution windows.", "implemented": true, "featureIds": ["F057"] },
|
|
{ "id": "T060", "description": "Schema: recurring invoice generation request schema accepts selector-input execution windows.", "implemented": true, "featureIds": ["F058"] },
|
|
{ "id": "T061", "description": "API: preview endpoint accepts a selector-input request and returns preview output successfully.", "implemented": true, "featureIds": ["F057", "F059", "F060"] },
|
|
{ "id": "T062", "description": "API: generate endpoint accepts a selector-input request and creates a recurring invoice successfully.", "implemented": true, "featureIds": ["F058", "F060", "F064"] },
|
|
{ "id": "T063", "description": "API: preview endpoint continues to accept `billing_cycle_id` compatibility requests during the cutover.", "implemented": true, "featureIds": ["F057", "F064"] },
|
|
{ "id": "T064", "description": "API: generate endpoint continues to accept `billing_cycle_id` compatibility requests during the cutover.", "implemented": true, "featureIds": ["F058", "F064"] },
|
|
{ "id": "T065", "description": "API: InvoiceService preview path no longer queries `client_billing_cycles` directly for unbridged contract-cadence requests.", "implemented": true, "featureIds": ["F059", "F063"] },
|
|
{ "id": "T066", "description": "API: invoice list/filter contract can return recurring invoices with execution-window metadata and nullable `billing_cycle_id`.", "implemented": true, "featureIds": ["F061", "F062"] },
|
|
{ "id": "T067", "description": "API: invoice list filter can query recurring invoices by execution-window kind or cadence source when provided.", "implemented": true, "featureIds": ["F061"] },
|
|
{ "id": "T068", "description": "UI/API compatibility: existing invoice consumers tolerate recurring invoices whose `billing_cycle_id` is null but whose service-period details are present.", "implemented": true, "featureIds": ["F062", "F064"] },
|
|
{ "id": "T069", "description": "Integration: hourly recurring charges bill approved time entries that fall inside a contract-cadence service period, not the nearest client billing cycle.", "implemented": true, "featureIds": ["F017", "F019"] },
|
|
{ "id": "T070", "description": "Integration: hourly recurring charges with no billable time inside the service period produce no recurring invoice line while preserving due-window identity.", "implemented": true, "featureIds": ["F017", "F019"] },
|
|
{ "id": "T071", "description": "Integration: usage recurring charges bill usage records that fall inside a contract-cadence service period, not the nearest client billing cycle.", "implemented": true, "featureIds": ["F018", "F019"] },
|
|
{ "id": "T072", "description": "Integration: usage recurring charges with no usage inside the service period produce no recurring invoice line while preserving due-window identity.", "implemented": true, "featureIds": ["F018", "F019"] },
|
|
{ "id": "T073", "description": "Integration: mixed recurring invoice generation can combine fixed, hourly, and usage content under one service-driven execution window when the commercial model requires it.", "implemented": true, "featureIds": ["F017", "F018", "F019", "F034"] },
|
|
{ "id": "T074", "description": "Unit: service-driven time and usage billing preserves canonical `servicePeriodStart`, `servicePeriodEnd`, and `billingTiming` metadata on generated charges.", "implemented": true, "featureIds": ["F017", "F018", "F047"] },
|
|
{ "id": "T075", "description": "Integration: due-work reader reports a missing-materialization state when a recurring obligation should exist but no future periods have been generated.", "implemented": true, "featureIds": ["F022", "F023"] },
|
|
{ "id": "T076", "description": "Permission: service-period view actions require `billing.recurring_service_periods.view`.", "implemented": true, "featureIds": ["F065", "F066"] },
|
|
{ "id": "T077", "description": "Permission: service-period regenerate actions require `billing.recurring_service_periods.regenerate`.", "implemented": true, "featureIds": ["F067", "F066"] },
|
|
{ "id": "T078", "description": "Permission: service-period repair/history correction actions require `billing.recurring_service_periods.correct_history`.", "implemented": true, "featureIds": ["F067", "F066"] },
|
|
{ "id": "T079", "description": "Integration: service-period regeneration action surfaces conflict payloads when a preserved edited/billed record no longer matches regenerated candidates.", "implemented": true, "featureIds": ["F067", "F068"] },
|
|
{ "id": "T080", "description": "UI: service-period management surface can show future generated rows, edited rows, and billed rows for one recurring obligation.", "implemented": true, "featureIds": ["F065", "F068"] },
|
|
{ "id": "T081", "description": "Workflow: recurring billing run started/completed/failed payloads record `contract_cadence_window` when a run contains only contract-cadence execution windows.", "implemented": true, "featureIds": ["F069"] },
|
|
{ "id": "T082", "description": "Workflow: recurring billing run payloads retain deterministic selection and retry keys for mixed client-cadence and contract-cadence due-work rows.", "implemented": true, "featureIds": ["F069"] },
|
|
{ "id": "T083", "description": "UI: recurring generation errors for unbridged rows display execution identity instead of blank client-name keys.", "implemented": true, "featureIds": ["F070"] },
|
|
{ "id": "T084", "description": "Runbook: backfill and replenishment commands are documented with enough detail to initialize service-driven invoicing in a local or staging tenant.", "implemented": true, "featureIds": ["F071", "F072"] },
|
|
{ "id": "T085", "description": "Runbook: reverse/delete repair workflow is documented for service-driven recurring invoices.", "implemented": true, "featureIds": ["F071", "F072"] },
|
|
{ "id": "T086", "description": "DB-backed integration: full happy path from due-work selection to preview to generate to invoiced-history works for a contract-cadence recurring invoice with no billing-cycle bridge.", "implemented": true, "featureIds": ["F003", "F033", "F034", "F049"] },
|
|
{ "id": "T087", "description": "DB-backed integration: full happy path from due-work selection to preview to generate to invoiced-history works for a client-cadence compatibility recurring invoice.", "implemented": true, "featureIds": ["F004", "F033", "F034", "F049"] },
|
|
{ "id": "T088", "description": "DB-backed integration: mixed batch generation from AutomaticInvoices creates both a bridged client-cadence recurring invoice and an unbridged contract-cadence recurring invoice.", "implemented": true, "featureIds": ["F031", "F034", "F049"] },
|
|
{ "id": "T089", "description": "DB-backed integration: deleting a contract-cadence recurring invoice makes the same execution window reappear in due-work selection.", "implemented": true, "featureIds": ["F021", "F053", "F054"] },
|
|
{ "id": "T090", "description": "DB-backed integration: reversing a bridged client-cadence recurring invoice preserves compatibility behavior and restores due selection appropriately.", "implemented": true, "featureIds": ["F021", "F052", "F055"] },
|
|
{ "id": "T091", "description": "Regression: legacy billing-cycle-only AutomaticInvoices flows still work when the selected row is a compatibility client-cadence row.", "implemented": true, "featureIds": ["F037", "F064"] },
|
|
{ "id": "T092", "description": "Regression: invoice list and invoice detail readers still populate service-period summaries for recurring invoices after the service-driven cutover.", "implemented": true, "featureIds": ["F062"] },
|
|
{ "id": "T093", "description": "Regression: purchase-order overage checks still behave correctly for legacy client-cadence recurring invoices after selector-input overage support is added.", "implemented": true, "featureIds": ["F042", "F064"] },
|
|
{ "id": "T094", "description": "Regression: recurring preview/generate wrappers still return the existing error shape for invalid or unauthorized compatibility billing-cycle requests.", "implemented": true, "featureIds": ["F057", "F058", "F064"] },
|
|
{ "id": "T095", "description": "Regression: materialized recurring service-period replenishment does not duplicate active future records when rerun idempotently.", "implemented": true, "featureIds": ["F015", "F024"] },
|
|
{ "id": "T096", "description": "Regression: service-driven invoicing cutover leaves non-recurring manual invoice flows unchanged.", "implemented": true, "featureIds": ["F064"] },
|
|
{ "id": "T097", "description": "UI: AutomaticInvoices disables preview for grouped candidates (`memberCount > 1`) and shows explicit copy explaining why preview is unavailable.", "implemented": true, "featureIds": ["F073"] },
|
|
{ "id": "T098", "description": "UI: AutomaticInvoices preview for single-member candidates still opens and uses the selected candidate selector input.", "implemented": true, "featureIds": ["F073"] },
|
|
{ "id": "T099", "description": "UI: AutomaticInvoices contract column derives contract names/line names from candidate members and does not collapse partially missing metadata to `No contract context`.", "implemented": true, "featureIds": ["F074"] },
|
|
{ "id": "T100", "description": "UI: AutomaticInvoices surfaces `Contract metadata missing` warning copy when member-level contract identity is incomplete.", "implemented": true, "featureIds": ["F074"] },
|
|
{ "id": "T101", "description": "UI: cadence-source rendering is exhaustive and unknown cadence-source values render an explicit unknown-state badge instead of `Client schedule`.", "implemented": true, "featureIds": ["F075"] },
|
|
{ "id": "T102", "description": "Unit: recurring run target mapper yields exactly one run target per client-cadence candidate (no row-flatten duplication).", "implemented": true, "featureIds": ["F076"] },
|
|
{ "id": "T103", "description": "Unit: `selectClientCadenceRecurringRunTargets` reports paging totals from candidate pages rather than target-count side effects.", "implemented": true, "featureIds": ["F076"] },
|
|
{ "id": "T104", "description": "DB-backed integration: generation rejects (or blocks) a partially materialized recurring window where eligible lines are missing persisted selections.", "implemented": true, "featureIds": ["F077"] },
|
|
{ "id": "T105", "description": "DB-backed integration: due-work reader marks partially materialized candidates non-generateable (or suppresses them) until materialization is repaired.", "implemented": true, "featureIds": ["F077"] },
|
|
{ "id": "T106", "description": "Unit: due-work candidate grouper respects purchase-order scope, currency, tax source, and export-shape split keys when determining candidate partitions.", "implemented": true, "featureIds": ["F078"] },
|
|
{ "id": "T107", "description": "Unit: legacy billing-window generation helpers are removed and no runtime callers import non-canonical recurring execution fallback builders.", "implemented": true, "featureIds": ["F079"] },
|
|
{ "id": "T108", "description": "Integration: billingInvoiceTiming recurring due-work assertions validate candidate-level contracts directly without `invoiceCandidates.flatMap(...)` row-flattening helpers.", "implemented": true, "featureIds": ["F080"] },
|
|
{ "id": "T109", "description": "DB-backed integration: client admin billing configuration actions no longer query `client_contract_lines` and still load/update recurring contract-line settings.", "implemented": true, "featureIds": ["F081"] },
|
|
{ "id": "T110", "description": "DB-backed integration: client-portal billing/account/services pages no longer query `client_contract_lines` and still render active recurring services correctly.", "implemented": true, "featureIds": ["F082"] },
|
|
{ "id": "T111", "description": "Integration: billing engine contract resolution joins only on instantiated `client_contracts.contract_id` without `template_contract_id` fallback joins.", "implemented": true, "featureIds": ["F083"] },
|
|
{ "id": "T112", "description": "Integration: contract assignment lookup rejects template IDs on instantiated contract detail queries and template detail loads remain supported via dedicated template path.", "implemented": true, "featureIds": ["F084"] },
|
|
{ "id": "T113", "description": "Unit/integration: `ContractLineService` no longer backfills or mutates `template_contract_id` during recurring line writes.", "implemented": true, "featureIds": ["F085"] },
|
|
{ "id": "T114", "description": "Static guard: post-drop client-contract-line hygiene tests scan `packages/client-portal` and `packages/clients` sources for forbidden legacy runtime table references.", "implemented": true, "featureIds": ["F086"] },
|
|
{ "id": "T115", "description": "Type-contract: paginated recurring due-work response and materialization-gap interfaces are exported from `@alga-psa/types` and consumed by billing actions/UI.", "implemented": true, "featureIds": ["F087"] },
|
|
{ "id": "T116", "description": "Type-contract: recurring due-work row `billingCycleId` semantics are explicitly enforced as either removed from canonical contracts or tagged as legacy display-only metadata.", "implemented": true, "featureIds": ["F088"] }
|
|
]
|