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
5.8 KiB
5.8 KiB
Project Materials Drawer - Scratchpad
Initial Discovery (2026-02-04)
Related Work
- 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)- ReturnsIProjectMaterial[]with service_name and sku joinedaddProjectMaterial(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 keyproject_id: string- Foreign key to projectclient_id: string- Foreign key to client (for billing)service_id: string- Foreign key to service_catalog (product)service_name?: string- Denormalized from service_catalogsku?: string | null- Product SKUquantity: numberrate: number- Price in centscurrency_code: string- ISO 4217 currency codedescription?: string | nullis_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/billingdependency topackages/projects/package.jsonfor 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
ProjectMaterialsDrawertolistProjectMaterialswith 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
ReflectionContainerand 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()).