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
111 lines
5.8 KiB
Markdown
111 lines
5.8 KiB
Markdown
# 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:
|
|
```json
|
|
"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()).
|