Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

1116 lines
25 KiB
JSON

[
{
"id": "T001",
"description": "Migration: quotes table created with correct columns including is_template boolean, types, and constraints",
"implemented": true,
"featureIds": [
"F001"
]
},
{
"id": "T002",
"description": "Migration: quotes table has indexes on (tenant, client_id), (tenant, status), (tenant, quote_number), (tenant, parent_quote_id)",
"implemented": true,
"featureIds": [
"F001"
]
},
{
"id": "T003",
"description": "Migration: quote_items table created with correct columns including is_selected, matching invoice_charges pattern plus quote-specific fields",
"implemented": true,
"featureIds": [
"F002"
]
},
{
"id": "T004",
"description": "Migration: quote_items FK to quotes cascades on delete",
"implemented": true,
"featureIds": [
"F002"
]
},
{
"id": "T005",
"description": "Migration: quote_activities table created with correct columns and FK to quotes",
"implemented": true,
"featureIds": [
"F003"
]
},
{
"id": "T006",
"description": "Numbering: 'QUOTE' entity type generates Q-0001 on first call",
"implemented": true,
"featureIds": [
"F004"
]
},
{
"id": "T007",
"description": "Numbering: sequential calls generate Q-0001, Q-0002, Q-0003",
"implemented": true,
"featureIds": [
"F004"
]
},
{
"id": "T008",
"description": "Numbering: different tenants have independent sequences",
"implemented": true,
"featureIds": [
"F004"
]
},
{
"id": "T009",
"description": "Types: IQuote interface includes all required fields with correct types",
"implemented": true,
"featureIds": [
"F005"
]
},
{
"id": "T010",
"description": "Types: QuoteStatus includes draft, sent, accepted, rejected, expired, converted, cancelled, superseded",
"implemented": true,
"featureIds": [
"F005"
]
},
{
"id": "T011",
"description": "Types: IQuoteListItem includes joined client name and computed display fields",
"implemented": true,
"featureIds": [
"F006"
]
},
{
"id": "T012",
"description": "Schema: createQuoteSchema requires client_id, title, quote_date, valid_until",
"implemented": true,
"featureIds": [
"F007"
]
},
{
"id": "T013",
"description": "Schema: createQuoteSchema rejects invalid dates (valid_until before quote_date)",
"implemented": true,
"featureIds": [
"F007"
]
},
{
"id": "T014",
"description": "Schema: createQuoteItemSchema requires description and validates quantity > 0",
"implemented": true,
"featureIds": [
"F008"
]
},
{
"id": "T015",
"description": "Schema: status transition validation allows draft\u2192sent but rejects draft\u2192accepted",
"implemented": true,
"featureIds": [
"F009"
]
},
{
"id": "T016",
"description": "Schema: status transition validation allows sent\u2192accepted, sent\u2192rejected, sent\u2192expired, sent\u2192cancelled",
"implemented": true,
"featureIds": [
"F009"
]
},
{
"id": "T017",
"description": "Schema: status transition validation allows accepted\u2192converted but rejects converted\u2192draft",
"implemented": true,
"featureIds": [
"F009"
]
},
{
"id": "T018",
"description": "Model: getById returns quote with items for correct tenant",
"implemented": true,
"featureIds": [
"F010"
]
},
{
"id": "T019",
"description": "Model: getById returns null for wrong tenant (isolation)",
"implemented": true,
"featureIds": [
"F010"
]
},
{
"id": "T020",
"description": "Model: getById auto-expires quote if valid_until < today and status is 'sent'",
"implemented": true,
"featureIds": [
"F017"
]
},
{
"id": "T021",
"description": "Model: getById does not auto-expire drafts or accepted quotes",
"implemented": true,
"featureIds": [
"F017"
]
},
{
"id": "T022",
"description": "Model: getByNumber returns correct quote by human-readable number within tenant",
"implemented": true,
"featureIds": [
"F011"
]
},
{
"id": "T023",
"description": "Model: listByTenant returns paginated results with correct total count",
"implemented": true,
"featureIds": [
"F012"
]
},
{
"id": "T024",
"description": "Model: listByTenant filters by status correctly",
"implemented": true,
"featureIds": [
"F012"
]
},
{
"id": "T025",
"description": "Model: listByTenant filters by client_id correctly",
"implemented": true,
"featureIds": [
"F012"
]
},
{
"id": "T026",
"description": "Model: listByTenant sorts by quote_date descending by default",
"implemented": true,
"featureIds": [
"F012"
]
},
{
"id": "T027",
"description": "Model: listByClient returns only quotes for specified client",
"implemented": true,
"featureIds": [
"F013"
]
},
{
"id": "T028",
"description": "Model: create inserts quote with generated quote_number and logs 'created' activity",
"implemented": true,
"featureIds": [
"F014"
]
},
{
"id": "T029",
"description": "Model: create sets default status to 'draft'",
"implemented": true,
"featureIds": [
"F014"
]
},
{
"id": "T030",
"description": "Model: update changes fields and logs 'updated' activity",
"implemented": true,
"featureIds": [
"F015"
]
},
{
"id": "T031",
"description": "Model: update rejects invalid status transitions",
"implemented": true,
"featureIds": [
"F015"
]
},
{
"id": "T032",
"description": "Model: delete removes draft quotes with no business history via deleteEntityWithValidation",
"implemented": true,
"featureIds": [
"F016",
"F049a"
]
},
{
"id": "T033",
"description": "Model: delete blocks non-draft quotes and offers archive alternative",
"implemented": true,
"featureIds": [
"F016",
"F049a"
]
},
{
"id": "T033a",
"description": "Model: delete blocks drafts that have business history (emails sent, etc.) and offers archive",
"implemented": true,
"featureIds": [
"F016",
"F049a"
]
},
{
"id": "T034",
"description": "Item model: listByQuoteId returns items ordered by display_order",
"implemented": true,
"featureIds": [
"F018"
]
},
{
"id": "T035",
"description": "Item model: create with service_id populates service_name, service_sku, unit_price from catalog",
"implemented": true,
"featureIds": [
"F019"
]
},
{
"id": "T036",
"description": "Item model: create without service_id allows custom item entry",
"implemented": true,
"featureIds": [
"F019"
]
},
{
"id": "T037",
"description": "Item model: update allows rate override (different unit_price than catalog default)",
"implemented": true,
"featureIds": [
"F020"
]
},
{
"id": "T038",
"description": "Item model: delete removes item and adjusts display_order of remaining items",
"implemented": true,
"featureIds": [
"F021"
]
},
{
"id": "T039",
"description": "Item model: reorder updates display_order for all items in batch",
"implemented": true,
"featureIds": [
"F022"
]
},
{
"id": "T040",
"description": "Activity model: create stores activity with all fields and auto-timestamps",
"implemented": true,
"featureIds": [
"F023"
]
},
{
"id": "T041",
"description": "Activity model: listByQuoteId returns activities in chronological order",
"implemented": true,
"featureIds": [
"F024"
]
},
{
"id": "T042",
"description": "Action: createQuote requires billing:create permission",
"implemented": true,
"featureIds": [
"F025"
]
},
{
"id": "T043",
"description": "Action: createQuote returns quote with generated number",
"implemented": true,
"featureIds": [
"F025"
]
},
{
"id": "T044",
"description": "Action: updateQuote enforces status transition rules",
"implemented": true,
"featureIds": [
"F026"
]
},
{
"id": "T045",
"description": "Action: deleteQuote rejects deletion of sent/accepted quotes",
"implemented": true,
"featureIds": [
"F028"
]
},
{
"id": "T046",
"description": "Action: addQuoteItem with service_id populates defaults from catalog",
"implemented": true,
"featureIds": [
"F029"
]
},
{
"id": "T047",
"description": "Action: addQuoteItem with all four billing methods (fixed, hourly, usage, per_unit)",
"implemented": true,
"featureIds": [
"F033"
]
},
{
"id": "T048",
"description": "Action: addQuoteItem allows rate override different from catalog default",
"implemented": true,
"featureIds": [
"F032"
]
},
{
"id": "T049",
"description": "Action: addQuoteItem stores is_optional=true when flagged",
"implemented": true,
"featureIds": [
"F034"
]
},
{
"id": "T050",
"description": "Action: addQuoteItem stores is_recurring=true with billing_frequency",
"implemented": true,
"featureIds": [
"F035"
]
},
{
"id": "T050a",
"description": "Business template: creating a quote template sets is_template=true and does not generate a quote_number",
"implemented": true,
"featureIds": [
"F036"
]
},
{
"id": "T050b",
"description": "Business template: createQuoteFromTemplate copies all items from template to new draft quote",
"implemented": true,
"featureIds": [
"F036a"
]
},
{
"id": "T050c",
"description": "Business template: createQuoteFromTemplate generates a new quote_number for the draft",
"implemented": true,
"featureIds": [
"F036a"
]
},
{
"id": "T050d",
"description": "Business template: template list filters by is_template=true, quote list filters by is_template=false/null",
"implemented": true,
"featureIds": [
"F036b"
]
},
{
"id": "T050e",
"description": "Business template: templates are not included in status lifecycle (no sent/accepted/etc.)",
"implemented": true,
"featureIds": [
"F036"
]
},
{
"id": "T051",
"description": "Tax: calculateTax called per taxable item with correct net_amount and region",
"implemented": true,
"featureIds": [
"F050"
]
},
{
"id": "T052",
"description": "Tax: is_taxable=false items get zero tax_amount",
"implemented": true,
"featureIds": [
"F051"
]
},
{
"id": "T053",
"description": "Tax: tax-exempt client gets zero tax on all items",
"implemented": true,
"featureIds": [
"F051"
]
},
{
"id": "T054",
"description": "Tax: reverse charge applicable client gets zero tax",
"implemented": true,
"featureIds": [
"F051"
]
},
{
"id": "T055",
"description": "Tax: per-item tax_region and tax_rate stored correctly after calculation",
"implemented": true,
"featureIds": [
"F052"
]
},
{
"id": "T056",
"description": "Discount: percentage discount calculates correct amount from target item total",
"implemented": true,
"featureIds": [
"F054"
]
},
{
"id": "T057",
"description": "Discount: fixed discount stores exact amount as total_price",
"implemented": true,
"featureIds": [
"F054"
]
},
{
"id": "T058",
"description": "Discount: applies_to_item_id scopes discount to specific item's net_amount",
"implemented": true,
"featureIds": [
"F055"
]
},
{
"id": "T059",
"description": "Discount: applies_to_service_id scopes discount to all items of that service",
"implemented": true,
"featureIds": [
"F056"
]
},
{
"id": "T060",
"description": "Discount: quote-level discount (no target) applies to full subtotal",
"implemented": true,
"featureIds": [
"F057"
]
},
{
"id": "T061",
"description": "Totals: subtotal equals sum of non-discount item total_prices",
"implemented": true,
"featureIds": [
"F058"
]
},
{
"id": "T062",
"description": "Totals: discount_total equals sum of discount line amounts",
"implemented": true,
"featureIds": [
"F058"
]
},
{
"id": "T063",
"description": "Totals: total_amount = subtotal - discount_total + tax",
"implemented": true,
"featureIds": [
"F058"
]
},
{
"id": "T064",
"description": "Totals: adding an item triggers recalculation of all totals",
"implemented": true,
"featureIds": [
"F059"
]
},
{
"id": "T065",
"description": "Totals: removing an item triggers recalculation",
"implemented": true,
"featureIds": [
"F059"
]
},
{
"id": "T066",
"description": "Totals: toggling optional item off excludes it from totals",
"implemented": true,
"featureIds": [
"F060"
]
},
{
"id": "T067",
"description": "Totals: toggling optional item back on includes it in totals",
"implemented": true,
"featureIds": [
"F060"
]
},
{
"id": "T068",
"description": "Versioning: revise creates new quote row with version+1 and parent_quote_id set",
"implemented": true,
"featureIds": [
"F061"
]
},
{
"id": "T069",
"description": "Versioning: revise copies all quote_items to new version with new item_ids",
"implemented": true,
"featureIds": [
"F062"
]
},
{
"id": "T070",
"description": "Versioning: old version status set to 'superseded' after revision",
"implemented": true,
"featureIds": [
"F063"
]
},
{
"id": "T071",
"description": "Versioning: new version has same quote_number as original",
"implemented": true,
"featureIds": [
"F064"
]
},
{
"id": "T072",
"description": "Versioning: can revise a rejected quote (creates new version from rejected)",
"implemented": true,
"featureIds": [
"F061"
]
},
{
"id": "T073",
"description": "Version history: query returns all versions ordered by version number",
"implemented": true,
"featureIds": [
"F065"
]
},
{
"id": "T074",
"description": "Version history: works for quotes with 3+ versions",
"implemented": true,
"featureIds": [
"F065"
]
},
{
"id": "T075",
"description": "Template migration: quote_templates table has templateAst JSONB column",
"implemented": true,
"featureIds": [
"F070"
]
},
{
"id": "T076",
"description": "Template migration: standard_quote_templates seeded with default and detailed templates",
"implemented": true,
"featureIds": [
"F071"
]
},
{
"id": "T076a",
"description": "Template migration: standard quote template seed upsert succeeds on repeated runs",
"implemented": true,
"featureIds": [
"F071a"
]
},
{
"id": "T077",
"description": "QuoteViewModel: correctly maps all quote fields including items with optional/recurring metadata",
"implemented": true,
"featureIds": [
"F073"
]
},
{
"id": "T078",
"description": "AST bindings: quoteNumber, quoteDate, validUntil resolve to correct quote values",
"implemented": true,
"featureIds": [
"F074"
]
},
{
"id": "T079",
"description": "AST bindings: lineItems collection includes is_optional and is_recurring flags per item",
"implemented": true,
"featureIds": [
"F075"
]
},
{
"id": "T080",
"description": "Standard template: 'standard-quote-default' renders valid HTML with all sections",
"implemented": true,
"featureIds": [
"F076"
]
},
{
"id": "T081",
"description": "Standard template: 'standard-quote-detailed' renders phase grouping and optional item markers",
"implemented": true,
"featureIds": [
"F077"
]
},
{
"id": "T082",
"description": "Adapter: mapDbQuoteToViewModel fetches and joins client, contact, tenant data",
"implemented": true,
"featureIds": [
"F078"
]
},
{
"id": "T083",
"description": "PDF: generates valid PDF buffer from quote data",
"implemented": true,
"featureIds": [
"F079"
]
},
{
"id": "T084",
"description": "PDF: stores generated file in file storage and returns file_id",
"implemented": true,
"featureIds": [
"F080"
]
},
{
"id": "T085",
"description": "Preview: renders quote template in-browser without Puppeteer",
"implemented": true,
"featureIds": [
"F081"
]
},
{
"id": "T086",
"description": "Template selection: uses quote-specific template_id if set",
"implemented": true,
"featureIds": [
"F082"
]
},
{
"id": "T087",
"description": "Template selection: falls back to tenant default when no per-quote template",
"implemented": true,
"featureIds": [
"F082"
]
},
{
"id": "T088",
"description": "Template selection: falls back to standard-quote-default when no tenant default",
"implemented": true,
"featureIds": [
"F082"
]
},
{
"id": "T089",
"description": "Send: sendQuote rejects quotes not in draft/approved status",
"implemented": true,
"featureIds": [
"F084"
]
},
{
"id": "T090",
"description": "Send: sendQuote generates PDF, sends email to specified address(es), updates sent_at and status to 'sent'",
"implemented": true,
"featureIds": [
"F084"
]
},
{
"id": "T090a",
"description": "Send: sendQuote accepts array of email addresses and sends to all of them",
"implemented": true,
"featureIds": [
"F084"
]
},
{
"id": "T091",
"description": "Send: sendQuote logs 'sent' activity",
"implemented": true,
"featureIds": [
"F084"
]
},
{
"id": "T092",
"description": "Email: 'Quote Sent' email includes quote summary and PDF attachment",
"implemented": true,
"featureIds": [
"F085"
]
},
{
"id": "T093",
"description": "Email: sent email logged in email_sending_logs with entity_type='quote'",
"implemented": true,
"featureIds": [
"F088"
]
},
{
"id": "T094",
"description": "Client portal: QuotesTab loads and displays client's quotes",
"implemented": true,
"featureIds": [
"F089",
"F090"
]
},
{
"id": "T095",
"description": "Client portal: QuotesTab only shows quotes for authenticated client",
"implemented": true,
"featureIds": [
"F090"
]
},
{
"id": "T096",
"description": "Client portal: QuoteDetail shows full line items with optional item indicators",
"implemented": true,
"featureIds": [
"F091"
]
},
{
"id": "T097",
"description": "Client portal: toggling optional item on/off recalculates displayed total and persists is_selected server-side",
"implemented": true,
"featureIds": [
"F092"
]
},
{
"id": "T097a",
"description": "Client portal: optional item selections persist across page reloads",
"implemented": true,
"featureIds": [
"F092"
]
},
{
"id": "T098",
"description": "Client portal: Accept persists optional item selections and sets accepted_at, accepted_by, status to 'accepted'",
"implemented": true,
"featureIds": [
"F093"
]
},
{
"id": "T098a",
"description": "MSP detail view: accepted quote with optional items shows client's selections highlighted for review",
"implemented": true,
"featureIds": [
"F093a"
]
},
{
"id": "T100",
"description": "Client portal: Reject requires comment, sets rejected_at, rejection_reason, status to 'rejected'",
"implemented": true,
"featureIds": [
"F094"
]
},
{
"id": "T101",
"description": "Client portal: first view sets viewed_at timestamp and logs activity",
"implemented": true,
"featureIds": [
"F096"
]
},
{
"id": "T102",
"description": "Client portal: second view does not overwrite viewed_at",
"implemented": true,
"featureIds": [
"F096"
]
},
{
"id": "T103",
"description": "Client portal: cannot accept/reject expired quote",
"implemented": true,
"featureIds": [
"F093",
"F094"
]
},
{
"id": "T104",
"description": "Conversion: Quote\u2192Contract creates draft contract with correct name and dates",
"implemented": true,
"featureIds": [
"F098"
]
},
{
"id": "T105",
"description": "Conversion: recurring fixed-price item creates contract_line + _fixed_config",
"implemented": true,
"featureIds": [
"F099",
"F100"
]
},
{
"id": "T106",
"description": "Conversion: recurring hourly item creates contract_line + _hourly_config",
"implemented": true,
"featureIds": [
"F099",
"F100"
]
},
{
"id": "T107",
"description": "Conversion: recurring usage item creates contract_line + _usage_config",
"implemented": true,
"featureIds": [
"F099",
"F100"
]
},
{
"id": "T108",
"description": "Conversion: client_contracts assignment created with correct client and dates",
"implemented": true,
"featureIds": [
"F101"
]
},
{
"id": "T109",
"description": "Conversion: converted_contract_id set on quote after contract creation",
"implemented": true,
"featureIds": [
"F102"
]
},
{
"id": "T110",
"description": "Conversion: Quote\u2192Invoice creates draft invoice with is_manual=true",
"implemented": true,
"featureIds": [
"F103"
]
},
{
"id": "T111",
"description": "Conversion: one-time items mapped to invoice_charges with correct tax/discount data",
"implemented": true,
"featureIds": [
"F104"
]
},
{
"id": "T112",
"description": "Conversion: converted_invoice_id set on quote after invoice creation",
"implemented": true,
"featureIds": [
"F105"
]
},
{
"id": "T113",
"description": "Conversion: combined conversion creates both contract and invoice in single transaction",
"implemented": true,
"featureIds": [
"F106"
]
},
{
"id": "T114",
"description": "Conversion: combined conversion rolls back both if invoice creation fails after contract creation",
"implemented": true,
"featureIds": [
"F106"
]
},
{
"id": "T115",
"description": "Conversion: status set to 'converted' after successful conversion",
"implemented": true,
"featureIds": [
"F106"
]
},
{
"id": "T116",
"description": "Conversion: preview correctly categorizes items as contract-bound vs invoice-bound",
"implemented": true,
"featureIds": [
"F107"
]
},
{
"id": "T117",
"description": "Conversion: optional items with is_selected=false (excluded by client) are not converted",
"implemented": true,
"featureIds": [
"F098",
"F103"
]
},
{
"id": "T118",
"description": "Conversion: post-conversion quote detail shows links to created contract and invoice",
"implemented": true,
"featureIds": [
"F109"
]
},
{
"id": "T119",
"description": "Approval: 'Submit for Approval' changes status from draft to pending_approval",
"implemented": true,
"featureIds": [
"F111"
]
},
{
"id": "T119a",
"description": "Approval migration: quotes status constraint allows pending_approval and approved",
"implemented": true,
"featureIds": [
"F110a"
]
},
{
"id": "T120",
"description": "Approval: approve changes status from pending_approval to approved",
"implemented": true,
"featureIds": [
"F113"
]
},
{
"id": "T121",
"description": "Approval: reject returns quote to draft with comment",
"implemented": true,
"featureIds": [
"F113"
]
},
{
"id": "T122",
"description": "Approval: quotes:approve permission required \u2014 user without it gets denied",
"implemented": true,
"featureIds": [
"F114"
]
},
{
"id": "T123",
"description": "Approval: when disabled per tenant, draft\u2192sent transition allowed directly",
"implemented": true,
"featureIds": [
"F113"
]
},
{
"id": "T124",
"description": "Duplication: creates new quote with new number, draft status, copied items",
"implemented": true,
"featureIds": [
"F119"
]
},
{
"id": "T125",
"description": "Duplication: duplicated items have new item_ids (not referencing original)",
"implemented": true,
"featureIds": [
"F119"
]
},
{
"id": "T126",
"description": "Auto-expiration job: bulk-expires all sent quotes past valid_until",
"implemented": true,
"featureIds": [
"F118"
]
},
{
"id": "T127",
"description": "Save as Template: creates business template from existing quote with is_template=true, copies items",
"implemented": true,
"featureIds": [
"F120"
]
},
{
"id": "T128",
"description": "Save as Template: template does not copy quote-specific fields (client, contact, dates, status)",
"implemented": true,
"featureIds": [
"F120"
]
}
]