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

5.8 KiB

Project Materials Drawer - Scratchpad

Initial Discovery (2026-02-04)

  • Ticket Materials PR #1701 (merged 2026-01-29): 328eff8b0 - "feat: implement ticket materials with multi-currency"
  • Tag Filter Fix: 6057c5bd0 - "Fix tag filter to preserve colors and clean orphans"

Architecture Decision: Component Location

Pattern Discovered: TicketMaterialsCard lives in @alga-psa/tickets, NOT in @alga-psa/billing.

Decision: Keep ProjectMaterialsDrawer in @alga-psa/projects and add @alga-psa/billing as a dependency.

Rationale:

  • Follows established pattern (TicketMaterialsCard in tickets, imports from billing)
  • Feature modules keep their UI components
  • Import actions from the domain owner (billing)

Required Package Change

packages/projects/package.json needs:

"dependencies": {
  "@alga-psa/billing": "*",
  // ... existing
}

Existing Infrastructure

Server Actions (Already Exist!)

Located in packages/billing/src/actions/materialActions.ts:

  • listProjectMaterials(projectId) - Returns IProjectMaterial[] with service_name and sku joined
  • addProjectMaterial(input) - Creates new material (rate in cents, quantity floored to min 1)
  • deleteProjectMaterial(projectMaterialId) - Deletes if not billed

All actions are already exported from @alga-psa/billing/actions.

Data Model

IProjectMaterial interface (packages/types/src/interfaces/material.interfaces.ts):

  • project_material_id: string - Primary key
  • project_id: string - Foreign key to project
  • client_id: string - Foreign key to client (for billing)
  • service_id: string - Foreign key to service_catalog (product)
  • service_name?: string - Denormalized from service_catalog
  • sku?: string | null - Product SKU
  • quantity: number
  • rate: number - Price in cents
  • currency_code: string - ISO 4217 currency code
  • description?: string | null
  • is_billed: boolean

Key Files

File Purpose
packages/projects/package.json Add billing dependency
packages/projects/src/components/ProjectMaterialsDrawer.tsx Implement drawer
packages/tickets/src/components/ticket/TicketMaterialsCard.tsx Reference impl
packages/billing/src/actions/materialActions.ts Actions (complete)

Decisions Log

Date Decision Rationale
2026-02-04 Keep component in projects package Follows TicketMaterialsCard pattern
2026-02-04 Add @alga-psa/billing dependency Required for material actions
2026-02-04 12 features, 18 tests Streamlined from initial 41/78

Updates

  • 2026-02-04: Added @alga-psa/billing dependency to packages/projects/package.json for project materials drawer actions.
  • 2026-02-04: Added drawer header scaffold and set project materials drawer width to 560px via openDrawer.
  • 2026-02-04: Wired ProjectMaterialsDrawer to listProjectMaterials with loading and empty states.
  • 2026-02-04: Added materials table layout with product, SKU, qty, rate, total, and status badge columns.
  • 2026-02-04: Added per-currency unbilled totals summary to support multi-currency projects.
  • 2026-02-04: Implemented add-form product picker with searchable catalog lookup.
  • 2026-02-04: Added price/currency selector with auto-selected first price and multi-price dropdown.
  • 2026-02-04: Added quantity/description inputs and live total display to the add form.
  • 2026-02-04: Implemented add-material submission with validation, toast feedback, and list refresh.
  • 2026-02-04: Added delete action for unbilled materials with toast feedback and reload.
  • 2026-02-04: Allowed materials drawer to open without a client and display a no-client warning while hiding the Add button.
  • 2026-02-04: Wrapped drawer content in ReflectionContainer and added automation IDs for key elements.
  • 2026-02-04: Added T001 test to assert billing dependency in projects package.json.
  • 2026-02-04: Added T002 test to assert ProjectInfo opens materials drawer with 560px width.
  • 2026-02-04: Added T003 test to verify loading state while materials fetch is pending.
  • 2026-02-04: Added T004 test to verify empty state when no materials are returned.
  • 2026-02-04: Added T005 test to verify table columns and material row content.
  • 2026-02-04: Added T006 test to verify Pending/Billed badge rendering.
  • 2026-02-04: Added T007 test to verify currency formatting from minor units.
  • 2026-02-04: Added T008 test to verify per-currency unbilled totals summary.
  • 2026-02-04: Added T009 test to ensure product picker loads catalog items.
  • 2026-02-04: Added T010 test to ensure price selector options appear after product selection.
  • 2026-02-04: Added T011 test for quantity default/min validation.
  • 2026-02-04: Added T012 test for total recalculation on quantity/currency changes.
  • 2026-02-04: Added T013 test to verify add-material submission and list refresh.
  • 2026-02-04: Added T014 test to verify validation toasts for missing product/price.
  • 2026-02-04: Added T015 test to ensure delete controls only show for unbilled items.
  • 2026-02-04: Added T016 test to verify delete action triggers list refresh.
  • 2026-02-04: Added T017 test to verify no-client warning and Add button suppression.
  • 2026-02-04: Added T018 test to verify automation IDs on key elements.
  • 2026-02-04: Adjusted add button to allow validation toasts without disabling, and aligned vitest aliases for @alga-psa/projects.
  • 2026-02-04: Added vitest alias for @alga-psa/tags and ensured RTL cleanup between drawer tests.
  • 2026-02-04: Added explicit data-automation-id wrappers for quantity/description fields and mocked TagManager in tests.
  • 2026-02-04: Test run: npx vitest --run packages/projects/tests/packageDependencies.test.ts packages/projects/tests/projectInfoDrawer.test.tsx packages/projects/tests/projectMaterialsDrawer.test.tsx (passes; warnings about act()).